opencv(21)---轮廓属性特征以及应用之凹包
2017-05-21 21:01
561 查看
凸包
基本概念
凸包(Convex Hull)是一个计算机几何图形学中的概念, 简单来说, 给定二维平面点集, 凸包就是能够将最外层的点连接起来构成的凸多边形, 它能够包含点集中所有的点。物体的凸包检测场应用在物体识别、手势识别及边界检测等领域。寻找凸包—convexHull()
函数原型
points: 输入的二维点集, 可以填Mat类型或std::vector
hull: 函数调用后找到的凸包
clockwise: 操作方向标志符, 当为true时, 输出的凸包为顺时针方向, false为逆时针方向(假定坐标系x轴指向右,y轴指向上方)
returnPoints: 操作标志符, 默认值true. 当标志符为true时, 函数返回凸包各个点, 否则返回凸包各点的指数, 当输出数组是std::vector时, 此标志被忽略
凹包一- - -点集的凹包
代码
Mat img(500, 500, CV_8UC3, Scalar::all(0)); //定义绘制图像 RNG rng; //定义随机数对象 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范围 points.push_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 = points[hull[hullcount-1]]; //连接凸包边的坐标点 //绘制凸包的边 for(int i = 0; i < hullcount; i++ ) { Point point = points[hull[i]]; circle(img, point, 8, Scalar(0, 255, 0), 2, 8); line(img, point0, point, Scalar(255, 255, 255), 2, CV_AA); point0 = point; } //显示效果图 imshow("img", img); //按下ESC,Q,或者q,程序退出 key = (char)waitKey(); if( key == 27 || key == 'q' || key == 'Q' ) break; } return;
运行结果
凹包二- - -轮廓的凹包
代码
Mat srcImg = imread("D:\\1\\12.jpg"); imshow("src", srcImg); Mat dstImg2 = srcImg.clone(); Mat tempImg(srcImg.rows, srcImg.cols, CV_8UC3, Scalar::all(0)); //用于绘制凸包 Mat dstImg(srcImg.rows, srcImg.cols, CV_8UC3, Scalar::all(0)); //用于绘制轮廓 cvtColor(srcImg, srcImg, CV_BGR2GRAY); threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY); //二值化 vector<vector<Point>> contours; vector<Vec4i> hierarcy; findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); vector<vector<Point>> hull(contours.size()); //凸包是对每个轮廓来进行的 for(int i=0; i<contours.size(); i++) { convexHull(Mat(contours[i]), hull[i], true); //查找凸包 } 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); drawContours(tempImg, hull, i, Scalar(255, 255, 255), -1, 8); } imshow("hull", tempImg); imshow("contours", dstImg);
运行结果
原图轮廓
凹包
凸包与轮廓
二者是不同的两个概念,可以利用二者的差,寻找工件的瑕疵区域Mat srcImg = imread("D:\\1\\10.png"); imshow("src", srcImg); Mat dstImg2 = srcImg.clone(); Mat tempImg(srcImg.rows, srcImg.cols, CV_8UC3, Scalar::all(0)); //用于绘制凸包 Mat dstImg(srcImg.rows, srcImg.cols, CV_8UC3, Scalar::all(0)); //用于绘制轮廓 cvtColor(srcImg, srcImg, CV_BGR2GRAY); threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY); //二值化 vector<vector<Point>> contours; vector<Vec4i> hierarcy; findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); vector<vector<Point>> hull(contours.size()); //凸包是对每个轮廓来进行的 for(int i=0; i<contours.size(); i++) { convexHull(Mat(contours[i]), hull[i], true); //查找凸包 } 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); drawContours(tempImg, hull, i, Scalar(255, 255, 255), -1, 8); } imshow("hull", tempImg); imshow("contours", dstImg); Mat diffImg; absdiff(tempImg, dstImg, diffImg); //图像相减 //通过对图像进行腐蚀,来去除边缘的一些区域 Mat element = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1)); erode(diffImg, diffImg, element); imshow("diff", diffImg); vector<vector<Point>> contours2; vector<Vec4i> hierarcy2; cvtColor(diffImg, diffImg, CV_BGR2GRAY); //转为灰度图 threshold(diffImg, diffImg, 100, 255, CV_THRESH_BINARY); //二值化 findContours(diffImg, contours2, hierarcy2, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); drawContours(dstImg2, contours2, -1, Scalar(0, 0, 255), 2, 8); //红色绘制缺陷轮廓 imshow("defects", dstImg2); waitKey(0);
运行结果
凸包缺陷分析—convexityDefects()
函数原型
contour: 表示输入参数检测到的轮廓, 可以用findContours函数获得
convexhull: 输入参数表示检测到的凸包, 可以用convexHull函数获得
convexityDefects: 检测到的最终结果, 应为vector
相关文章推荐
- 【OpenCV学习笔记】三十、轮廓特征属性及应用(七)—位置关系及轮廓匹配
- opencv(25)---轮廓特征属性及应用之矩
- 【OpenCV学习笔记】三十一、轮廓特征属性及应用(八)——颜色物体识别与跟踪
- OpenCV学习笔记】二十七、轮廓特征属性及应用(四)——正外接矩形
- opencv(23)---轮廓特征属性及应用之最小外接矩形
- opencv之轮廓特征属性及应用
- opencv之轮廓特征属性及应用(一)
- 【OpenCV学习笔记】二十七、轮廓特征属性及应用(四)——正外接矩形
- opencv(24)---轮廓特征属性及应用之最小外接圆
- opencv之轮廓特征属性及应用
- opencv之轮廓特征属性及应用
- 【OpenCV学习笔记】三十、轮廓特征属性及应用(七)—位置关系及轮廓匹配
- opencv之轮廓特征属性及应用
- opencv(26)---轮廓特征属性及应用之颜色空间
- opencv(22)---轮廓特征属性及应用之使用特定形状的轮廓
- 【OpenCV学习笔记】二十九、轮廓特征属性及应用(六)——外接圆等
- 【OpenCV学习笔记】二十六、轮廓特征属性及应用(三)——凸包
- opencv之轮廓特征属性及应用
- 【opencv学习之三十五】轮廓特征应用:按轮廓剪切图像ROI
- 【opencv学习之三十六】轮廓特征应用:计算点与轮廓距离