1.目的
(1)使用openCV函数convexHull计算物体的凸包
2.原理
[1]什么是凸包
点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内。右图中由红色线段表示的多边形就是点集Q={p0,p1,…p12}的凸包。
一组平面上的点,求一个包含所有点的最小的凸多边形,这就是凸包问题了。这可以形象地想成这样:在地上放置一些不可移动的木桩,用一根绳子把他们尽量紧地圈起来,这就是凸包了。
[2]凸包作用
凸包在很多地方有着重要的应用,如手势识别,需要识别出手的轮廓的凸包,二维或者三维区域的边界的信息等。
3.部分代码解释
(1)convexHull
/*
convexHull参数解释
contours[i]:轮廓i点
hull[i]:凸包i的点
bool clockwise:bool变量,表示求得的凸包是顺时针方向还是逆时针方向,true是顺时针方向,false为逆时针方向
bool returnPoints:bool变量,表示是否返回凸包点
*/
convexHull(contours[i], hull[i], false);
4.完整代码
(1)CommonInclude.h
#ifndef COMMON_INCLUDE
#define COMMON_INCLUDE
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
#endif
(2)ConvexHull.cpp
#include"CommonInclude.h"
Mat src, src_gray, src_blur;
Mat src_canny;
int thresh = 50;
int max_thresh = 85;
char windowName[] = "convexHull";
RNG rng(12345);
void ThreshCallBack(int, void*){
vector< vector<Point> > contours;
vector<Vec4i> hirerarchy;
//边缘检测
Canny(src_gray, src_canny, thresh, 3*thresh, 3);
//threshold(src_gray, src_canny, thresh, 255, CV_THRESH_BINARY);
//寻找轮廓
findContours(src_canny, contours, hirerarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0));
vector< vector<Point> > hull(contours.size());
for(int i=0; i<contours.size(); i++){
//为每一个轮廓寻找凸包
/*
convexHull参数解释
contours[i]:轮廓i点
hull[i]:凸包i的点
bool clockwise:bool变量,表示求得的凸包是顺时针方向还是逆时针方向,true是顺时针方向,false为逆时针方向
bool returnPoints:bool变量,表示是否返回凸包点
*/
convexHull(contours[i], hull[i], false);
}
Mat drawing = Mat::zeros(src.size(), CV_8UC3);
for(int j=0; j<contours.size(); j++){
//绘制凸包
Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255));
drawContours(drawing, contours, j, color, 2, 8, vector<Vec4i>(), 0, Point());
drawContours(drawing, hull, j, color, 2, 8, vector<Vec4i>(), 0, Point());
}
imshow(windowName, drawing);
}
int main(int argc, char** argv){
if(argc<2){
cout << "more parameters are required!!!" << endl;
return(-1);
}
src = imread(argv[1]);
if(!src.data){
cout << "error to read imgea!!!" << endl;
return(-1);
}
namedWindow(windowName, CV_WINDOW_AUTOSIZE);
GaussianBlur(src, src_blur, Size(3,3), 0, 0);
cvtColor(src_blur, src_gray, CV_BGR2GRAY);
createTrackbar("Thresh:", windowName, &thresh, max_thresh, ThreshCallBack);
ThreshCallBack(0,0);
waitKey(0);
return(0);
}
参考文献
1.http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/shapedescriptors/hull/hull.html