OpenCV基本繪圖

2022-07-06 17:01 更新

目標(biāo)

在本教程中,您將學(xué)習(xí)如何:

  • 使用cv :: Point定義圖像中的2D點(diǎn)。
  • 使用cv :: Scalar,為什么它是有用的
  • 畫(huà)一條線使用OpenCV的函數(shù)CV ::線
  • 畫(huà)一個(gè)橢圓利用OpenCV的功能CV ::橢圓形
  • 繪制一個(gè)矩形,使用OpenCV的功能CV ::矩形
  • 畫(huà)一個(gè)圓圈使用OpenCV的功能CV ::圈
  • 使用OpenCV函數(shù)cv :: fillPoly繪制一個(gè)填充的多邊形

OpenCV理論

對(duì)于本教程,我們將大量使用兩個(gè)結(jié)構(gòu):cv :: Pointcv :: Scalar

Point

它表示由其圖像坐標(biāo)和指定的2D點(diǎn)。我們可以將其定義為:xy

Point pt;
pt.x = 10;
pt.y = 8;

or

Point pt = Point(10,8);

Scalar

  • 代表一個(gè)4元素的向量。Scalar類型廣泛用于OpenCV中,用于傳遞像素值。
  • 在本教程中,我們將廣泛使用它來(lái)表示BGR顏色值(3個(gè)參數(shù))。如果不使用最后一個(gè)參數(shù),則無(wú)需定義最后一個(gè)參數(shù)。
  • 讓我們看一個(gè)例子,如果我們被要求一個(gè)顏色參數(shù),我們給出:
Scalar( a, b, c )

我們將定義一個(gè)BGR顏色,如:Blue = a,Green = b和Red = c

Code


#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#define w 400
using namespace cv;
void MyEllipse( Mat img, double angle );
void MyFilledCircle( Mat img, Point center );
void MyPolygon( Mat img );
void MyLine( Mat img, Point start, Point end );
int main( void ){
  char atom_window[] = "Drawing 1: Atom";
  char rook_window[] = "Drawing 2: Rook";
  Mat atom_image = Mat::zeros( w, w, CV_8UC3 );
  Mat rook_image = Mat::zeros( w, w, CV_8UC3 );
  MyEllipse( atom_image, 90 );
  MyEllipse( atom_image, 0 );
  MyEllipse( atom_image, 45 );
  MyEllipse( atom_image, -45 );
  MyFilledCircle( atom_image, Point( w/2, w/2) );
  MyPolygon( rook_image );
  rectangle( rook_image,
         Point( 0, 7*w/8 ),
         Point( w, w),
         Scalar( 0, 255, 255 ),
         FILLED,
         LINE_8 );
  MyLine( rook_image, Point( 0, 15*w/16 ), Point( w, 15*w/16 ) );
  MyLine( rook_image, Point( w/4, 7*w/8 ), Point( w/4, w ) );
  MyLine( rook_image, Point( w/2, 7*w/8 ), Point( w/2, w ) );
  MyLine( rook_image, Point( 3*w/4, 7*w/8 ), Point( 3*w/4, w ) );
  imshow( atom_window, atom_image );
  moveWindow( atom_window, 0, 200 );
  imshow( rook_window, rook_image );
  moveWindow( rook_window, w, 200 );
  waitKey( 0 );
  return(0);
}
void MyEllipse( Mat img, double angle )
{
  int thickness = 2;
  int lineType = 8;
  ellipse( img,
       Point( w/2, w/2 ),
       Size( w/4, w/16 ),
       angle,
       0,
       360,
       Scalar( 255, 0, 0 ),
       thickness,
       lineType );
}
void MyFilledCircle( Mat img, Point center )
{
  circle( img,
      center,
      w/32,
      Scalar( 0, 0, 255 ),
      FILLED,
      LINE_8 );
}
void MyPolygon( Mat img )
{
  int lineType = LINE_8;
  Point rook_points[1][20];
  rook_points[0][0]  = Point(    w/4,   7*w/8 );
  rook_points[0][1]  = Point(  3*w/4,   7*w/8 );
  rook_points[0][2]  = Point(  3*w/4,  13*w/16 );
  rook_points[0][3]  = Point( 11*w/16, 13*w/16 );
  rook_points[0][4]  = Point( 19*w/32,  3*w/8 );
  rook_points[0][5]  = Point(  3*w/4,   3*w/8 );
  rook_points[0][6]  = Point(  3*w/4,     w/8 );
  rook_points[0][7]  = Point( 26*w/40,    w/8 );
  rook_points[0][8]  = Point( 26*w/40,    w/4 );
  rook_points[0][9]  = Point( 22*w/40,    w/4 );
  rook_points[0][10] = Point( 22*w/40,    w/8 );
  rook_points[0][11] = Point( 18*w/40,    w/8 );
  rook_points[0][12] = Point( 18*w/40,    w/4 );
  rook_points[0][13] = Point( 14*w/40,    w/4 );
  rook_points[0][14] = Point( 14*w/40,    w/8 );
  rook_points[0][15] = Point(    w/4,     w/8 );
  rook_points[0][16] = Point(    w/4,   3*w/8 );
  rook_points[0][17] = Point( 13*w/32,  3*w/8 );
  rook_points[0][18] = Point(  5*w/16, 13*w/16 );
  rook_points[0][19] = Point(    w/4,  13*w/16 );
  const Point* ppt[1] = { rook_points[0] };
  int npt[] = { 20 };
  fillPoly( img,
        ppt,
        npt,
        1,
        Scalar( 255, 255, 255 ),
        lineType );
}
void MyLine( Mat img, Point start, Point end )
{
  int thickness = 2;
  int lineType = LINE_8;
  line( img,
    start,
    end,
    Scalar( 0, 0, 0 ),
    thickness,
    lineType );
}

說(shuō)明

  • 由于我們計(jì)劃繪制兩個(gè)例子(an atom and a rook),我們必須創(chuàng)建兩個(gè)圖像和兩個(gè)窗口來(lái)顯示它們。
  char atom_window[] = "Drawing 1: Atom";
  char rook_window[] = "Drawing 2: Rook";
  Mat atom_image = Mat::zeros( w, w, CV_8UC3 );
  Mat rook_image = Mat::zeros( w, w, CV_8UC3 );
  • 我們創(chuàng)建了繪制不同幾何形狀的功能。例如,為了繪制原子,我們使用MyEllipseMyFilledCircle
  MyEllipse( atom_image, 90 );
  MyEllipse( atom_image, 0 );
  MyEllipse( atom_image, 45 );
  MyEllipse( atom_image, -45 );
  MyFilledCircle( atom_image, Point( w/2, w/2) );
  • 并提請(qǐng)我們所使用的車MYLINE,矩形MyPolygon
  MyPolygon( rook_image );
  rectangle( rook_image,
         Point( 0, 7*w/8 ),
         Point( w, w),
         Scalar( 0, 255, 255 ),
         FILLED,
         LINE_8 );
  MyLine( rook_image, Point( 0, 15*w/16 ), Point( w, 15*w/16 ) );
  MyLine( rook_image, Point( w/4, 7*w/8 ), Point( w/4, w ) );
  MyLine( rook_image, Point( w/2, 7*w/8 ), Point( w/2, w ) );
  MyLine( rook_image, Point( 3*w/4, 7*w/8 ), Point( 3*w/4, w ) );
  • 我們來(lái)檢查一下這些功能的內(nèi)容:

MYLINE


void MyLine( Mat img, Point start, Point end )
{
  int thickness = 2;
  int lineType = LINE_8;
  line( img,
    start,
    end,
    Scalar( 0, 0, 0 ),
    thickness,
    lineType );
}

我們可以看到,MyLine只是調(diào)用函數(shù)cv :: line,它執(zhí)行以下操作:

  1. 從點(diǎn)開(kāi)始到點(diǎn)結(jié)束繪制一條線
  2. 該行顯示在圖像img中
  3. 線顏色由Scalar(0,0,0)定義,它是與Black相對(duì)應(yīng)的RGB值
  4. 線厚度設(shè)定為厚度(在這種情況下為2)
  5. 線是8連接線(lineType = 8)

MyEllipse


void MyEllipse( Mat img, double angle )
{
  int thickness = 2;
  int lineType = 8;
  ellipse( img,
       Point( w/2, w/2 ),
       Size( w/4, w/16 ),
       angle,
       0,
       360,
       Scalar( 255, 0, 0 ),
       thickness,
       lineType );
}

