凸包
凸包指如果在集合A内连接任意两个点的直线段都在A的内部,则称集合A是凸形的。简单点理解,就是一个多边型,没有凹的地方。凸包(凸壳)能包含点集中所有的点,凸包检测常应用在物体识别、手势识别及边界检测等领域。一个轮廓可以有无数个包围它的外壳,而其中表面积最小的一个外壳,就是凸包。
凸包绘制步骤
- 图像灰度处理
- 灰度图二值化处理
- 轮廓检测得到候选点
- 凸包API调用,筛选可用点
- 绘制显示
API介绍
void convexHull( InputArray points, OutputArray hull,bool clockwise = false, bool returnPoints = true );
/*******************************************************************
* points: 轮廓点集
* hull: 凸包点集输出
* clockwise: 凸包方向的标志位
* true:顺时针方向
* false:逆时针
* returnPoints: 返回点个数
*********************************************************************/
综合代码
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
class ConvexHull
{
public:
ConvexHull() :img(imread("hand.jpg"))
{
result["img"] = img;
}
void TestConvexHull()
{
//图像灰度处理
cvtColor(result["img"], result["Gray"], COLOR_BGR2GRAY);
//灰度图二值化处理
blur(result["Gray"], result["Gray"], Size(3, 3));//模糊处理
threshold(result["Gray"], result["Binary"], 240, 255, THRESH_BINARY_INV);
//轮廓检测得到候选点
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(result["Binary"], contours, hierarchy, RETR_EXTERNAL,CHAIN_APPROX_SIMPLE);
//凸包API调用,筛选可用点
//绘制显示
for (int i = 0; i < contours.size(); i++)
{
vector<Point> hull;
convexHull(contours[i], hull);
//bool isOk = isContourConvex(contours[i]); //判断当前点是否为有效点
int count = hull.size();
for (int j = 0; j < count; j++)
{
circle(img, hull[j], 5, Scalar(0, 0, 255));
line(img, hull[j % count], hull[(j + 1) % count], Scalar(255, 0, 0), 2);
}
}
}
void Show()
{
for (auto& v : result)
{
imshow(v.first, v.second);
}
waitKey(0);
}
private:
Mat img;
map<string, Mat> result;
};
int main()
{
ConvexHull* p = new ConvexHull;
p->TestConvexHull();
p->Show();
return 0;
}