凸包是计算机几何中常见的概念。简单来说,给定二维平面上的点集,凸包就是将最外层的点连接起来构成凸多边形,它是能包含点集中所有点的。理解物体形状或轮廓的一种比较有用的方法是计算一个物体的凸包,然后计算其凸缺陷,很多复杂物体的特性能很好的被这种缺陷表现出来。
convexHull()函数
OpenCV中用convexHull()函数寻找图像点集中的凸包,函数原型:
void convexHull(InputArray points, OutputArray hull, bool clockwise=false, bool returnPoints=true)
参数详解:
- 第一个参数:输入的二维点集,可以是Mat类型的或std::vector。
- 第二个参数:输出,检测到的凸包。
- 第三个参数:bool类型的clockwise,操作方向标识符。当此标识符为真时,输出的凸包为顺指针方向,否则就是逆时针方向。
- 第四个参数:操作标识符,默认是true。当标识符是真时,函数返回凸包的各个点,否则返回凸包的各点指数。
代码示例:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main() {
// 读取图像
Mat srcImage = imread("/Users/dwz/Desktop/cpp/a.jpg");
cout << srcImage.size << endl;
cout << srcImage.channels() << endl;
// 将图像转化为灰度图,可进行阈值化,这里省略
Mat grayImage;
grayImage.create(srcImage.rows, srcImage.cols, CV_8U);
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
// 声明contours
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
// 寻找轮廓
findContours(grayImage, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
// 凸包检测
vector<vector<Point>> hull(contours.size());
for (unsigned int i=0; i < contours.size(); i++)
{
convexHull(Mat(contours[i]), hull[i], false);
}
// 分别画出轮廓和凸包
for (unsigned int i = 0; i < contours.size();i++)
{
drawContours(grayImage, contours, i, Scalar(0,0, 255), 1, 8, vector<Vec4i>(), 0, Point());
drawContours(grayImage, hull, i, Scalar(255,0,0), 1, 8, vector<Vec4i>(), 0, Point());
}
imwrite("hull.jpg", grayImage);
return 0;
}
输入:
输出: