包含点s集合中所有点的最小凸多边形的名字叫凸包
Graham扫描算法:
1.从y轴最低点作为起始点p0
2.从p0开始极坐标扫描,依次遍历图中所有的点,按极坐标角度大小,逆时针方向遍历
3.如果新遍历的点能产生一个左旋转,则将该点添加到凸包中,否则舍去
实现流程
1.彩色图像转灰度图像
2.灰度图像转二值图像
3.通过发现轮廓得到候选点
4.计算凸包
5.绘制结果
cv::convexHull()
InputArrays Poins 输入候选点
OutputArray hull 凸包集合
bool clockwise 顺时针方向
bool returnPoints 表示返回点个数,如果第二个参数(凸包)是vector<Points>则自动忽略
#include<iostream> #include<vector> #include<opencv2/opencv.hpp> using namespace std; using namespace cv; int Threshold_value = 100; int Threshold_max = 255; Mat src, dst, canny_output, grayImg; void demo(int, void*); int main(int argc, char** argv) { src = imread("C:/Users/Administrator/Desktop/3.png"); imshow("input_pic", src); cvtColor(src, grayImg, COLOR_BGR2GRAY); blur(grayImg, grayImg, Size(3, 3), Point(-1, -1), BORDER_DEFAULT);//标准化盒式过滤器平滑图像 createTrackbar("Threshold:", "input_pic", &Threshold_value, Threshold_max,demo); demo(0, 0); waitKey(0); return 0; } void demo(int, void*) { vector<vector<Point>> points; vector<Vec4i>hierachy; threshold(grayImg, canny_output, Threshold_value, Threshold_max, THRESH_BINARY);//二值化 findContours(canny_output, points, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); vector<vector<Point>> convex(points.size()); for (size_t i = 0; i < points.size(); ++i) { convexHull(points[i], convex[i], false, true);//凸包算法 } dst = Mat::zeros(grayImg.size(), CV_8UC3); vector<Vec4i> empty(0); for (size_t i = 0; i < points.size(); ++i) { Scalar color = Scalar(0,0,255); drawContours(dst, points, i, color, 1,LINE_8, empty, 0, Point(0, 0)); } imshow("rslt", dst); }