1 #include <opencv2/opencv.hpp> 2 #include <iostream> 3 4 using namespace std; 5 using namespace cv; 6 7 Mat searchConcaveRegion(vector<vector<Point> >hull, Mat &src); 8 vector<Point2f> searchConcavePoint(Mat &src); 9 10 void main() 11 { 12 Mat img = imread("C:\\4.jpg",1); 13 Mat gray, gray_back; 14 15 cvtColor(img, gray, CV_BGR2GRAY); 16 17 threshold(gray, gray, 0, 255, CV_THRESH_OTSU); 18 gray_back = gray.clone(); 19 20 //提取轮廓 21 vector<vector<Point>>contours; 22 findContours(gray, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); 23 drawContours(img, contours, -1, Scalar(0, 0, 255), 2); 24 25 Mat aotu = searchConcaveRegion(contours, gray_back); 26 vector<Point2f> pt; 27 pt = searchConcavePoint(aotu); 28 29 line(img, pt[pt.size() - 2], pt[pt.size() - 1], Scalar(255, 0, 0), 2, 8, 0); 30 31 imshow("切割线", img); 32 waitKey(0); 33 } 34 35 /** 36 * @brief searchConcaveRegion 寻找凹区域 37 * @param hull 凸包点集 38 * @param src 原图像(二值图) 39 * @return 返回 图像凹区域 40 */ 41 Mat searchConcaveRegion(vector<vector<Point> >contours, Mat &src) 42 { 43 if (src.empty()) 44 return Mat(); 45 46 //遍历每个轮廓,寻找其凸包 47 vector<vector<Point>>hull(contours.size()); 48 for (unsigned int i = 0; i<contours.size(); ++i) 49 { 50 convexHull(Mat(contours[i]), hull[i], false); 51 } 52 53 //绘制轮廓及其凸包 54 Mat drawing = Mat::zeros(src.rows, src.cols, CV_8UC1); 55 for (unsigned int i = 0; i < contours.size(); ++i) 56 { 57 drawContours(drawing, hull, i, Scalar(255), -1, 8, vector<Vec4i>(), 0, Point()); 58 drawContours(drawing, contours, i, Scalar(0), -1, 8, vector<Vec4i>(), 0, Point()); 59 } 60 61 medianBlur(drawing, drawing, 3); 62 63 imshow("凹区域", drawing); 64 65 return drawing; 66 } 67 68 /** 69 * @brief searchConcavePoint 70 * @param src 凹区域图像 71 * @return 返回匹配好的凹点对(2个) 72 */ 73 vector<Point2f> searchConcavePoint(Mat &src) 74 { 75 vector<Point2f> ConcavePoint; 76 //轮廓寻找 77 vector<vector<Point> > contour;//用来存储轮廓 78 vector<Vec4i> hierarchys; 79 findContours(src, contour, hierarchys, 80 CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); //寻找轮廓 81 82 //凹区域少于2要退出 83 if (contour.size()<2) 84 return ConcavePoint; 85 86 //按照轮廓面积大小排序 87 sort(contour.begin(), contour.end(), [](const vector<Point> &s1, 88 const vector<Point> &s2){ 89 double a1 = contourArea(s1); 90 double a2 = contourArea(s2); 91 return a1>a2; 92 }); 93 94 int minDistance = 100000000;//最短距离 95 for (int i = 0; i<contour[0].size(); ++i) 96 for (int j = 0; j<contour[1].size(); ++j) 97 { 98 //欧氏距离 99 int d = sqrt(pow((contour[0][i].x - contour[1][j].x), 2) + 100 pow((contour[0][i].y - contour[1][j].y), 2)); 101 if (minDistance>d) 102 { 103 minDistance = d; 104 ConcavePoint.push_back(contour[0][i]); 105 ConcavePoint.push_back(contour[1][j]); 106 } 107 } 108 cout << "ConcavePoint0:" << ConcavePoint[ConcavePoint.size() - 2].x << "," << ConcavePoint[ConcavePoint.size() - 2].y << endl; 109 cout << "ConcavePoint1:" << ConcavePoint[ConcavePoint.size() - 1].x << "," << ConcavePoint[ConcavePoint.size() - 1].y << endl; 110 111 return ConcavePoint; 112 }