什么是凸包(Convex Hull),在一个多变形边缘或者内部任意两个点的连线都包含在多边形边界或者内部。
正式定义:包含点集合S中所有点的最小凸多边形称为凸包。凸包可以想象为一条刚好包着所有点的橡皮圈,用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点。
convexHull(
InputArray points,// 输入候选点,来自findContours
OutputArray hull,// 凸包
bool clockwise,// default true。操作方向,当标识符为真时,输出凸包为顺时针方向,否则为逆时针方向。
bool returnPoints)//操作标识符,默认值为true,此时返回各凸包的各个点,否则返回凸包各点的指数,当输出数组时std::vector时,此标识被忽略。
)
#include
#include
using namespace std;
using namespace cv;
Mat srcImage, grayImage;
int thresh = 100;
const int threshMaxValue = 255;
RNG rng(12345);
//定义回调函数
void thresh_callback(int, void*);
int main()
{
srcImage = imread("E:/Experiment/OpenCV/Pictures/HandTest.jpg");
//判断图像是否加载成功
if (srcImage.empty()){
cout << "图像加载失败" << endl;
return -1;
}
//图像灰度图转化并平滑滤波
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
blur(grayImage, grayImage, Size(3, 3));
namedWindow("原图像", WINDOW_AUTOSIZE);
imshow("原图像", grayImage);
//创建轨迹条
createTrackbar("Threshold:", "原图像", &thresh, threshMaxValue, thresh_callback);
thresh_callback(thresh, 0);
waitKey(0);
return 0;
}
void thresh_callback(int, void*)
{
Mat src_copy = srcImage.clone();
Mat threshold_output;
vector<vector<Point>>contours;
vector<Vec4i>hierarchy;
//使用Threshold检测图像边缘,对图像进行二值化
threshold(grayImage, threshold_output, thresh, 255, THRESH_BINARY);
//寻找图像轮廓
findContours(threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
//寻找图像凸包
vector<vector<Point>>hull(contours.size());
for (int i = 0; i < contours.size(); i++){
convexHull(Mat(contours[i]), hull[i], false);
}
//绘制轮廓和凸包
Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3);
for (int i = 0; i < contours.size(); i++){
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
drawContours(drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point());
drawContours(drawing, hull, i, color, 1, 8, vector<Vec4i>(), 0, Point());
}
namedWindow("凸包", WINDOW_AUTOSIZE);
imshow("凸包", drawing);
}
- https://blog.csdn.net/keith_bb/article/details/70194073