1)凸包
凸包是一个计算机几何图形学中的概念,简单来说,给定二维平面点集,凸包就是能够将最外层的点连接起来构成的凸多边形,他能够包含点集中所有的点,物体的凸包检测常应用在物体识别,手势识别及边界检测等领域
寻找凸包–convexHull()
void convexHull(InputArray points,OutputArray hulll,bool clockwise=false,bool returnPoints=true);
&&points:输入的二维点集,可以填Mat类型或std::vector
&&hull:函数调用后找到的凸包
&&clockwise:操作方向标识符,当为true时,输出的凸包为顺时针方向,,false为逆时针方向(假定坐标系x轴指向右,Y轴指向上方)
&&returnPoints:操作标志符,默认值true,当标识符为true时,函数返回凸包的各个点,否则返回凸包各点的指数,当输出数组是std::vector,此标志被忽略
ex1:
vectorhull;
convexHull(Mat(points),hull,true);
ex2:
vector<vector<Point>>hull(contours.size());
for(int i=0;i<contours.size();i++)
{
convexHull(Mat(contours[i],hull[i],true));
}
凸包缺陷分析–convexityDefects()
void convexityDefevts(InputArray contour,InputArray convexhull,OutputArray convexityDefects);
&&contour:表示输入参数检测到的轮廓,可以用findContours函数获得
&&convexhull:输入参数表示检测到的凸包,可以用convexHull函数获得
&&convexityDefects:检测到的最终结果,应为vector < vector /Vec4i>>类型,Vec4i存储了起始点,结束点,距离及最远点到凸包的距离
void main()
{ //--绘制点集的凸包
Mat img(500,500,CV_8UC3,Scalar::all(0));//定义绘制图像 纯黑
RHG rng;//c++产生随机数的类
while(1)
{
char key;
int count=(unsigned int)rng%100;//定义点的个数
vector<Point>points;//定义点集
for(int i=0;i<count;i++)
{
Point pt;
pt.x=rng.uniform(img.cols/4,img.cols*3/4);//设定点的x范围设定随机数范围
pt.y=rng.uniform(img.rows/4,img.rows*3/4);//设定点的Y范围
point.pish_back(pt);//把点保存到这个点集里面
}
//检测凸包
vector<int>hull;
convexHull(Mat(points),hull,true);
img=Scalar:all(0);
for(int i=0;i<count;i++)
circle(img,points[i],3,Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255)),CV_FILLED,CV_AA);
//准备参数
int hullcount=(int)hull.size();//凸包的边数
Point point0=point[hull][hullcount-1];//连接凸包边的坐标点
for(int i=0;i<hullcount;i++)
{
Point point=points[hull][i];
circle(img,point,3,Scalar(0,255,0),2,8);
line(img,point0,point,Scalar(255,255,255),2,CV_AA);
point0=point;
}
//显示效果图
imshow("img",img);
key=(char)waitKey();
if(key==27||key=='q'||key=='Q')
break;
}
return ;
}
//绘制轮廓的凸包
Mat srcImg=imread("22.jpg");
imshow("src",srcImg);
//Mat dstImg=srcImg.clone();
Mat dstImg(srcImg.rows,srcImg.cols,CV_8UC3,Scalar::all(0));
cvtColor(srcImg,srccImg,CV_BGR2GRAY);
threshold(srcImg,srcImg,100,255,CV_THRESH_BINARY_INV);//二值化 取反
vector<vector<Point>>contours;
vector<Vec4i>hierarcy;
findContours(srcImg,contours,hierarcy,CV_RETR_TREE,CV_HAIN_APPROX_NONE);
vector<vector<Point>>hull(contours.size());//一定要指定size
for(int i=0;i<contours.size();i++)
{
convexHull(Mat(contours[i]),hull[i],ture);//查找凸包
}
for(int i=0;i<contours.size();i++)
{
drawContours(dstImg,contours,i,Scalar(255,255,255),1,8);//绘制轮廓
drawContours(dstImg,hull,i,Scalar(rand()%255,rand()%255,rand()%255),2,8);//绘制凸包
}
imshow("dst",dstImg);
waitKey(0);
//利用图像做差 来查找凸包缺陷