OpenCV 形状检测
本教程将讨论使用 OpenCV 的 findContours()
和 approxPolyDP()
函数检测图像中存在的形状。
使用 OpenCV 的 findContours()
和 approxPolyDP()
函数来检测图像中存在的形状
我们可以使用 OpenCV 的 findContours()
和 approxPolyDP()
函数找到图像中存在的形状。我们可以根据它的角数来检测形状。
例如,三角形有 3 个角,正方形有 4 个角,五边形有 5 个角。
要找到一个形状的角数,我们必须首先使用 findContours()
函数找到给定图像的轮廓,然后使用 approxPolyDP()
函数找到一个形状的角或边数。
我们可以使用 OpenCV 的 findContours()
函数找到给定图像的轮廓,但我们必须在 findContours()
函数中使用二进制或黑白图像。
要将给定的图像转换为二进制,我们必须使用 OpenCV 的 cvtColor()
和 threshold()
函数。
cvtColor()
函数将一种颜色空间转换为另一种颜色空间,我们将使用它来将 BGR 图像转换为灰度。threshold()
函数将灰度图像转换为只有两个值的二进制,0 和 255。
我们必须找到 approxPolyDP()
函数的输出长度以获取图像的角数,并使用 if-else
语句打印形状名称和角数。
我们还可以使用 drawContours()
函数为每个形状添加不同的颜色。
例如,让我们检测 BGR 图像中存在的形状。请参阅下面的代码。
import cv2
import numpy as np
img = cv2.imread("shapes.png")
original = img.copy()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
ROI_number = 0
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for cnt in cnts:
approx = cv2.approxPolyDP(cnt, 0.01 * cv2.arcLength(cnt, True), True)
print(len(approx))
if len(approx) == 5:
print("Blue = pentagon")
cv2.drawContours(img, [cnt], 0, 255, -1)
elif len(approx) == 3:
print("Green = triangle")
cv2.drawContours(img, [cnt], 0, (0, 255, 0), -1)
elif len(approx) == 4:
print("Red = square")
cv2.drawContours(img, [cnt], 0, (0, 0, 255), -1)
elif len(approx) == 6:
print("Cyan = Hexa")
cv2.drawContours(img, [cnt], 0, (255, 255, 0), -1)
elif len(approx) == 8:
print("White = Octa")
cv2.drawContours(img, [cnt], 0, (255, 255, 255), -1)
elif len(approx) > 12:
print("Yellow = circle")
cv2.drawContours(img, [cnt], 0, (0, 255, 255), -1)
cv2.imshow("image", img)
cv2.imshow("Binary", thresh)
cv2.waitKey()
输出:
5
Blue = pentagon
6
Cyan = Hexa
8
White = Octa
3
Green = triangle
4
Red = square
14
Yellow = circle
二进制图像中的形状应为白色,背景应为黑色。如你所见,输出图像中形状的颜色与原始图像中形状的颜色不同。
OpenCV 的 findContours()
和 approxPolyDP()
函数的参数
findContours()
函数的第一个参数是二值图像,第二个参数是轮廓检索方法。
我们使用 cv2.RETR_EXTERNAL
,因为我们只需要外部轮廓。第三个参数是用于查找轮廓的近似方法。
approxPolyDP()
函数的第一个参数是图像的轮廓。第二个是指定逼近精度的参数,第三个用来指定逼近曲线是否闭合。
approxPolyDP()
函数使用 Douglas Peucker 算法将轮廓形状近似为另一个形状。drawContours()
函数用于绘制轮廓。
drawContours()
函数的第一个参数是我们要绘制颜色的图像。第二个参数是轮廓,第三个参数是轮廓的颜色。
第四个参数是线条粗细,如果它的值为负数,颜色将填充形状。