转自:https://www.cnblogs.com/long5683/p/9694983.html


1 #include <opencv2/opencv.hpp>
2 #include <iostream>
3 #include <math.h>
4
5 using namespace cv;
6 using namespace std;
7
8
9 int main(int argc, char** argv)
10 {
11 Mat src = imread("3 input.bmp", IMREAD_GRAYSCALE);
12 Mat binary, dst = Mat::zeros(src.size(), CV_8UC3);
13 Mat Triangle = dst.clone(), Rect1 = dst.clone(), BigCircle = dst.clone(), SmallCircle = dst.clone();
14
15 if (src.empty()) {
16 printf("Could not load image...");
17 return -1;
18 }
19 src = ~src;//取反
20 imshow("原图", src);
21 //二值化
22 threshold(src, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
23
24 //发现轮廓
25 vector<vector<Point>> contours;
26 vector<Vec4i> hireachy;
27 findContours(binary, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
28
29 //面积删选
30 for (size_t t = 0; t < contours.size(); t++)
31 {
32 double area = contourArea(contours[t]);
33 if (area < 40000) continue;//将面积小于40000的去掉
34 drawContours(Triangle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());
35 }
36
37 for (size_t t = 0; t < contours.size(); t++)
38 {
39 double area = contourArea(contours[t]);
40 if (area > 40000 || area<20000) continue;//将面积小于40000的去掉
41 drawContours(BigCircle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());
42 }
43
44 for (size_t t = 0; t < contours.size(); t++)
45 {
46 double area = contourArea(contours[t]);
47 if (area > 20000 || area<15000) continue;//将面积小于40000的去掉
48 drawContours(Rect, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());
49 }
50
51 for (size_t t = 0; t < contours.size(); t++)
52 {
53 double area = contourArea(contours[t]);
54 if (area > 15000) continue;//将面积小于40000的去掉
55 //其他过滤方法
56
57 /*//横纵比过滤
58 Rect rect= boundingRect(contours[t]);//返回最小外接矩形
59 float ratio = float(rect.width) / float(rect.height);//计算横纵比
60 if (ratio<1.1&&ratio>0.9) {}
61
62 //周长过滤
63 float length = arcLength(contours[t], true);//计算轮廓长度
64
65 */
66
67
68 drawContours(SmallCircle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());
69 }
70 imshow("Triangle", Triangle);
71 imshow("BigCircle", BigCircle);
72 imshow("Rect", Rect1);
73 imshow("SmallCircle", SmallCircle);
74
75 waitKey(0);
76 return 0;
77 }

方法二:多边形逼近:
void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed);
参数说明:
InputArray curve:输入的点集
OutputArray approxCurve:输出的点集,当前点集是能最小包容指定点集的。draw出来即是一个多边形;
double epsilon:指定的精度,也即是原始曲线与近似曲线之间的最大距离。
bool closed:若为true,则说明近似曲线是闭合的,它的首位都是相连,反之,若为false,则断开。

1 #include <opencv2/opencv.hpp>
2 #include <iostream>
3
4 #define MATCHMETHOD TM_SQDIFF_NORMED//宏定义匹配模式
5 using namespace cv;
6 using namespace std;
7
8
9 int main(int argc, char** argv)
10 {
11 Mat src = imread("F:/2019视觉培训内容/2019视觉培训内容/3 input.bmp");
12 Mat src_gray,binary ;
13 Mat Triangle = src.clone(), Rect = src.clone(), BigCircle = src.clone(), SmallCircle = src.clone();
14 if (src.empty()) {
15 printf("Could not load image...");
16 return -1;
17 }
18 imshow("Input Image",src);
19
20 //二值化
21 cvtColor(src, src_gray, COLOR_BGR2GRAY);
22 threshold(src_gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
23 binary = ~binary;
24 imshow("binary", binary);
25
26 //发现轮廓
27 vector<vector<Point>> contours;
28 vector<Point> point;
29 vector<Vec4i> hireachy;
30 findContours(binary, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
31
32 //绘制出所有轮廓
33 for (size_t t = 0; t < contours.size(); t++)
34 {
35
36 int epsilon = 0.01*arcLength(contours[t], true);
37 approxPolyDP(contours[t], point, epsilon, true);
38 if(point.size()==3)
39 {
40 drawContours(Triangle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());//dst必须先初始化
41 }
42 else if (point.size() == 4)
43 {
44 drawContours(Rect, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());//dst必须先初始化
45 }
46
47 else
48 {
49 double area = contourArea(contours[t]);
50 if (area < 15000)
51 {
52 drawContours(SmallCircle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());//dst必须先初始化
53 }
54 else
55 {
56 drawContours(BigCircle, contours, t, Scalar(0, 0, 255), 2, 8, Mat(), 0, Point());//dst必须先初始化
57 }
58 }
59
60 cout << "边的数目:" << point.size() << endl;
61 }
62
63 imshow("Triangle", Triangle);
64 imshow("BigCircle", BigCircle);
65 imshow("Rect", Rect);
66 imshow("SmallCircle", SmallCircle);
67
68 waitKey(0);
69
70 return 0;
71 }

本文详细介绍了使用OpenCV进行图像处理的方法,包括图像的二值化、轮廓检测及多边形逼近等关键技术。通过面积筛选和多边形逼近,实现了不同形状物体的有效识别,如三角形、圆形和矩形。
1638





