首页 > 编程知识 正文

opencv2轮廓检测,opencv获取轮廓内所有像素

时间:2023-05-04 19:37:13 阅读:127057 作者:1654

目录一、基本概念1.1轮廓层次1.2轮廓层次列表(hierarchy )中四要素数组中各要素的含义二、findContours函数的细节三、代码示例四、drawContours函数的细节五、代码示例六、详细解释6.1 mode method将CHAIN_APPROX_NONE6.2 mode的值变更为RETR_LIST,将method的值变更为CHAIN_APPROX_SIMPLE; 6.3 mode更改为RETR_TREE,method更改为CHAIN_APPROX_NONE

一、基本概念

因为基本概念我差不多都知道,所以我相信读了详细的说明后,再回到基础概念上来看,会有更深的理解。

1.1轮廓级别如图所示为一张图像:

图中有五个颜色区域,分别标记为a、b、c、d、e。 各区域的外部边界和内部边界分别构成轮廓,轮廓数如下图所示。

构建大纲树:

每个节点都是一个大纲,根据每个节点层次结构中四元数组的索引进行标记,如下表所示。

1.2轮廓层次列表(hierarchy )中四元素数组中各元素的语义索引语义0兄弟下一个轮廓1兄弟上一个轮廓2下级第一个子节点3上级父节点2,findContours函数详解函数原型:

find contours (inputoutputarrayimage,OutputArrayOfArrays contours,OutputArray hierarchy,int mode,int method,pointoffset爸爸)

image :图像必须是8位单通道图像,可以是灰度图像,但更常用的是二值图像,一般由Canny、忧郁酒馆等边缘检测算子处理后的二值图像; (当函数运行时,此图像将直接填充。 因此,如果将来有要使用的图像,则应该复制后传递给此函数。 ) contours :定义为vectorvectorpointcontours。 向量,向量中的每个元素存储由连续点组成的点集合的向量。 每个点集都是一个轮廓,有几个轮廓,向量contours定义为Hierarchy:vectorveC4IHierarchy;向量中的每个元素都表示包含4个int型变量—— hierarchy [ I ] [0]-hierarchy [ I ] [3],分别是第I个轮廓之后的轮廓、前面的轮廓、第一个子轮廓、父轮廓

cv:RETR_EXTERNAL :仅检测最外周轮廓;

cv:RETR_LIST :检测所有轮廓,但不建立等级关系;

cv:RETR_CCOMP :检测所有轮廓,但所有轮廓仅存在两个级别关系,外周处于最高级别

cv:RETR_TREE :检测所有轮廓,在所有轮廓上形成一个分层树结构的方法:轮廓近似方法

CV_CHAIN_APPROX_NONE :从物体边界上的所有连续轮廓点保存到contours向量

CV_CHAIN_APPROX_SIMPLE :只存储轮廓的拐点信息,所有轮廓拐点的点在contours矢量上;点:偏移,缺省为(0,0 )无偏移;代码示例为简单代码

vectorvectorPoint contours; vectorVec4i hierarchy; findcontours(image,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point ) ); 四. drawContours函数详细解函数原型:

draw contours (inputoutputarrayimage,InputArrayOfArrays contours,int contourIdx,const Scalar color,int thickness=1), intl less input array hierarchy=no array (),int maxLevel=INT_MAX,Point offset=Point ) )参数的含义:

