计算机视觉
图像处理

基础学习笔记之opencv(13):基本绘图

本文主要讲讲怎样用Opencv画一些基本图形,这些图形包括,直线,圆,椭圆,多边形等。参考资料为opencv自带tutiol及其code。
开发环境:ubuntu12.04+Qt4.8.2+QtCreator2.5+opencv2.4.2
实验功能:
1.单击Drawing1按钮,将会画出atom图形,并且可以看出该图形成的过程,共分5个步骤画,每画完1个部分会自动停留1s,以便观察,然后画下一个部分,直至完成atom图形。
2.单击Drawing2按钮,将会画出rook图形,并且可以看出该图形成的过程,共分3个步骤画 ,每画完1个部分会自动停留1s,以便观察,然后画下一个部分,直至完成atom图形。
3.单击close按钮,退出程序。

实验说明:
1. QtextEdit除了用append()函数显示图片外,还可以用insertHtml()函数和setPlainText()来显示,用法类似,其中insertHtml()可以用来显示图片和有格式的文字,而setPlainText()只能用来显示无格式的文字。
2.为什么TextBrowser下的append()函数2个连在一起使用时,只有当最后一个append函数运行完后才显示出append的内容呢?
比如说, ui->textBrowser->append( “first” );

usleep( 1000000 );//延时1s

ui->textBrowser->append( “second” );

usleep( 1000000 );

ui->textBrowser->append( “third” ); 
实际运行到这几句代码时,并不是显示完first,延时1s后显示second,再延时1s后显示third. 而是直接延时2秒,first,second,third同时显示呢?
而把程序改成在终端输出字符串,用的usleep函数,其结果却正常,能满足我们预先设定的了。即改为下面代码时:    cout<<"first"<
其原因在主线程GUI中不宜采用sleep()等函数,否则会出现意想不到的结果。
如果需要延时,#include <QElapsedTimer>后,可以用下面的代码(比如说延时1s):  QElapsedTimer t;

t.start();

while(t.elapsed()<1000) QcoreApplication::processEvents(); 
3.fillPoly函数的第2个参数是指1个指向Point的双指针,因为该函数可以同时填充多个多边形。第3个参数为指向整型的指针,表示每个多边形中顶点的个数。

实验结果:
画atom图过程之一及其结果:


画rook图过程之一及其结果:


实验主要部分代码及注释(附录有工程code下载链接):  #include "mainwindow.h"
#include "ui_mainwindow.h"
//#include 
//#include
#include
#include

using namespace std;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->textBrowser->setFixedWidth( W );
    ui->textBrowser->setFixedHeight( W );

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_closeButton_clicked()
{
    close();
}

