#include <opencv2/opencv.hpp>using namespace std;
using namespace cv;int main()
{Mat srcGary = imread("./141-1.png", 0);imshow("srcGary", srcGary);// 阈值化操作Mat threMat;int thresh = 128;threshold(srcGary, threMat, thresh, 255, THRESH_BINARY);// 轮廓检测vector<vector<Point> > contours;vector<Vec4i> hierarchy;findContours(threMat, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); //注意:在3.X版本中,标志为:CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE// 绘制轮廓Mat contours_img(srcGary.size(), CV_8U, Scalar(0));drawContours(contours_img, contours, -1, Scalar(255), 1);imshow("contours_img", contours_img);//凸包检测和凸包缺陷检测vector<vector<Point> > pointHull(contours.size());vector<vector<int> > intHull(contours.size());vector<vector<Vec4i> > hullDefect(contours.size());for (size_t i = 0; i < contours.size(); i++){// 输出结果为Point类型的凸包检测convexHull(Mat(contours[i]), pointHull[i], false);// 输出结果为int类型的凸包检测convexHull(Mat(contours[i]), intHull[i], false);//凸包缺陷检测convexityDefects(Mat(contours[i]), intHull[i], hullDefect[i]);}//绘制凸包及凸包缺陷Mat convex_hull_img = contours_img.clone();cvtColor(convex_hull_img, convex_hull_img, COLOR_GRAY2BGR);for (size_t i = 0; i < contours.size(); i++){Scalar color = Scalar(0, 0, 255);drawContours(convex_hull_img, pointHull, i, color, 1, 8, vector<Vec4i>(), 0, Point());// 绘制缺陷size_t count = contours[i].size();if (count < 300) //小于300个点的轮廓略去continue;// 凸包缺陷迭代器设置vector<Vec4i>::iterator iterDefects = hullDefect[i].begin();// 遍历得到凸包缺陷的4个特征量并进行绘制int num = 0;while (iterDefects != hullDefect[i].end()){Vec4i& v = (*iterDefects);// 起始位置int startidx = v[0];Point ptStart(contours[i][startidx]);// 终止位置int endidx = v[1];Point ptEnd(contours[i][endidx]);// 内凸壳的最远的点缺陷int faridx = v[2];Point ptFar(contours[i][faridx]);// 凸包之间的最远点int depth = v[3] / 256;if (depth > 10 && depth < 1000){line(convex_hull_img, ptStart, ptFar, CV_RGB(0, 255, 0), 2);line(convex_hull_img, ptEnd, ptFar, CV_RGB(0, 255, 0), 2);circle(convex_hull_img, ptStart, 4, Scalar(255, 0, 0), 2);//ptStart用蓝色circle(convex_hull_img, ptEnd, 4, Scalar(255, 0, 128), 2);//ptEnd用紫色circle(convex_hull_img, ptFar, 4, Scalar(128, 0, 255), 2);//ptFar用粉红色cv::putText(convex_hull_img, std::to_string(num++), ptStart,FONT_HERSHEY_SIMPLEX,0.5,Scalar(0, 255, 255));cv::putText(convex_hull_img, std::to_string(num++), ptEnd,FONT_HERSHEY_SIMPLEX,0.5,Scalar(0, 255, 255));cv::putText(convex_hull_img, std::to_string(num++), ptFar,FONT_HERSHEY_SIMPLEX,0.5,Scalar(0, 255, 255));}iterDefects++;}}imshow("./141-1-hull.png", convex_hull_img);cv::imwrite("./141-1-hull.png", convex_hull_img);cv::waitKey();return 0;
}



