基礎學習筆記之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下載




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM