OpenCV基本繪圖

2022-07-06 17:01 更新

目標

在本教程中,您將學習如何:

OpenCV理論

對于本教程,我們將大量使用兩個結構:cv :: Pointcv :: Scalar

Point

它表示由其圖像坐標和指定的2D點。我們可以將其定義為:xy

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

or

Point pt = Point(10,8);

Scalar

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

我們將定義一個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 );
}

說明

  • 由于我們計劃繪制兩個例子(an atom and a rook),我們必須創(chuàng)建兩個圖像和兩個窗口來顯示它們。
  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) );
  • 并提請我們所使用的車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 ) );
  • 我們來檢查一下這些功能的內容:

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只是調用函數(shù)cv :: line,它執(zhí)行以下操作:

  1. 從點開始到點結束繪制一條線
  2. 該行顯示在圖像img中
  3. 線顏色由Scalar(0,0,0)定義,它是與Black相對應的RGB值
  4. 線厚度設定為厚度(在這種情況下為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繪制一個橢圓,使得:

  1. 橢圓顯示在圖像img中
  2. 橢圓中心位于**(w / 2,w / 2)**的點,并且被包圍在大小為**(w / 4,w / 16)**
  3. 橢圓旋轉角度
  4. 橢圓延伸0到360度之間的圓弧
  5. 圖中的顏色將為標量(255,0,0),表示BGR值為藍色。
  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. 圓的中心表示為點中心
  3. 圓的半徑:w / 32
  4. 圓的顏色:標量(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 );
}

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

  1. 多邊形將在img上繪制
  2. 多邊形的頂點是ppt中的一組點
  3. 要繪制的頂點總數(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ù)(我們沒有為這個人創(chuàng)建一個特殊的函數(shù))。我們注意到:

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

結果

編譯和運行你的程序應該給你一個這樣的結果:

OpenCV基本繪圖

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號