void MainWindow::on_drawing1Button_clicked()
{
    /*画图1,资料中称该图为atom*/

    img = Mat::zeros( W, W, CV_8UC3 );
    imwrite( "../drawing/drawing.jpg", img );
    ui->textBrowser->insertHtml( "" );

    /*下面几句为在Qt中常用的延时函数,这里为延时1s,注意主线程中不要采用sleep()等函数
    否则会出现意想不到的结果*/
    QElapsedTimer t;
    t.start();
    while(t.elapsed()<1000)         QCoreApplication::processEvents();     /*画椭圆1*/     ui->textBrowser->clear();
    my_ellipse( img, 0 );
    imwrite ( "../drawing/drawing1.jpg", img );
    ui->textBrowser->append( "" );
    t.start();
    while(t.elapsed()<1000)         QCoreApplication::processEvents();     /*画椭圆2*/     ui->textBrowser->clear();
    my_ellipse( img ,90 );
    imwrite ( "../drawing/drawing2.jpg", img );
    ui->textBrowser->append( "" );
    t.start();
    while(t.elapsed()<1000)         QCoreApplication::processEvents();     /*画椭圆3*/     ui->textBrowser->clear();
    my_ellipse( img, 45 );
    imwrite ( "../drawing/drawing3.jpg", img );
    ui->textBrowser->append( "" );
    t.start();
    while(t.elapsed()<1000)         QCoreApplication::processEvents();     /*画椭圆4*/     ui->textBrowser->clear();
    my_ellipse( img, 135 );
    imwrite ( "../drawing/drawing3.jpg", img );
    ui->textBrowser->append( "" );
    t.start();
    while(t.elapsed()<1000)         QCoreApplication::processEvents();     /*画atom的中心实心圆*/     ui->textBrowser->clear();
    my_filled_circle( img, Point(W/2, W/2) );
    imwrite ( "../drawing/drawing3.jpg", img );
    ui->textBrowser->append( "" );
    t.start();
    while(t.elapsed()<1000)         QCoreApplication::processEvents(); } void MainWindow::on_drawing2Button_clicked() {     /*画图2,资料中称该图为rook,其实就是一枚国际像棋子*/          img = Mat::zeros( W, W, CV_8UC3 );     imwrite( "../drawing/drawing.jpg", img );     ui->textBrowser->insertHtml( "" );
    QElapsedTimer t;
    t.start();
    while(t.elapsed()<1000)         QCoreApplication::processEvents();          ui->textBrowser->clear();
    my_polygon( img );
    imwrite ( "../drawing/drawing2.jpg", img );
    ui->textBrowser->append( "" );
    t.start();
    while(t.elapsed()<1000)         QCoreApplication::processEvents();          ui->textBrowser->clear();
    rectangle( img, Rect( Point(0, 7*W/8), Point(W, W) ), Scalar(0, 0, 255), -1, 8);
    imwrite ( "../drawing/drawing2.jpg", img );
    ui->textBrowser->append( "" );
    t.start();
    while(t.elapsed()<1000)         QCoreApplication::processEvents();     ui->textBrowser->clear();
    my_line( img, Point(0, 15*W/16), Point( W, 15*W/16) );
    my_line( img, Point(W/4, W/8), Point(W/4, W) );
    my_line( img, Point(W/2, 7*W/8), Point(W/2, W) );
    my_line( img, Point(3*W/4, W/8), Point(3*W/4, W) );
    imwrite ( "../drawing/drawing2.jpg", img );
    ui->textBrowser->append( "" );
    t.start();
    while(t.elapsed()<1000)         QCoreApplication::processEvents(); } void MainWindow::my_ellipse( Mat& img, float angle ) {     cv::ellipse( img, Point(W/2, W/2), Size(3*W/8, W/8), angle, 0, 360, Scalar(0, 255, 0), 2, 8 ); } void MainWindow::my_filled_circle( Mat& img, Point center ) {     cv::circle( img, center, W/8, Scalar(0, 0, 255), -1, 8 ); } void MainWindow::my_polygon( Mat& img ) {     int ncontours = 1;     Point rook_points[1][20];     rook_points[0][0] = Point( W/4.0, 7*W/8.0 );     rook_points[0][1] = Point( 3*W/4.0, 7*W/8.0 );     rook_points[0][2] = Point( 3*W/4.0, 13*W/16.0 );     rook_points[0][3] = Point( 11*W/16.0, 13*W/16.0 );     rook_points[0][4] = Point( 19*W/32.0, 3*W/8.0 );     rook_points[0][5] = Point( 3*W/4.0, 3*W/8.0 );     rook_points[0][6] = Point( 3*W/4.0, W/8.0 );     rook_points[0][7] = Point( 26*W/40.0, W/8.0 );     rook_points[0][8] = Point( 26*W/40.0, W/4.0 );     rook_points[0][9] = Point( 22*W/40.0, W/4.0 );     rook_points[0][10] = Point( 22*W/40.0, W/8.0 );     rook_points[0][11] = Point( 18*W/40.0, W/8.0 );     rook_points[0][12] = Point( 18*W/40.0, W/4.0 );     rook_points[0][13] = Point( 14*W/40.0, W/4.0 );     rook_points[0][14] = Point( 14*W/40.0, W/8.0 );     rook_points[0][15] = Point( W/4.0, W/8.0 );     rook_points[0][16] = Point( W/4.0, 3*W/8.0 );     rook_points[0][17] = Point( 13*W/32.0, 3*W/8.0 );     rook_points[0][18] = Point( 5*W/16.0, 13*W/16.0 );     rook_points[0][19] = Point( W/4.0, 13*W/16.0) ;     const Point *pts[1] = { rook_points[0] };  //   const Point **pts = rook_points;//这样定义是不行的,因为rook_points是个常量的二阶指针     int npts[1] = { 20 };     //用指定颜色填充指定闭合的多边形。     fillPoly( img, pts, npts, ncontours, Scalar(0, 255, 0), 8 ); } void MainWindow::my_line( Mat& img, Point start, Point end ) {     line( img, start, end, Scalar(0, 0, 0), 2, 8 ); }

实验总结:
本次实验的主要时间花在了延时函数的使用上,因为不同操作系统的内核不同,所以使用延时函数时需要小心,一开始使用的延时函数usleep(),总出现莫名其妙的现象,后面在论坛上得到了网友的指点说GUI线程中最好不要使用sleep()系列的函数。
  附:工程code下载

转载注明来源:CV视觉网 » 基础学习笔记之opencv(13):基本绘图

分享到:更多 ()
扫描二维码,给作者 打赏
pay_weixinpay_weixin

请选择你看完该文章的感受:

0不错 0超赞 0无聊 0扯淡 0不解 0路过

评论 3

评论前必须登录!