從上面的代碼,我們可以看到函數(shù)cv :: ellipse繪制一個(gè)橢圓,使得:

  1. 橢圓顯示在圖像img中
  2. 橢圓中心位于**(w / 2,w / 2)**的點(diǎn),并且被包圍在大小為**(w / 4,w / 16)**
  3. 橢圓旋轉(zhuǎn)角度
  4. 橢圓延伸0到360度之間的圓弧
  5. 圖中的顏色將為標(biāo)量(255,0,0),表示BGR值為藍(lán)色。
  6. 橢圓的厚度為2。

MyFilledCircle


void MyFilledCircle( Mat img, Point center )
{
  circle( img,
      center,
      w/32,
      Scalar( 0, 0, 255 ),
      FILLED,
      LINE_8 );
}

類似于橢圓函數(shù),我們可以觀察到接 作為參數(shù):

  1. 將顯示圓圈的圖像(img)
  2. 圓的中心表示為點(diǎn)中心
  3. 圓的半徑:w / 32
  4. 圓的顏色:標(biāo)量(0,0,255),表示BGR中的紅色
  5. 由于厚度 = -1,圓將被繪制填充。

MyPolygon


void MyPolygon( Mat img )
{
  int lineType = LINE_8;
  Point rook_points[1][20];
  rook_points[0][0]  = Point(    w/4,   7*w/8 );
  rook_points[0][1]  = Point(  3*w/4,   7*w/8 );
  rook_points[0][2]  = Point(  3*w/4,  13*w/16 );
  rook_points[0][3]  = Point( 11*w/16, 13*w/16 );
  rook_points[0][4]  = Point( 19*w/32,  3*w/8 );
  rook_points[0][5]  = Point(  3*w/4,   3*w/8 );
  rook_points[0][6]  = Point(  3*w/4,     w/8 );
  rook_points[0][7]  = Point( 26*w/40,    w/8 );
  rook_points[0][8]  = Point( 26*w/40,    w/4 );
  rook_points[0][9]  = Point( 22*w/40,    w/4 );
  rook_points[0][10] = Point( 22*w/40,    w/8 );
  rook_points[0][11] = Point( 18*w/40,    w/8 );
  rook_points[0][12] = Point( 18*w/40,    w/4 );
  rook_points[0][13] = Point( 14*w/40,    w/4 );
  rook_points[0][14] = Point( 14*w/40,    w/8 );
  rook_points[0][15] = Point(    w/4,     w/8 );
  rook_points[0][16] = Point(    w/4,   3*w/8 );
  rook_points[0][17] = Point( 13*w/32,  3*w/8 );
  rook_points[0][18] = Point(  5*w/16, 13*w/16 );
  rook_points[0][19] = Point(    w/4,  13*w/16 );
  const Point* ppt[1] = { rook_points[0] };
  int npt[] = { 20 };
  fillPoly( img,
        ppt,
        npt,
        1,
        Scalar( 255, 255, 255 ),
        lineType );
}

要繪制一個(gè)填充的多邊形,我們使用函數(shù)cv :: fillPoly。我們注意到:

  1. 多邊形將在img上繪制
  2. 多邊形的頂點(diǎn)是ppt中的一組點(diǎn)
  3. 要繪制的頂點(diǎn)總數(shù)為npt
  4. 要繪制的多邊形的數(shù)量只有1
  5. 多邊形的顏色由Scalar(255,255,255)定義,它是白色的BGR值

rectangle

  rectangle( rook_image,
         Point( 0, 7*w/8 ),
         Point( w, w),
         Scalar( 0, 255, 255 ),
         FILLED,
         LINE_8 );

最后我們有cv :: rectangle函數(shù)(我們沒(méi)有為這個(gè)人創(chuàng)建一個(gè)特殊的函數(shù))。我們注意到:

  1. 矩形將在rook_image上繪制
  2. 矩形的兩個(gè)相對(duì)頂點(diǎn)由**點(diǎn)(0,7 * w / 8)**和點(diǎn)(w,w)**定義
  3. 矩形的顏色由Scalar(0,255,255)給出,它是黃色的BGR值
  4. 由于厚度值由FILLED(-1)給出,矩形將被填充。

結(jié)果

編譯和運(yùn)行你的程序應(yīng)該給你一個(gè)這樣的結(jié)果:

OpenCV基本繪圖

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)