目标
理解什么是轮廓。
学习寻找轮廓,绘制轮廓等等
您将看到这些函数:cv.findContours(), cv.drawContours()
轮廓是什么?
轮廓可以简单地解释为一条连接所有连续点(沿边界)的曲线,具有相同的颜色或强度。轮廓是形状分析和对象检测和识别的有用工具。
为了更好的准确性,使用二进制图像。因此,在找到轮廓之前,应用阈值或精明的边缘检测。
自从opencv3.2以来,findContours()不再修改源图像,而是返回一个修改后的图像作为三个返回参数中的第一个。
在OpenCV中,寻找轮廓就像从黑色背景中寻找白色物体。记住,要找到的对象应该是白色的,背景应该是黑色的。
让我们来看看如何找到一个二进制图像的轮廓:
import cv2 as cv
import numpy as np
im = cv.imread('crzg.jpg')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
cv.imshow('image',im2)
cv.waitKey(0)
cv.destoryAllWindows()
看,在cv.find等高线()函数中有三个参数,第一个是源图像,第二个是等值线检索模式,第三个是等值线近似法。它输出一个修改过的图像,轮廓和层次结构。等高线是图像中所有轮廓的Python列表。每个单独的轮廓是物体边界点(x,y)坐标的一个数字数组。
请注意
稍后我们将讨论第二和第三个参数以及关于层次结构的讨论。在此之前,在代码样本中给它们的值将对所有图像都适用。
如何画出轮廓?
画出轮廓,cv.drawContours 函数使用。如果你有它的边界点,它也可以用来画任何形状。它的第一个参数是源图像,第二个参数是应该作为Python列表传递的轮廓,第三个参数是轮廓的索引(在绘制单个轮廓时很有用。画出所有的轮廓,通过-1)剩下的参数是颜色,厚度等。
import numpy as np
import cv2 as cv
im = cv.imread('bk.jpg')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv.findContours(
thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
cv.drawContours(imgray, contours, -1, (0,0,0), 2)
cv.imshow("img", imgray)
cv.waitKey(0)
cv.drawContours(img, contours, 3, (0,255,0), 3)#要画出一个轮廓,比如第4个轮廓:
cv.drawContours(img, contours, -1, (0,255,0), 3)#把所有的轮廓画在一张图片上:
cnt = contours[4]
cv.drawContours(img, [cnt], 0, (0,255,0), 3)#但在大多数情况下
最后两种方法是相同的,但是当你向前走的时候,你会发现最后一个方法更有用。
轮廓近似法
这是简历中的第三个论点 cv.findContours s函数。它表示的是什么?
在上面,我们告诉我们,轮廓是一个具有相同强度的形状的边界。它存储一个形状边界的(x,y)坐标。但是它会储存所有的坐标吗?这是由这个轮廓近似法指定的。
如果你通过 cv.CHAIN_APPROX_NONE,所有的边界点都被存储。但实际上我们需要所有的点吗?例如,你发现了一条直线的轮廓。你是否需要直线上的所有点来表示这条直线?不,我们只需要这条线的两个端点。这是简历。cv.CHAIN_APPROX_SIMPLE 。它删除所有的冗余点并压缩轮廓,从而节省内存。
下面是一个矩形的图像,演示了这种技术。在等高线阵列的所有坐标上画一个圈(用蓝色画)。第一张图片显示了我的 cv.CHAIN_APPROX_NONE(734分)和第二张图片显示的是带有cv的。CHAIN_APPROX_SIMPLE(只有4分)。看,它节省了多少内存!!