基础学习笔记之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"<<endl;
usleep( 1000000 );//延时1s
cout<<"second"<<endl;
usleep( 1000000 );
count<<"third"<<endl;

 

  其原因在主线程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  <windows.h>
//#include <time.h>
#include <iostream>
#include <QElapsedTimer>

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( "<img src =../drawing/drawing.jpg>" );

    /*下面几句为在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( "<img src=../drawing/drawing1.jpg>" );
    t.start();
    while(t.elapsed()<1000)
        QCoreApplication::processEvents();

    /*画椭圆2*/
    ui->textBrowser->clear();
    my_ellipse( img ,90 );
    imwrite ( "../drawing/drawing2.jpg", img );
    ui->textBrowser->append( "<img src=../drawing/drawing2.jpg>" );
    t.start();
    while(t.elapsed()<1000)
        QCoreApplication::processEvents();

    /*画椭圆3*/
    ui->textBrowser->clear();
    my_ellipse( img, 45 );
    imwrite ( "../drawing/drawing3.jpg", img );
    ui->textBrowser->append( "<img src=../drawing/drawing3.jpg>" );
    t.start();
    while(t.elapsed()<1000)
        QCoreApplication::processEvents();

    /*画椭圆4*/
    ui->textBrowser->clear();
    my_ellipse( img, 135 );
    imwrite ( "../drawing/drawing3.jpg", img );
    ui->textBrowser->append( "<img src=../drawing/drawing3.jpg>" );
    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( "<img src=../drawing/drawing3.jpg>" );
    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( "<img src =../drawing/drawing.jpg>" );
    QElapsedTimer t;
    t.start();
    while(t.elapsed()<1000)
        QCoreApplication::processEvents();

    
    ui->textBrowser->clear();
    my_polygon( img );
    imwrite ( "../drawing/drawing2.jpg", img );
    ui->textBrowser->append( "<img src=../drawing/drawing2.jpg>" );
    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( "<img src=../drawing/drawing2.jpg>" );
    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( "<img src=../drawing/drawing2.jpg>" ); 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下载



posted on 2012-07-25 16:28  tornadomeet  阅读(15515)  评论(0编辑  收藏  举报

阿萨德发斯蒂芬