OpenCV 查找轮廓

Ammar Ali 2024年2月15日
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)

输出:

使用 opencv 查找轮廓

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)

输出:

图像顶部的轮廓

作者: Ammar Ali
Ammar Ali avatar Ammar Ali avatar

Hello! I am Ammar Ali, a programmer here to learn from experience, people, and docs, and create interesting and useful programming content. I mostly create content about Python, Matlab, and Microcontrollers like Arduino and PIC.

LinkedIn Facebook

相关文章 - Python OpenCV