在您提供的代码中,cv2.findContours
函数返回了两个值:contours
和 hierarchy
。contours
是一个轮廓列表,每个轮廓由多个点组成,而 hierarchy
包含了轮廓之间的层级关系。在某些情况下,一个完整的形状(如五角星)可能会被检测为多个轮廓片段。
为了给整个五角星绘制一个矩形框,我们需要重新考虑如何确定这个矩形框。由于 contours[0]
只包含了五角星的一部分,您不能简单地选择 contours
列表中的一个轮廓来包围整个五角星。
以下是一些可能的解决方案:
使用
cv2.boundingRect
包围所有轮廓点:您可以迭代所有的轮廓,并使用cv2.boundingRect
来获取每个轮廓的边界矩形,然后找到包围所有这些矩形的最小矩形。使用
cv2.minAreaRect
或cv2.minEnclosingCircle
:这些函数可以返回一个最小的形状(矩形或圆),它可以包围所有的轮廓点。自定义方法:您可以自定义一个算法来确定五角星的外接矩形。例如,记录所有轮廓点的最小和最大 x 和 y 坐标,然后使用这些坐标来绘制矩形框。
以下是使用第一种方法绘制包围整个五角星的最小矩形框的示例代码:
import cv2
import numpy as np
img = cv2.imread("star.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 寻找所有轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# 初始化最小和最大坐标
min_x, min_y = np.inf, np.inf
max_x, max_y = 0, 0
# 迭代所有轮廓,更新坐标
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
min_x = min(min_x, x)
min_y = min(min_y, y)
max_x = max(max_x, x + w)
max_y = max(max_y, y + h)
# 使用找到的坐标绘制矩形框
cv2.rectangle(img, (min_x, min_y), (max_x, max_y), (0, 0, 255), 2)
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
请注意,这种方法可能不总是完美的,特别是如果轮廓之间有较大的间隙,计算出的最小矩形可能会比实际五角星的边界大。在实践中,可能需要根据具体情况调整算法。