4.1. 轮廓:入门¶
4.1.1. 目标¶
了解轮廓是什么。
学会找轮廓,画轮廓等
您将看到这些功能: cv2.查找目录() , 绘制轮廓()
4.1.2. 什么是轮廓?¶
等高线可以简单地解释为连接所有连续点(沿边界)的曲线,具有相同的颜色或强度。轮廓线是形状分析、目标检测和识别的有用工具。
为了获得更好的精度,请使用二进制图像。因此,在寻找轮廓之前,应用阈值或canny边缘检测。
findConteurs函数修改源图像。所以,如果你想得到源图像,即使在找到轮廓后,也要将其存储到其他变量中。
在OpenCV中,寻找轮廓就像从黑色背景中寻找白色物体。所以记住,要找到的物体应该是白色的,背景应该是黑色的。
让我们看看如何找到二值图像的轮廓:
>>> %matplotlib inline
>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> import cv2
>>>
>>> # im = cv2.imread('test.jpg')
>>> im = cv2.imread('/cvdata/messi5.jpg')
>>> imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
>>> ret,thresh = cv2.threshold(imgray,127,255,0)
>>> image, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
看,有三个论点 cv2.查找目录() 函数,一是源图像,二是轮廓检索模式,三是轮廓逼近方法。输出图像、轮廓和层次结构。 contours
是图像中所有轮廓的Python列表。每一个单独的轮廓是物体边界点(x,y)坐标的Numpy数组。
注意
稍后我们将详细讨论第二和第三个参数以及关于层次结构的问题。在此之前,在代码示例中给它们的值对于所有图像都可以正常工作。
4.1.3. 如何绘制轮廓?¶
为了画出轮廓, cv2.drawContours
使用函数。它也可以用来绘制任何形状,只要你有它的边界点。它的第一个参数是源图像,第二个参数是应该作为Python列表传递的轮廓,第三个参数是轮廓索引(在绘制单个轮廓时很有用)。要绘制所有轮廓,pass-1)和其余参数是颜色、厚度等。
要绘制图像中的所有轮廓:
>>> img = cv2.drawContours(im, contours, -1, (0,255,0), 3)
>>> plt.imshow(img)
<matplotlib.image.AxesImage at 0x7f2d3da30b70>

要绘制单个轮廓,请说第四个轮廓:
>>> img = cv2.drawContours(im, contours, 3, (0,255,0), 3)
>>> plt.imshow(img)
<matplotlib.image.AxesImage at 0x7f2d3c0c1470>

但在大多数情况下,以下方法将是有用的:
>>> cnt = contours[4]
>>> img = cv2.drawContours(im, [cnt], 0, (0,255,0), 3)
>>> plt.imshow(img)
<matplotlib.image.AxesImage at 0x7f2d3c09c860>

注意
最后两种方法是相同的,但当您继续前进时,您将看到最后一种方法更有用。
4.1.4. 轮廓近似法¶
这是第三个论点 cv2.findContours
功能。它实际上意味着什么?
上面,我们说等高线是具有相同强度的形状的边界。它存储形状边界的(x,y)坐标。但它能存储所有的坐标吗?由该轮廓近似方法指定的。
如果你通过 cv2.CHAIN_APPROX_NONE
,存储所有边界点。但实际上我们需要所有的要点吗?例如,你发现了一条直线的轮廓。你需要这条线上的所有点来表示那条线吗?不,我们只需要那条线的两个端点。这就是 cv2.CHAIN_APPROX_SIMPLE
做。它删除所有冗余点并压缩轮廓,从而节省内存。
下面的矩形图片演示了这种技术。只需在轮廓数组中的所有坐标上画一个圆(用蓝色绘制)。第一张图片显示了我得到的分数 cv2.CHAIN_APPROX_NONE
(734点)第二张图片显示 cv2.CHAIN_APPROX_SIMPLE
(只有4分)。看,它节省了多少内存!!!