OpenCV 查找轮廓
本教程将讨论使用 Python 中 OpenCV 的 findContours()
函数查找图像中存在的轮廓。
在 Python 中使用 OpenCV 的 findContours()
函数查找图像中的轮廓
轮廓是通过将点与对象的边界连接起来形成的曲线。在图像中,存在多个对象,并且找到图像的轮廓,我们可以获得有关对象形状的信息,因为轮廓会突出图像中存在的对象的边界。
如果我们知道物体的形状,我们可以很容易地猜出图像中存在哪些物体。轮廓广泛用于分析形状以及检测和识别物体。
我们可以使用 OpenCV 的 findContours()
函数来查找图像中存在的轮廓。我们必须使用二值图像来找到轮廓以获得更好的精度。
如果给定的图像不是二进制的,我们可以将其转换为二进制。例如,在彩色图像的情况下,我们必须使用 OpenCV 的 cvtColor()
函数将图像转换为灰度。
我们可以使用 OpenCV 的 threshold() 函数中的灰度图像来找到二值图像。之后,我们可以使用 findContours()
函数和二值图像来查找轮廓。
如果我们想显示轮廓,我们必须创建一个绘图并使用 drawContours()
函数绘制轮廓。绘图应与给定图像大小相同,以更好地可视化轮廓。
我们可以使用 numpy
库的 zeros() 函数创建与给定图像相同大小的黑色绘图。
例如,让我们使用 imread()
函数读取图像,将其转换为二进制比例,然后找到轮廓并显示它们。请参阅下面的代码。
import cv2
import numpy as np
image = cv2.imread("cat.jpg")
cv2.imshow("Original Image", image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Gray Image", gray)
_, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
cv2.imshow("Binary image", binary)
contours, hierarchy = cv2.findContours(
binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
drawing = np.zeros((gray.shape[0], gray.shape[1], 3), dtype=np.uint8)
CountersImg = cv2.drawContours(drawing, contours, -1, (255, 255, 0), 3)
cv2.imshow("Contours", CountersImg)
cv2.waitKey(0)
输出:
findContours()
函数返回两个输出参数。第一个输出参数包含轮廓的位置点和列表中的坐标。第二个输出参数包含轮廓的层次结构。
findContours()
函数的第一个输入是二进制或灰度图像。第二个输入参数是用于定义轮廓层次结构的检索模式。
我们可以在检索模式中传递不同的值,例如 cv2.RETR_LIST
检索所有轮廓,cv2.RETR_EXTERNAL
仅检索外部计数器,cv2.RETR_COMP
检索 2 级层次结构中的轮廓,以及 cv2.RETR_TREE
检索完整层次结构中的轮廓。findContours()
函数的第三个输入参数是用于存储边界点的近似方法。
cv2.CHAIN_APPROX_NONE
方法存储所有边界点,但有时我们不需要所有边界点。我们可以使用 cv2.CHAIN_APPROX_SIMPLE
方法来存储起点和终点轮廓。
我们还可以定义一个偏移量,它将根据 findContours()
函数中的偏移量移动每个轮廓。我们还可以使用 OpenCV 的 drawContours()
函数在给定图像上显示轮廓。
drawContours()
函数的第一个参数是我们要绘制轮廓的图像。第二个参数是轮廓,第三个是轮廓索引。
第三个参数是轮廓的颜色,可以定义为 RGB 三元组。第四个参数是轮廓的厚度,可以定义为整数。
例如,让我们在给定图像的顶部显示轮廓。请参阅下面的代码。
import cv2
import numpy as np
image = cv2.imread("cat.jpg")
cv2.imshow("Original Image", image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Gray Image", gray)
_, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
cv2.imshow("Binary image", binary)
contours, hierarchy = cv2.findContours(
binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
drawing = np.zeros((gray.shape[0], gray.shape[1], 3), dtype=np.uint8)
CountersImg = cv2.drawContours(drawing, contours, -1, (255, 255, 0), 3)
cv2.imshow("Contours", CountersImg)
ImgWithCounter = cv2.drawContours(image, contours, -1, (255, 255, 0), 3)
cv2.imshow("Image with counters", ImgWithCounter)
cv2.waitKey(0)
输出: