问题描述:
在这个cv2.findContours()函数中的2个返回值是什么意思呢?请以2个正方形轮廓进行解释说明,其中正方形A的轮廓在正方形B的轮廓内部?
问题解答:
在使用 cv2.findContours()
函数时,如果有两个正方形轮廓,其中正方形 A 的轮廓在正方形 B 的轮廓内部,返回值 contours
和 hierarchy
的含义可以如下解释:
1. contours
:轮廓列表
contours
是一个包含所有检测到的轮廓的列表。在这种情况下,它将包含两个轮廓的点数组:
-
正方形 A(内轮廓):一个数组,表示正方形 A 四个角的坐标,例如:
contour_A = np.array([[x1, y1], [x2, y2], [x3, y3], [x4, y4]])
-
正方形 B(外轮廓):另一个数组,表示正方形 B 四个角的坐标,例如:
contour_B = np.array([[x5, y5], [x6, y6], [x7, y7], [x8, y8]])
所以,contours
的结构可能是:
contours = [contour_A, contour_B]
2. hierarchy
:轮廓的层次关系
hierarchy
是一个数组,表示轮廓之间的层次关系,格式为 [Next, Previous, First Child, Parent]
。在这种情况下,它描述了正方形 A 和 B 的父子关系:
-
对于 正方形 B(外轮廓):
Next
指向下一个轮廓(如果存在)。Previous
指向前一个轮廓(如果存在)。First Child
指向其第一个子轮廓(如果存在)。Parent
指向其父轮廓(对于外轮廓来说通常为 -1)。
-
对于 正方形 A(内轮廓):
Next
、Previous
、First Child
和Parent
的值表示它是 B 的子轮廓。
假设正方形 B 是外轮廓,正方形 A 是内轮廓,hierarchy
可能会如下表示:
hierarchy = [[-1, -1, 1, -1], # 正方形 B(外轮廓)
[-1, 0, -1, 0]] # 正方形 A(内轮廓)
解释:
-
正方形 B(外轮廓):
Next = -1
:没有下一个轮廓。Previous = -1
:没有前一个轮廓。First Child = 1
:指向正方形 A(它是第一个子轮廓)。Parent = -1
:没有父轮廓。
-
正方形 A(内轮廓):
Next = -1
:没有下一个轮廓。Previous = 0
:前一个轮廓是正方形 B(相对而言)。First Child = -1
:没有子轮廓。Parent = 0
:指向正方形 B(因为 A 是 B 的子轮廓)。
总结
contours
包含两个数组,分别表示正方形 A 和正方形 B 的轮廓点。hierarchy
表示它们之间的层次关系,清楚地指示正方形 A 是正方形 B 的内轮廓,反映了它们的嵌套结构。
#################################################################
怎么确定外轮廓B的序号是0呢?
在 cv2.findContours()
中,轮廓的顺序是由函数根据图像中的轮廓检测顺序决定的。具体来说,轮廓的顺序取决于图像的扫描方式,通常从左上角开始,按行从左到右、从上到下扫描图像中的每个像素。当找到一个轮廓时,它会按顺序被存入 contours
列表。因此,外轮廓和内轮廓的顺序会依据它们在图像中出现的次序。
不过,cv2.RETR_TREE
模式会返回轮廓之间的层次结构,并且 hierarchy
数组提供了轮廓之间的父子关系信息。通过分析 hierarchy
的返回值,你可以确定哪些轮廓是外轮廓,哪些是内轮廓。
如何确定外轮廓 B 的序号:
假设我们检测到两个正方形:正方形 A 是内轮廓,正方形 B 是外轮廓。你可以通过以下步骤确定哪个轮廓是外轮廓:
-
通过
hierarchy
确定父子关系: 在cv2.RETR_TREE
模式下,hierarchy
的每个条目[Next, Previous, First Child, Parent]
包含了与当前轮廓相关的信息。- 外轮廓通常没有父轮廓,因此其
Parent
值通常为-1
。 - 内轮廓通常有一个父轮廓,其
Parent
值为外轮廓的索引。
- 外轮廓通常没有父轮廓,因此其
-
查看
Parent
值:- 如果某个轮廓的
Parent
值为-1
,则可以确定它是外轮廓。 - 如果某个轮廓的
Parent
值为非-1
(比如0
),则它是某个外轮廓的子轮廓(即内轮廓)。
- 如果某个轮廓的
例子:
假设 hierarchy
的结果如下:
hierarchy = [[-1, -1, 1, -1], # 第一个轮廓(可能是正方形 B)
[-1, 0, -1, 0]] # 第二个轮廓(可能是正方形 A)
解释:
-
hierarchy[0]
(第一个轮廓):[-1, -1, 1, -1]
Next = -1
:没有下一个轮廓。Previous = -1
:没有前一个轮廓。First Child = 1
:有一个子轮廓,其索引为 1(即第二个轮廓,正方形 A)。Parent = -1
:没有父轮廓(它是外轮廓,正方形 B)。
-
hierarchy[1]
(第二个轮廓):[-1, 0, -1, 0]
Next = -1
:没有下一个轮廓。Previous = 0
:前一个轮廓是索引 0(即正方形 B)。First Child = -1
:没有子轮廓。Parent = 0
:它的父轮廓是索引 0(即正方形 B)。
从 hierarchy
中可以看出,索引为 0 的轮廓(正方形 B)是外轮廓,而索引为 1 的轮廓(正方形 A)是内轮廓,因为它有一个父轮廓,父轮廓的索引是 0。
总结:
- 通过
hierarchy
中的Parent
值为-1
,你可以确定哪个轮廓是外轮廓。在这个例子中,hierarchy[0]
对应的轮廓是外轮廓 B,因此其序号是 0。 - 内轮廓的
Parent
值会指向外轮廓的索引,因此通过hierarchy
可以轻松识别外轮廓和内轮廓。