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 }