Contours in OpenCV

翻译自 Contour in OpenCV

Contours

Contours 可以简单的理解为一条连通连续点的曲线(沿着边缘),有同样的颜色或者强度。在进行形状分析,目标检测和识别时很有用处。

  • 为了更好了精度,使用二值化的图像。在寻找轮廓之前,先对图像应用二值化阈值或者canny 边缘检测等技术。
  • 在OpenCV中,寻找轮廓是:在黑色背景上寻找白色物体,所以一定记住,被检测的对象应该是白色的,背景是黑色的。

采用cv::findContours()需找图像中的轮廓。

Drawing Contours

采用cv::drawContours()画轮廓。它也能用于画各种形状(用户提供的有边缘的点)。它的第一个参数是原图,第二个参数是轮廓数组,第三个参数是轮廓索引(-1 画所有轮廓)。其他的参数是颜色,线性等。

img = imread('image.jpg')
gray = cv.cvtColor(img, 'RGB2GRAY');
bw = cv.threshold(gray, 'Otsu');
[contours,hierarchy] = cv.findContours(bw, 'Mode','Tree', 'Method','Simple');
img = cv.drawContours(img, contours, 'Hierarchy',hierarchy, 'Color',[0 255 0]);

Contour Approximation Method

这是 cv::findContours()的第三个参数,实际意义是什么呢?
我们之前说过,轮廓是一个有相同强度的形状的边缘。它存放这形状的边缘的点坐标(x,y),但是它存储所有的坐标吗?这是由Contour Approximation Method 指定的。

如果你设置 Method = None,边的所有点都会被存储。但是实际上我们需要所有的点吗?例如:你发现了一条直线的边缘,你需要该线上的所有点以表示该线吗?不,我们只需要二个点而已。这就是Methon = Simple 方法所做的。它移除所有冗余的点,压缩轮廓,以节省内存。

下图是一个长方形的图像来阐释这个原理:
左边的图保持了所有边上的点(Nnoe).右边只保留4个点(Simple).
在这里插入图片描述

% image with a simple rectangular shape
img = zeros(200, 300, 'uint8');
img = cv.rectangle(img, [50 50 200 100], 'Color',255, 'Thickness','Filled');

% find contour w/o approximation
contours = cv.findContours(img, 'Method','None');
cntr1 = cat(1, contours{1}{:});

% find contour w/ approximation
contours = cv.findContours(img, 'Method','Simple');
cntr2 = cat(1, contours{1}{:});

% draw both contours points
out = repmat(img, 1, 1, 3);
out1 = cv.circle(out, cntr1, 3, 'Color',[255 0 0], 'Thickness','Filled');
out2 = cv.circle(out, cntr2, 3, 'Color',[255 0 0], 'Thickness','Filled');

% compare results
subplot(121), imshow(out1)
title({'Method = None', sprintf('%d points', size(cntr1,1))})
subplot(122), imshow(out2)
title({'Method = Simlpe', sprintf('%d points', size(cntr2,1))})

在这里插入图片描述

Contours Hierarchy

正常情况下,我们使用cv::findContours()来检测图像中的目标,是吗?有时,目标在不同的位置,但是在一些场景下,一些目标在其他目标内部。就是嵌套图像一样。在这种情况下,我们称外部的对象是parent,在内部的是child.这种情况下,在一个图像上的轮廓彼此之间有联系。我们可以指定一个轮廓如何联系其他的轮廓。我们把这种关系称为 Hierarchy.

考虑下图:
在这里插入图片描述
在这个图上,有一些形状编号为0-5. 2和2表示外部和内部的轮廓。

Here, contours 0,1,2 are external or outermost. We can say, they are in hierarchy-0 or simply they are in same hierarchy level.

Next comes contour-2a. It can be considered as a child of contour-2 (or in opposite way, contour-2 is parent of contour-2a). So let it be in hierarchy-1. Similarly contour-3 is child of contour-2 and it comes in next hierarchy. Finally contours 4,5 are the children of contour-3a, and they come in the last hierarchy level. From the way the boxes are numbered, we would say contour-4 is the first child of contour-3a (It can be contour-5 also).

OpenCV把hierarchy的对象表示为一个四元数组[Next,Previous,First_Child,Parent].

  • Next 表示同一个级别的下一条轮廓
  • Previous 表示同一个级别的前一条轮廓
  • First_Child 表示下级的第一个子节点
  • Parent 表示父节点
    不存在联系时,设置为-1.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值