首页 > 其他分享 >opencv筛选轮廓的几种方法总结

opencv筛选轮廓的几种方法总结

时间:2022-11-08 14:02:18浏览次数:75  
标签:idx hierarchy image opencv contours 筛选 轮廓

在使用opencv处理图像的时候,在获取ROI区域这一步用的最多的就是找到指定区域,一般是根据轮廓提取,我们可以通过opencv中的findContours()函数来查找图片中的轮廓,但是会发现找到的轮廓相当之多,如何在这些轮廓中准确定位道自己需要的轮廓呢?下面介绍几种方法:

前导知识

1. 查找轮廓

findContours() ps:点击函数名可以直接跳转到官方文档哦!

void cv::findContours(InputOutputArray 	    image,
                      OutputArrayOfArrays   contours,
                      OutputArray 	    hierarchy,
                      int 	            mode,
                      int 	            method,
                      Point 	            offset = Point() 
)	
	
Python:
  cv.findContours(image, mode, method[, contours[, hierarchy[, offset]]])->image, contours, hierarchy

#include <opencv2/imgproc.hpp>

 在二值图像中查找轮廓

参数 说明
image 输入的源图像
contours 查找到的所有的轮廓的集合
hierarchy 维护了每个轮廓的拓扑结构(层级关系),和contours同型
mode 轮廓检索模式
method 轮廓近似方法
offest 每个轮廓点移动的偏移量

Examples:

vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

cv::findContours( img, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);

2. 绘制轮廓

drawContours()ps:点击函数名可以直接跳转到官方文档哦!

void cv::drawContours	( InputOutputArray 	image,
                          InputArrayOfArrays 	contours,
                          int 	                contourIdx,
                          const Scalar & 	color,
                          int 	                thickness = 1,
                          int 	                lineType = LINE_8,
                          InputArray 	        hierarchy = noArray(),
                          int 	                maxLevel = INT_MAX,
                          Point 	        offset = Point() 
)		
Python:
  cv.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]])->image

#include <opencv2/imgproc.hpp>

 绘制轮廓线或者填充轮廓

参数 说明
image 输入的源图像
contours 保存了所有轮廓的集合
contourIdx 待绘制的轮廓序号
color 绘制的轮廓线的颜色
thickness 轮廓线的粗细
lineType 轮廓线线型
hierarchy 维护了所有轮廓的拓扑结构
maxLevel 最大嵌套层级
offset 轮廓线的偏移量

Examples:

vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(imgDilate, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE );

for (int idx = 0; idx < contours.size(); idx++)
{
    Scalar color(rand() & 255, rand() & 255, rand() & 255);
    drawContours(img, contours, idx, color, 2, LINE_8, hierarchy, 3);
}
imshow("img",img);

正文

1. 根据面积筛选

使用contourArea()可以计算得到一个轮廓的面积(这里的面积的单位应该是平方像素),然后和最小面积比较,得到筛选后的轮廓。

ps:上图为findContours函数查找到的所有的轮廓,下图为根据面积筛选得到area>10000的所有轮廓

Examples:

// 计算轮廓面积
double area = contourArea(contours[idx]);
// 预设最小轮廓面积为1000,<=1000的轮廓被筛除,>1000的轮廓被放入finalContours中以返回
if(area > minArea){
    finalContours.push_back(contours[idx]);
}

2. 根据拐点个数筛选多边形轮廓

如果要在一堆多边形轮廓中筛选出四边形轮廓,则可以首先根据拐点的个数进行筛选,使用approxPolyDP()获取轮廓拐点。

ps:上图为经过预处理的二值图像,下图为根据拐点数量筛选出的所有拐点为4的轮廓

Examples:

// 获取轮廓拐点,拐点坐标保存在approx中,精度为轮廓周长的0.02倍
approxPolyDP(contours[idx],approx,0.02*arcLength(contours[idx],true), true);
// 预设要筛选的拐点数目approxNum=4
if (approx.size() == approxNum) {
    finalContours.push_back(contours[idx]);
}