image (描绘轮廓的图像; contours :要绘制的轮廓组。 与findContours中输出的contours相同。 contourIdx :指示要绘制第几个轮廓。 如果此参数为负值(通常设置为-1),则绘制所有轮廓。 颜色:指定要绘制的颜色或亮度(灰度图像),如scalar (255,0,255 ) thickness。 直线宽度lineType :指定边框

findContours中输出的hierarchymaxLevel:限制将在图上绘制的轮廓层次深度,为0表示只绘制“第0层”,以此类推offset:偏移量,默认为(0,0)没有偏移 五、代码示例

绘制轮廓部分代码如下:

Mat imageContours = Mat::zeros(image.size(), CV_8UC1);for (int i = 0; i < contours.size(); i++){//绘制轮廓drawContours(imageContours, contours, i, Scalar(255), 1, 8, hierarchy);} 六、详细解释

基本流程如下:
①将输出图像使用cvtColor转换为灰度图像
②使用边缘算法(如Canny)进行边缘提取
③使用findContours寻找轮廓
④使用drawContours绘制轮廓

完整程序如下:

#include<opencv2/opencv.hpp>#include "iostream"using namespace std;using namespace cv;int main(int argc, char *argv[]){Mat imageSource = imread("D:/Desktop/1.png", 0);imshow("Source Image", imageSource);//灰度图像Mat image;GaussianBlur(imageSource, image, Size(3, 3), 0);//高斯滤波Canny(image, image, 100, 250);//canny算子边缘检测vector<vector<Point>> contours;vector<Vec4i> hierarchy;findContours(image, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());Mat imageContours = Mat::zeros(image.size(), CV_8UC1);Mat Contours = Mat::zeros(image.size(), CV_8UC1); //绘制 for (int i = 0; i < contours.size(); i++){//contours[i]代表的是第i个轮廓,contours[i].size()代表的是第i个轮廓上所有的像素点数 for (int j = 0; j < contours[i].size(); j++){//绘制出contours向量内所有的像素点 Point P = Point(contours[i][j].x, contours[i][j].y);Contours.at<uchar>(P) = 255;}输出hierarchy向量内容 cout << "向量hierarchy的第" << i << "个元素内容为:" << endl << hierarchy[i] << endl << endl;//绘制轮廓 drawContours(imageContours, contours, i, Scalar(255), 1, 8, hierarchy);}imshow("Contours Image", imageContours); //轮廓imshow("Point of Contours", Contours); //向量contours内保存的所有轮廓点集 waitKey(0);return 0;}

原图像:

灰度化图像:

边缘轮廓绘制后的图像:

向量contours内保存的所有轮廓点集形成的图像:

6.1 mode修改为RETR_EXTERNAL,method修改为CHAIN_APPROX_NONE

这种参数表示:只检测最外层轮廓。

边缘轮廓绘制后的图像:

可以发现,只有最外层的轮廓被检测到,内层的轮廓被自动忽略。

向量contours内保存的所有轮廓点集形成的图像:

可以发现,点集保存了所有轮廓上的所有点,图像表现跟轮廓一致。

hierarchy向量输出内容为:

hierarchy向量中每个元素的四个整型分别表示当前轮廓的后一个轮廓,前一个轮廓,第一条子轮廓和父轮廓的索引编号。

本次参数配置下,hierarchy向量内有4个元素,分别对应于4个轮廓。以第2个轮廓(对应向量内第1个元素)为例,内容为[2,0,-1,-1], “2”表示当前轮廓的后一个轮廓的编号为2,“0”表示当前轮廓的前一个轮廓编号为0,其后2个“-1”表示为空,因为只有最外层轮廓这一个等级,所以不存在父轮廓和内嵌轮廓。

6.2 mode取值为RETR_LIST, method取值为CHAIN_APPROX_SIMPLE;

这类参数表示:检测所有轮廓,但各轮廓之间彼此独立。

边缘轮廓绘制后的图像:

可以发现,内外层轮廓都被绘制。

向量contours内保存的所有轮廓点集形成的图像:

可以发现,点集中直线段部分都被省略掉了,其他部分得到了保留。

6.3 mode修改为RETR_TREE,method修改为CHAIN_APPROX_NONE

这类参数表示:检测所有轮廓,并且轮廓间建立外层、内层的等级关系,并且保存轮廓上所有点。

边缘轮廓绘制后的图像:

可以发现,所有内外层轮廓都被绘制。

向量contours内保存的所有轮廓点集形成的图像:

contours点集组成的图形跟轮廓表现一致。

hierarchy向量输出内容为:

可以观察到,每个轮廓都被划分等级,最外围、第一内围、第二内围等等,所以除第1个最后一个轮廓外,其他轮廓都具有不为-1的第3、第4个整形参数。

如果对你有所帮助,记得点个赞哟~

参考:
1.《学习OpenCV3》
2.OpenCV中的findContours函数参数详解

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