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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198


/**
* @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原型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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圆

1
2
3
4
5
6
7
8
void cv::circle ( InputOutputArray  img, //图像
Point  center, //圆心坐标
int  radius, //半径
const Scalar &  color, //颜色
int  thickness = 1, //粗细
int  lineType = LINE_8, //类型
int  shift = 0 
)

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

  • fillPoly多边形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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直线

1
2
3
4
5
6
7
8
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矩形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 
)

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

  • 颜色

1
2
3
4
5
6
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

-------------本文结束感谢您的阅读-------------