首页 > 编程知识 正文

opencv轮廓,opencv轮廓检测

时间:2023-05-04 10:27:15 阅读:163592 作者:3228

找出图像的轮廓在图像处理和APP应用中起着重要的作用。 那么什么是“轮廓”? 在《Learning OpenCV 3》中给出的定义是这样的——轮廓用某种方式表示图像中的曲线的点的列表。 该表示可以根据实际情况而不同。 表示一条曲线的方法有很多种。 在OpenCV中,轮廓由STL样式的向量模板对象表示,向量中的每个元素编码曲线上下一个点的位置信息。

在opencv2和opencv3中找到图像轮廓的函数在图像上绘制在cv:findContours ()、cv:drawContours ()中找到的轮廓。

1、轮廓的查找——cv::findContours()

函数cv:findContour根据二值图像计算轮廓。 cv:Canny () )函数可以处理的图像是因为包含边缘像素。 也可以使用由cv:threshold ((或cv:adaptiveThreshold ) )处理的图像,使其边缘隐藏在正负区域的边界上。

轮廓的层级结构

下图显示了cv:findCountour () )的基本功能。 图的上部是测试图像,背景为白色,包含几个颜色区域(标签a (到e ) )。 图中还绘制了由cv:findContours () )确定的轮廓。 这些轮廓被标记为cX或hX。 其中c是“contour”,h是“孔”,x是一些数字。 有些轮廓用虚线表示,表示白色区域或非零区域的外部边界。 OpenCV和cv:findContour ()区分这些外部边界和图中的虚线,即内部边界或孔的外部边界。

如图的下半部分所示,OpenCV可以将找到的轮廓组织成轮廓树,表示其轮廓结构的包围关系。 对于测试图像的轮廓,根节点的轮廓称为c0,“孔”h00和h01是其子节点。 相反,这些子节点将包含新的子节点。

有几种方法表示此树。 OpenCV使用数组表示此树,特别是vectors。 数组中的每个条目都表示一个特定的大纲,每个条目都包含一个由四个整数组成的集合。 通常表示为cv : Vec4i类型的元素,如4通道数组中的条目。 对于每个节点,四个元素分别表示以下含义: 0号元素表示下一个轮廓(同一级别)。 第一个元素表示上一个轮廓(同一级别); 第二个元素表示第一个子配置文件(下一级别); 第三个元素表示父配置文件(上一级)。

使用cv::findContours()查找轮廓

具体调用cv:findContours (),有以下两种方法。

void cv :3360 find contours (cv :3360 inputoutputarrayimage,//输入的8位单通道“2值”图像cv : outputarrrayofarrrarimage vectors的vector cv :3360 outputarrayhierarchy,//(可选)拓扑信息int mode,//配置文件搜索模式int method, //近似方法cv 33603360 pointoo de void cv :3360 find contours (cv :3360 inputoutputarrayimage, vectors的vectorint mode,//轮廓搜索模式,包括输入的8位单通道“2值”图像cv : outputarrayofarrayscontours,points

其中,第一个参数是输入图像,图像格式为8位单通道图像,将被解析为二进制图像。 也就是说,图中非零的所有像素都是相同的。

第二个参数是数组数组,在大多数实际操作中是STL vectors的STL vector。 在这里,用找到的轮廓列表填充。 也就是说,这是contours的向量,contours[i]表示特定的轮廓。 这样,contours[i]就可以

第三个参数hierarchy,可以指定也可以不指定此参数。 如果指定,输出hierarchy将描述输出配置文件树的结构信息。 其中包含的具体信息已经说明(四项)。

以下参数、轮廓的模式告诉OpenCV想要如何提取轮廓。 有四个选项值,如下图所示。

cv:RETR_EXTERNAL :表示仅提取最外侧轮廓;

cv:RETR_LIST :表示提取所有轮廓并将其放入列表中;

cv:RETR_CCOMP:表示提取所有轮廓并组织为一个双层结构。 其中,顶层轮廓是外部轮廓,第二个轮廓是“孔”轮廓。

cv:RETR_TREE :提取所有轮廓,表示轮廓嵌套的完整分层结构。

>




下一个参数是见识方法,即轮廓如何呈现的方法,有三种可选的方法:

cv::CHAIN_APPROX_NONE:将轮廓中的所有点的编码转换成点;

cv::CHAIN_APPROX_SIMPLE:压缩水平、垂直和对角直线段,仅保留它们的端点;

cv::CHAIN_APPROX_TC89_L1 or cv::CHAIN_APPROX_TC89_KCOS:应用Teh-Chin链近似算法中的一种风格

最后一个参数是偏移,可选,如果是定,那么返回的轮廓中的所有点均作指定量的偏移。


2、轮廓的绘制——cv::drawContours()

cv::drawContours()用于绘制cv::findContours()找到的轮廓。使用方法其实和OpenCV3中常用的绘图函数类似。具体调用方法如下:

void cv::drawContours(cv::InputOutputArray image, // 用于绘制的输入图像cv::InputArrayOfArrays contours, // 点的vectors的vectorint contourIdx, // 需要绘制的轮廓的指数 (-1 表示 "all")const cv::Scalar& color, // 轮廓的颜色int thickness = 1, // 轮廓线的宽度int lineType = 8, // 轮廓线的邻域模式('4'邻域 或 '8'邻域)cv::InputArray hierarchy = noArray(), // 可选 (从 findContours得到)int maxLevel = INT_MAX, // 轮廓中的最大下降cv::Point offset = cv::Point() // (可选) 所有点的偏移)

下面是这两个函数的实际使用示例:

cv::Mat image_gray = cv::imread("lena.jpg", cv::IMREAD_GRAYSCALE);cv::Mat image_binary;cv::threshold(image_gray, image_binary, 100, 255, cv::THRESH_BINARY);std::vector< std::vector< cv::Point> > contours;cv::findContours(image_binary,contours,cv::noArray(),cv::RETR_LIST,cv::CHAIN_APPROX_SIMPLE);image_binary = cv::Scalar::all(0);cv::drawContours(image_binary, contours, -1, cv::Scalar::all(255));cv::imshow("gray image", image_gray);cv::imshow("Contours", image_binary);cv::waitKey(0);return;

结果如下:



2017.04.05

补充:最大轮廓检测,请参考《【OpenCV3】图像最大轮廓检测——cvFindBiggestContour()封装》一文

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。