OpenCV教程 之 寻找物体的轮廓与凸包:findContours、convexHull函数(C++)
来源:互联网 发布:珠海金山软件招聘 编辑:程序博客网 时间:2024/05/16 18:49
凸包(Convex Hull)是一个计算几何中常见的概念,简单来说,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有点,理解物体形状轮廓的一种比较有用的方法便是计算一个物体的凸包,然后计算其凸缺陷。很多复杂物体的性能能被这种缺陷表示出来
一、寻找轮廓:findContours()函数
一个轮廓一般对应着一系列的点,也就是图像中的一条曲线,在OpenCV中,可以用findContours()函数从二值图像中查找轮廓,我们先来看一下这个函数的函数原型
void findContours(InputOutArray image,OutputArrayOfArrays contours,outputArray hierarchy,int method,Point offset = Point())@第一个参数,InputArray类型的image,输入图像,即源图像,填Mat类对象即可,且需为8位单通道图像@第二个参数,OutputArrayOfArrays类型的contours,检测到的轮廓、函数调用后的运算结果存在这里。每一个轮廓存储为一个点向量,即用point类型的vector表示@第三个参数,outputArray类型的hierarchy,可选的输出量,包含图像的拓扑信息@第四个参数,int类型的mode,轮廓检索模式,取值有RETR_EXTERNAL、RETR_LIST、RETR_CCOMP、RETR_TREE@第五个参数,int类型的method,为轮廓的近似办法,取值有CHAIN_APPROX_NONE、CHAIN_APPROX_SIMPLE、CHAIN_APPROX_TC89_L1、CHAIN_APPROX_TC89_KCOS@第六个参数,Point类型的offset,每个轮廓点的可选偏移量,有默认值Point()
举个栗子
vector<vector<Point>> contours;findContours(image,countours,CV_RETR_EXTERNAL,CV_CHAIN_APROX_NONE)
二、绘制轮廓:drawContours()函数
findContours经常与drawContours配合使用,在使用findContours()函数检测到图像的轮廓以后,便可以用drawContours()函数将检测到的轮廓绘制出来,该函数的函数原型如下:
void drawContours(InputOutputArray image,InputArrayOfArrays contours,int contourIdx,const Scalar& color,int thickness = 1,int lineType = 8,inputArray hierarchy = noArray(),int maxLevel = INT_MAX,Point offset = Point())@第一个参数,InputArray类型的image,输入图像,即源图像,填Mat类对象即可@第二个参数,OutputArrayOfArrays类型的contours,所有的输入轮廓。每一个轮廓存储为一个点向量,即用point类型的vector表示@第三个参数,int类型的contourIdx,轮廓绘制的指示变量。如果其为负值,则绘制所有轮廓@第四个参数,constScalar&类型的color,轮廓的颜色@第五个参数,int thickness,轮廓线条的粗细,有默认值1@第六个参数,int类型的lineType,线条的类型,有默认值8@第七个参数,InputArray类型的hierarchy,可选的层次结构信息,有默认值noArray()@第八个参数,int类型的maxLevel,表示用于绘制轮廓的最大等级,有默认值INT_MAX@第九个参数,Point类型的offset,可选的轮廓偏移参数,默认为Point()
举个栗子:
使用下图作为原图像
//在白色图像上绘制黑色轮廓Mat result(image.size(),CV_8U,CV::Scalar(255));drawContours(result,contours,-1,Scalar(0),3);
二、convexHull函数
首先来介绍一下OpenCV中的这个凸包检测函数
void convexHull(InputArray points,OutputArray hull,bool clockwise = false,bool returnPoints = true)@第一个参数,InputArray类型的Points,输入的二维点集,可以填Mat类型或者std::vector@第二个参数,OutputArray类型的Hull,输出参数,函数调用后找到的凸包@第三个参数,bool类型的clockwise,操作方向标识符。当此标志符为真时,输出的凸包为顺时针方向,否则就为逆时针方向。并且是假定坐标系的x轴指向右,y轴指向上方@第四个参数,bool类型的returnPoints,操作符标识,默认为true。当标识符为真时,函数返回各个凸包的各个点。否则,它返回凸包各点的指数。当输出数组是std::vector时,此标志被忽略
三、应用举例
结合上面介绍的三个函数,我们来尝试一个完整的使用案例
//-------------------------------------【head file\namesapce declaration】------------------------------// statement: declare head file and namespace//-----------------------------------------------------------------------------------------------------#include <opencv2/core/core.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/highgui/highgui.hpp>#include <iostream>using namespace cv;using namespace std;typedef vector<Point> vec;//-------------------------------------【public Variables】---------------------------------------------// statement: declare global variables//-----------------------------------------------------------------------------------------------------Mat g_srcImage,g_grayImage;int g_nThresh = 50;int g_maxThresh = 255;RNG g_rng(12345);Mat srcImage_copy;Mat g_thresholdImage_ouput;vector<vec> g_vContours;vector<Vec4i> g_vHierarchy;//-------------------------------------【public function】---------------------------------------------// statement: declare global function//-----------------------------------------------------------------------------------------------------static void on_ThreshChange(int,void*);//--------------------------------------【main()function】----------------------------------------------// statement: our code run from here//-----------------------------------------------------------------------------------------------------int main(int argc,char *argv[]){ g_srcImage = imread("/Users/zhuxiaoxiansheng/Desktop/xiaoxin.jpg",1 ); cvtColor(g_srcImage,g_grayImage,COLOR_BGR2GRAY); blur(g_grayImage,g_grayImage,Size(3,3)); namedWindow("srcIamge"); imshow("srcImage",g_srcImage); waitKey(); namedWindow("show"); createTrackbar("ThresholdValue:","show",&g_nThresh,g_maxThresh,on_ThreshChange); on_ThreshChange(0,0); waitKey(); return(0);}//----------------------------------【thresh_callback() function】--------------------------------------// statement: Thresh's help function//-----------------------------------------------------------------------------------------------------static void on_ThreshChange(int,void*){ threshold(g_grayImage,g_thresholdImage_ouput,g_nThresh,255,THRESH_BINARY); findContours(g_thresholdImage_ouput,g_vContours,g_vHierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point(0,0)); vector<vec> hull(g_vContours.size()); for(unsigned int i =0;i < g_vContours.size();i++) convexHull(Mat(g_vContours[i]),hull[i],false); Mat drawing = Mat::zeros(g_thresholdImage_ouput.size(),CV_8UC3); for(unsigned int i = 0;i<g_vContours.size();i++){ Scalar color = Scalar(g_rng.uniform(0,255),g_rng.uniform(0,255),g_rng.uniform(0,255)); drawContours(drawing,g_vContours,i,color,1,8,vector<Vec4i>(),0,Point()); drawContours(drawing,hull,i,color,1,8,vector<Vec4i>(),0,Point()); } imshow("show",drawing);}
效果如下:
这里有更完整的代码介绍:
https://github.com/LiangjunFeng/Implement-OpenCV
阅读全文
0 0
- OpenCV教程 之 寻找物体的轮廓与凸包:findContours、convexHull函数(C++)
- 【OpenCV笔记 15-1】OpenCV寻找物体的凸包convexHull
- opencv学习(四十一)之寻找凸包convexHull()
- 计算物体的凸包--convexHull()
- 计算物体的凸包(convexHull)
- OpenCV在图像中寻找轮廓和计算图像中物体的凸包
- opencv学习(四十)之寻找图像轮廓findContours()
- Opencv学习之寻找和绘制物体的凸包
- 使用OpenCV的函数findContours提取轮廓并绘制轮廓
- opencv学习之寻找凸包,使用多边形包围轮廓
- FindContours 寻找轮廓 参数
- 寻找轮廓findContours
- [转]opencv轮廓提取(findcontours函数详解)
- 轮廓的凸包寻找
- opencv floodfill与findContours结合提取轮廓
- OpenCV之imgproc 模块. 图像处理(5)在图像中寻找轮廓 计算物体的凸包 创建包围轮廓的矩形和圆形边界框 为轮廓创建可倾斜的边界框和椭圆 轮廓矩 多边形测试
- EmgnCv进行轮廓寻找和计算物体凸包
- python-opencv2利用cv2.findContours()函数来查找检测物体的轮廓
- Linux下多进程编程
- 【C++】链表实现约瑟夫环
- 深刻理解python装饰器
- 软件测试学习笔记第二课:测试对象和测试级别的定义
- C指针详解与链表实现
- OpenCV教程 之 寻找物体的轮廓与凸包:findContours、convexHull函数(C++)
- 专业术语:迭代、循环、遍历与递归的区别
- 第十三周图形用户界面2
- netty源码分析(二十)NIO堆外内存与零拷贝深入讲解
- HTML5游戏2
- ASP.NET Core 企业级开发架构简介及框架汇总
- c语言实现两数交换
- linux打开一个有管理员权限的文件夹
- 浅谈摩尔定律