OpenCV4入门系列教程85.5:测试7寻找轮廓综合测试

索引地址:系列教程索引地址

上一篇:OpenCV4入门系列教程85:寻找最大内接圆

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
//--------------------------------------【程序说明】-------------------------------------------
// 程序说明:《OpenCV3编程入门》OpenCV3版书本配套示例程序75
// 程序描述:创建轮廓边界框
// 2014年11月 Created by @浅墨_毛星云
// 2014年12月 Revised by @浅墨_毛星云
//------------------------------------------------------------------------------------------------

//---------------------------------【头文件、命名空间包含部分】----------------------------
// 描述:包含程序所使用的头文件和命名空间
//------------------------------------------------------------------------------------------------
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;

//-----------------------------------【宏定义部分】--------------------------------------------
// 描述:定义一些辅助宏
//------------------------------------------------------------------------------------------------
#define WINDOW_NAME1 "Original" //为窗口标题定义的宏
#define WINDOW_NAME2 "Result" //为窗口标题定义的宏

//-----------------------------------【全局变量声明部分】--------------------------------------
// 描述:全局变量的声明
//-----------------------------------------------------------------------------------------------
Mat g_srcImage;
Mat g_grayImage;
int g_nThresh = 50; //阈值
int g_nMaxThresh = 255; //阈值最大值
RNG g_rng(12345); //随机数生成器

//-----------------------------------【全局函数声明部分】--------------------------------------
// 描述:全局函数的声明
//-----------------------------------------------------------------------------------------------
void on_ContoursChange(int, void *);
static void ShowHelpText();

//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main() {
//【0】显示欢迎和帮助文字
ShowHelpText();

//【1】载入3通道的原图像
g_srcImage = imread("1.jpg", 1);
if (!g_srcImage.data) {
printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n");
return false;
}

//【2】得到原图的灰度图像并进行平滑
cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
blur(g_grayImage, g_grayImage, Size(3, 3));

//【3】创建原始图窗口并显示
namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
imshow(WINDOW_NAME1, g_srcImage);

//【4】设置滚动条并调用一次回调函数
createTrackbar(" 阈值:", WINDOW_NAME1, &g_nThresh, g_nMaxThresh, on_ContoursChange);
on_ContoursChange(0, 0);

waitKey(0);

return (0);
}

//----------------------------【on_ContoursChange( )函数】---------------------------------
// 描述:回调函数
//-------------------------------------------------------------------------------------------------
void on_ContoursChange(int, void *) {
//定义一些参数
Mat threshold_output;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;

// 使用Threshold检测边缘
threshold(g_grayImage, threshold_output, g_nThresh, 255, THRESH_BINARY);

// 找出轮廓
findContours(threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE,
Point(0, 0));

// 多边形逼近轮廓 + 获取矩形和圆形边界框
vector<vector<Point>> contours_poly(contours.size());
vector<Rect> boundRect(contours.size());
vector<Point2f> center(contours.size());
vector<float> radius(contours.size());

//一个循环,遍历所有部分,进行本程序最核心的操作
for (unsigned int i = 0; i < contours.size(); i++) {
approxPolyDP(Mat(contours[ i ]), contours_poly[ i ], 3, true); //用指定精度逼近多边形曲线
boundRect[ i ] =
boundingRect(Mat(contours_poly[ i ])); //计算点集的最外面(up-right)矩形边界
minEnclosingCircle(contours_poly[ i ], center[ i ],
radius[ i ]); //对给定的 2D点集,寻找最小面积的包围圆形
}

// 绘制多边形轮廓 + 包围的矩形框 + 圆形框
Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3);
for (int unsigned i = 0; i < contours.size(); i++) {
Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255),
g_rng.uniform(0, 255)); //随机设置颜色
drawContours(drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0,
Point()); //绘制轮廓
rectangle(drawing, boundRect[ i ].tl(), boundRect[ i ].br(), color, 2, 8, 0); //绘制矩形
circle(drawing, center[ i ], (int)radius[ i ], color, 2, 8, 0); //绘制圆
}

// 显示效果图窗口
namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);
imshow(WINDOW_NAME2, drawing);
}

//-----------------------------------【ShowHelpText( )函数】----------------------------------
// 描述:输出一些帮助信息
//----------------------------------------------------------------------------------------------
static void ShowHelpText() {
//输出欢迎信息和OpenCV版本
printf("\n\n\t\t\t非常感谢购买《OpenCV3编程入门》一书!\n");
printf("\n\n\t\t\t此为本书OpenCV3版的第75个配套示例程序\n");
printf("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION);
printf("\n\n ----------------------------------------------------------------------------\n");

//输出一些帮助信息
printf("\n\n\n\t欢迎来到【创建包围轮廓的矩形和圆形边界框】示例程序~\n\n");
printf("\n\n\t按键操作说明: \n\n"
"\t\t键盘按键【ESC】- 退出程序\n\n"
"\t\t滑动滚动条 - 改变阈值\n\n");
}

测试效果:

poly

下一篇:OpenCV4入门系列教程86:图像距(几何矩、中心矩、hu矩)