OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Basic Drawing

2.6基础绘画

目标

在这里我们会学习:

1、在图像中使用Point 来定义2D

2、使用Scalar以及为什么要使用它

3、使用OpenCV函数line来绘制一条直线

4、使用OpenCV函数ellipse来绘制一个椭圆

5、使用OpenCV函数rectangle来绘制一个矩形

6、使用OpenCV函数circle来绘制一个圆

7、使用OpenCV函数fillPoly来填充一个任意图形

OpenCV理论知识

在这个教程中,我们着重使用两种数据结构:PointScalar

 

Point

它代表2D点,使用xy指定他的图像中的坐标。我们可以使用如下来定义:

Point 平台;

pt.x=10;

pt.y=8;

或者

Point pt=Point(10,8);

 

Scalar

1、代表一个4个元素的向量。Scalar类型在OpenCV中被广泛适用于传递像素值。

2在教程中,我们使用广泛的使用它来表示RGB色彩值(3个参数)。如果最后一个元素不会被使用,那就没有必要去定义它。

3、让我们来看一个例子,如果我们想要一个色彩参数,我们会给:

Scalar(a,b,c)

我们定义一个RGB颜色,例如:Red=cGreen=bBlue=a

 

 

 

代码

/**

 * @file Drawing_1.cpp

 * @brief Simple sample code

 */

 

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

 

#define w 400

 

using namespace cv;

 

/// Function headers

void MyEllipse( Mat img, double angle );

void MyFilledCircle( Mat img, Point center );

void MyPolygon( Mat img );

void MyLine( Mat img, Point start, Point end );

 

/**

 * @function main

 * @brief Main function

 */

int main( void ){

 

  /// Windows names

  char atom_window[] = "Drawing 1: Atom";

  char rook_window[] = "Drawing 2: Rook";

 

  /// Create black empty images

  Mat atom_image = Mat::zeros( w, w, CV_8UC3 );

  Mat rook_image = Mat::zeros( w, w, CV_8UC3 );

 

  /// 1. Draw a simple atom:

  /// -----------------------

 

  /// 1.a. Creating ellipses

  MyEllipse( atom_image, 90 );

  MyEllipse( atom_image, 0 );

  MyEllipse( atom_image, 45 );

  MyEllipse( atom_image, -45 );

 

  /// 1.b. Creating circles

  MyFilledCircle( atom_image, Point( w/2, w/2) );

 

  /// 2. Draw a rook

  /// ------------------

 

  /// 2.a. Create a convex polygon

  MyPolygon( rook_image );

 

  /// 2.b. Creating rectangles

  rectangle( rook_image,

         Point( 0, 7*w/8 ),

         Point( w, w),

         Scalar( 0, 255, 255 ),

         -1,

         8 );

 

  /// 2.c. Create a few lines

  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 ) );

 

  /// 3. Display your stuff!

  imshow( atom_window, atom_image );

  moveWindow( atom_window, 0, 200 );

  imshow( rook_window, rook_image );

  moveWindow( rook_window, w, 200 );

 

  waitKey( 0 );

  return(0);

}

 

/// Function Declaration

 

/**

 * @function MyEllipse

 * @brief Draw a fixed-size ellipse with different angles

 */

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 );

}

 

/**

 * @function MyFilledCircle

 * @brief Draw a fixed-size filled circle

 */

void MyFilledCircle( Mat img, Point center )

{

  int thickness = -1;

  int lineType = 8;

 

  circle( img,

      center,

      w/32,

      Scalar( 0, 0, 255 ),

      thickness,

      lineType );

}

 

/**

 * @function MyPolygon

 * @function Draw a simple concave polygon (rook)

 */

void MyPolygon( Mat img )

{

  int lineType = 8;

 

  /** Create some points */

  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 );

}

 

/**

 * @function MyLine

 * @brief Draw a simple line

 */

void MyLine( Mat img, Point start, Point end )

