opencv自带例子学习-几何图形的绘制1

96
芒果浩明
2018.09.19 18:34 字数 453

opencv提供了一些自带的函数供我们绘制几何图形,涵盖了一些常见的几何图形。有规则的圆形、矩形、直线椭圆等。不规则的多边形也可以绘制,只不过相比规则的稍麻烦,需要传入一系列的坐标点进行绘制。话不多说,上代码先



/**
 * @file Drawing_1.cpp
 * @brief Simple geometric drawing
 * @author OpenCV team
 */

//所需头文件
#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";

  /// Create black empty images
  /// 创建两张空白的图像
  Mat atom_image = Mat::zeros( w, w, CV_8UC3 );
  Mat rook_image = Mat::zeros( w, w, CV_8UC3 );
  //![create_images]

  /// 1. Draw a simple atom:
  /// 画一个简单的原子
  /// -----------------------

  //![draw_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) );
  //![draw_atom]

  /// 2. Draw a rook
  /// ------------------

  //![draw_rook]
  /// 2.a. Create a convex polygon
  ///绘制多边形
  MyPolygon( rook_image );

  //![rectangle]
  /// 2.b. Creating rectangles
  ///绘制矩形
  rectangle( rook_image,
         Point( 0, 7*w/8 ),
         Point( w, w),
         Scalar( 0, 255, 255 ),
         FILLED,
         LINE_8 );
  //![rectangle]

  /// 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 ) );
  //![draw_rook]

  /// 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
 */
//![my_ellipse]
void MyEllipse( Mat img, double angle )
{
  int thickness = 2;//线条的粗细程度
  int lineType = 8;//线条的类型

  //调用ellipse函数绘制椭圆
  ellipse( img,
       Point( w/2, w/2 ),
       Size( w/4, w/16 ),
       angle,
       0,
       360,
       Scalar( 255, 0, 0 ),
       thickness,
       lineType );
}
//![my_ellipse]

/**
 * @function MyFilledCircle
 * @brief Draw a fixed-size filled circle
 */
//![my_filled_circle]
void MyFilledCircle( Mat img, Point center )
{
  //绘制圆面
  circle( img,
      center,
      w/32,
      Scalar( 0, 0, 255 ),
      FILLED,
      LINE_8 );
}
//![my_filled_circle]

/**
 * @function MyPolygon
 * @brief Draw a simple concave polygon (rook)
 */
//![my_polygon]
//绘制多边形
void MyPolygon( Mat img )
{
  int lineType = LINE_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函数绘制多边形
  fillPoly( img,
        ppt,
        npt,
        1,
        Scalar( 255, 255, 255 ),
        lineType );
}
//![my_polygon]

/**
 * @function MyLine
 * @brief Draw a simple line
 */
//![my_line]
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 );
}
//![my_line]

下面来分别看看几个绘制函数

  • ellipse椭圆
    先看看ellipse原型
void cv::ellipse ( InputOutputArray  img, //图像
  Point  center, //圆心坐标
  Size  axes, //短轴长
  double  angle, //倾斜角
  double  startAngle, //起始角,长轴到起始边沿的夹角
  double  endAngle, //结束角,长轴到结束点的夹角
  const Scalar &  color, //颜色
  int  thickness = 1, //粗细
  int  lineType = LINE_8, //类型
  int  shift = 0  
 ) 

void cv::ellipse ( InputOutputArray  img, //图像
  const RotatedRect &  box, //倾斜矩形
  const Scalar &  color, //颜色
  int  thickness = 1, //粗细
  int  lineType = LINE_8  //类型
 ) 

函数原型有两个,看程序的调用可以知道本例程匹配个是第一个函数原型。
椭圆的绘制函数稍有点复杂,可以参考下面图示进行理解

image.png
  • circle圆
void cv::circle ( InputOutputArray  img, //图像
  Point  center, //圆心坐标
  int  radius, //半径
  const Scalar &  color, //颜色
  int  thickness = 1, //粗细
  int  lineType = LINE_8, //类型
  int  shift = 0  
 ) 

绘制圆型的函数比较简单,圆心坐标和半径可以确定一个圆

  • fillPoly多边形
void cv::fillPoly ( Mat &  img, //图像
  const Point **  pts, //Point **类型的坐标点,与历程中相对应
  const int *  npts, //点的数量
  int  ncontours, //轮廓数
  const Scalar &  color, //颜色
  int  lineType = LINE_8, //类型
  int  shift = 0, 
  Point  offset = Point()  
 ) 

void cv::fillPoly ( InputOutputArray  img, 
  InputArrayOfArrays  pts, //点坐标集合
  const Scalar &  color, 
  int  lineType = LINE_8, 
  int  shift = 0, 
  Point  offset = Point()  //偏移
 ) 
  • line直线
void cv::line ( InputOutputArray  img, //图像
  Point  pt1, //坐标点1
  Point  pt2, //坐标点2
  const Scalar &  color, //颜色
  int  thickness = 1, //粗细
  int  lineType = LINE_8, //类型
  int  shift = 0  
 ) 
  • rectangle矩形
void cv::rectangle ( InputOutputArray  img, //图像
//对角两个点可以确定一个矩形
  Point  pt1, 
  Point  pt2, 
  const Scalar &  color, //颜色
  int  thickness = 1, //粗细
  int  lineType = LINE_8, //线条类型
  int  shift = 0  
 ) 
void cv::rectangle ( Mat &  img, //图像
//一个Rect的矩形变量
  Rect  rec, 
  const Scalar &  color, //绘制的颜色
  int  thickness = 1, //粗细
  int  lineType = LINE_8, //线条类型
  int  shift = 0  
 ) 

可以通过上面几个函数原型得出,几何绘制图形函数的参数都是分为两部分,一部分是构成几何图形的数学参数,如直线需要两个坐标点,圆形需要圆心和半径等,这是独有的。另一部分是对绘制线条的一个限定包括如下几个参数,颜色、粗细、类型、坐标点中的小数点位数。这是共有的。

  • 颜色
typedef Scalar_<double> cv::Scalar //原型
//使用举例
Scalar( 255, 255, 255 )//白色
Scalar( 255, 0, 0)//蓝色
Scalar( 0, 255,  )//绿色
Scalar( 0, 0, 255 )//红色
  • 粗细

thickness,厚度。表示线条的粗细,单位应该是像素点

  • 类型
    lineType


    image.png

四种类型分别是

  • 填充,即假如绘制圆选用这个类型,结果会是绘制出一个实心圆面

  • 八邻域连接

  • 四邻域链接

  • 抗锯齿,采用了高斯模糊去平滑

  • shift
    坐标点中小数点的位数,默认一般为0

计算机视觉