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

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

在使用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

在二值图像中查找轮廓

参数

说明

可选值

image

输入的源图像

contours

(out)查找到的所有的轮廓的集合

hierarchy

(out)维护了每个轮廓的拓扑结构(层级关系),和contours同型

mode

轮廓检索模式

RETR_EXTERNALRETR_LISTRETR_CCOMPRETR_TREERETR_FLOODFILL

method

轮廓近似方法

CHAIN_APPROX_NONECHAIN_APPROX_SIMPLECHAIN_APPROX_TC89_L1CHAIN_APPROX_TC89_KCOS

offest

每个轮廓点移动的偏移量

Examples:

vector > contours;

vector 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

绘制轮廓线或者填充轮廓

参数

说明

取值

image

输入的源图像

contours

保存了所有轮廓的集合

contourIdx

待绘制的轮廓序号

color

绘制的轮廓线的颜色

thickness

轮廓线的粗细

负值时绘制内轮廓

lineType

轮廓线线型

FILLEDLINE_4LINE_8LINE_AA

hierarchy

维护了所有轮廓的拓扑结构

maxLevel

最大嵌套层级

offset

轮廓线的偏移量

Examples:

vector > contours;

vector 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:左图为筛选前,右图为筛选后

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);

}

}

参考文献

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

OpenCV官方文档

杂项

如何阅读OpenCV官方文档

markdown更改颜色和字体

markdown设置图片大小

资源分享

opencv官方文档网盘下载

相关推荐

激活日期比购买日期早2天
365bet提款限制

激活日期比购买日期早2天

09-14 阅读 3758
碳纤维自行车与铝合金自行车的对比分析
365bet盘口官网

碳纤维自行车与铝合金自行车的对比分析

10-30 阅读 9716