3. 根据嵌套层级筛选

以上面的二值图像为例,如果当通过拐点、面积筛选的方法筛选之后,发现白线的内侧和外侧轮廓都被画了出来,如果只要外轮廓,则可以根据hierarchy来进行筛选。

ps:图为筛选出的拐点为4的外层轮廓
approxPolyDP(contours[idx], approx, 0.02 * arcLength(contours[idx], true), true);
// 根据拐点数量筛选
if (approx.size() == approxNum) {
    // 筛除具有父轮廓的轮廓
    if (hierarchy[idx][3] < 0) {
        dstContours.push_back(contours[idx]);
        dstApproxs.push_back(approx);
    }
}

参考文献

  1. OpenCV—轮廓操作一站式详解:查找/筛选/绘制/形状描述与重心标注(Python版)
  2. OpenCV官方文档

杂项

  1. 如何阅读OpenCV官方文档
  2. markdown更改颜色和字体
  3. markdown设置图片大小

资源分享

  1. opencv官方文档网盘下载

标签:idx,hierarchy,image,opencv,contours,筛选,轮廓
From: https://www.cnblogs.com/fau152/p/16868637.html

相关文章

  • opencv-环境配置
     一、windows平台(版本:opencv-4.5.5-vc14_vc15):1)设置电脑环境变量:步骤:高级系统设置-》高级-》环境变量-》path-》D:\study\opencv\opencv\build\x64......
  • 11 Sonic - 调试 opencv
    sonic项目本身支持opencv图像识别库,但我在mac上调试却一直报错,最后在mac上也没有成功。没办法只能在windows上调试opencv代码了。一、mac上报错信息在mac上一......
  • build opencv with qt to make debugging easier
    最近发现使用自己编译的opencv,可以增强opencv的imshow函数功能。从哪里得到的线索已经忘记了。可能是无意中发现的某一张截图吧。要实现cv::imshow函数功能增强,需要在cmak......
  • python opencv 获取图像的区域
    pythonopencv提取图像的区域 start_x=index_box[0]start_y=index_box[1]end_x=index_box[2]end_y=index_box[3]index_person_img=camera1_img[start_y......
  • 解决OpenCV 4描述符匹配器(cv::DescriptorMatcher)create函数的参数类型问题
    1.在OpenCV4.6.0中函数签名如下:static Ptr<DescriptorMatcher>cv::DescriptorMatcher::create(const String & descriptorMatcherType)static Ptr<DescriptorMatc......
  • 8,批量处理单元格判断数据,分数筛选
    #批量处理单元格判断数据,分数筛选function分数筛选(){ varArr1=[]; varArr2=Range("a2:b13").Value(); for(vararofArr2){ if(ar[1]>=100){ Arr1.push(a......
  • OpenCV图像处理与视频分析详解
    1、OpenCV4环境搭建VS2017新建一个控制台项目配置包含目录配置库目录配置链接器配置环境变量重新启动VS20172、第一个图像显示程序main.cpp#i......
  • 筛选出带字母和数据
     问题:一列数据中,一部分内容是数字,另一部分内容是数字和字母混合,要筛选出其中之一解决:添加辅助列,使用以下公式=ISNUMBER(-CLEAN(A2))再根据辅助列筛选 思路:A......
  • opencv遇到std::bad_alloc异常
    配置opencv环境时遇到的,首先注意解决方案平台是x64而不是x86,然后属性管理器->Debug|64右键属性->链接器->输入->附加依赖项中,把opencv_world460.lib(不同版本数字不同,位......
  • OpenCV 实现BGR转RGB
    一、问题当使用opencv函数imread()读取图片时,颜色的顺序是BGR(blue、green、red),而Pillow的颜色顺序又是RGB,因此我们可能需要将BGR转RGB。二、转换可以通过以下几种方法......