{

  int thickness = 2;

  int lineType = 8;

  line( img,

    start,

    end,

    Scalar( 0, 0, 0 ),

    thickness,

    lineType );

}

 

 

 

 

解释

1、因为我们打算画两个例子(一个原子和一个棋子),我们必须创建两个图像和两个窗口来展示他们

 

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);

2、我们创建函数来画不同的几何形状。例如,画原子我们需要使用MyEllipseMyFilledCircle

 

MyEllipse(atom_image,90);

MyEllipse(atom_image,0);

MyEllipse(atom_image,45);

MyEllipse(atom_image,-45);

 

MyFilledCircle(atom_image,Point(w/2.0,w/2.0);

 

3、画棋子,我们需要使用MyLine,rectangle以及MyPolygon函数

 

MyPolygon(rook_image);

Rectangle(rook_image,Point(0,7*w/8.0),Point(w,w),Scalar(0,255,255),-1,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));

 

4、让我们看一下上面那些函数中每一个函数里面都有什么:

  

MyLine

void MyLine(Mat img.Point start,Point end)

{

int thickness=2;

 int lineType=8;

Line(img.star.end,Scalar(0,0,0),thickness,lineType);  
}

 

 

 

 

 

就像我们看到的,MyLine仅仅调用了line函数,line函数会做一下工作:

   -start点到end点做一条直线

   -将这条直线显示在img图像中

   -线条的颜色在Scalar(0,0,0)中定义出来,这个颜色在RGB色彩系统中对应于黑色

   -线条的粗细被设置为thickness(在这种情况下是2)

   -这个线条是一个8连接的(lineType=8)

 

MyEllipse

 

void  MyEllipse(Mat img,double angle)

{

int thickness=2;

int lineType=8;

Ellipse(img,Point(w/2.0,w/2.0),Size(w/4.0,w/16.0),angle,0,360,Scalar255,0,0),thickness,lineType);

}

 

 
}

 

从上面的代码中我们可以看到ellipse函数画了一个椭圆:

-椭圆显示在img图像中

-椭圆的中心定位在(w/2.0,w/2.0)这个点上,封闭于大小为(w/4.0,w/16.0)的矩形中

-椭圆旋转angle角度

-椭圆弧度从0-360

-颜色指数是Scalar255,255,0)在RGB颜色系统中是蓝色

-椭圆线的粗细为thickness,也就是2

 

MyFillCircle

 

void MyFilledCircle(Mat img,Point center)

{

int thickness=-1;

int lineType=8;

Circle(img,center,w/32.0,Scalar(0,0,255),thickness,lineType);
}

ellipse函数相似,我们可以看到circle函数中接受的参数:

  -img就是circle将要在哪个图像中显示

 

 

  -center就是圆心

  -w/32.0就是半径

  -Scalar(0,0,255)就是颜色;在RGB中就是红色。

  -因为thickness=-1,圆将要被填充。

 

MyPolygon

 

void MyPolygon(Mat img)

{

int lineType=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);

}
}

为了填充一个任意图形,我们使用fillPoly函数,注意:

  -任意图形会被显示在img

  -图形的顶点被放置在ppt这个数组中。

  - 顶点的数量放置在npt

  -绘画任意图形的数量为1

 

 

 

  -任意图形的颜色被定义为Scalar(255,255,255),RGB色彩系统中就是白色

 

rectangle

 

rectangle(rook_image,Point(0,7*w/8.0),Point(w,w),Scalar(0,255,255),-1,8);

 

最后我们使用rectangle方程(我们没有为这个家伙创建一个特殊的方程)。注意:

  -矩形(rectangle)将会被画在rook_image图像上

  -两个对角的顶点被定义在**Point(0,7*w/8.0)**Point(w,w)

  -矩形的颜色在Scalar(0,255,255)中给出,在BGR色彩中就是黄色。

  -由于thickness这个参数被置-1,所以矩形被填充。

 

结果

编译并运行程序,你会得到下面的结果

 

 

posted @ 2015-05-26 09:29  你猜你猜啊  阅读(214)  评论(0编辑  收藏  举报