从列表中检索轮廓时,轮廓显示点而不是曲线,但否则显示曲线

1 python opencv

我正在找到阈值图像的轮廓并像这样绘制它:

self.disc_contour = cv2.findContours(self.thresh.copy(), cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE)[1] 
cv2.drawContours(self.original_image, self.disc_contour, -1, (0,255,0), 2)
Run Code Online (Sandbox Code Playgroud)

我得到了所需的轮廓:

(忽略内圆。外部是上下文中的轮廓)

在此输入图像描述

但是如果我将self.disc_contourdrawContour函数更改为self.disc_contour[0]我会得到以下结果:

在此输入图像描述

可能是什么原因?

Dan*_*šek 5

注意:特定于 OpenCV 3.x

第二个结果cv2.findContours是轮廓列表。的第二个参数cv.drawContours应该是轮廓列表。

轮廓表示为点列表(或数组)。每个点都是一个坐标列表。

有多种方法可以仅绘制单个轮廓:

import cv2

src_img = cv2.imread("blob.png")
gray_img = cv2.cvtColor(src_img, cv2.COLOR_BGR2GRAY)

contours = cv2.findContours(gray_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)[1]

print(contours)

# Choose one:    

# Draw only first contour from the list
cv2.drawContours(src_img, contours, 0, (0,255,0), 2)
# Pass only the first contour (v1)
cv2.drawContours(src_img, [contours[0]], -1, (0,255,0), 2)
# Pass only the first contour (v2)
cv2.drawContours(src_img, contours[0:1], -1, (0,255,0), 2)


cv2.imshow("Contour", src_img)
cv2.waitKey()
Run Code Online (Sandbox Code Playgroud)

输入图像示例:

当我们检查 的结果时cv2.findContours,您看到点的原因就变得很明显了——有 4 层嵌套。

[
    array([
        [[ 95,  61]], # Point 0
        [[ 94,  62]], # Point 1
        [[ 93,  62]],
        ... <snip> ...
        [[ 98,  61]],
        [[ 97,  61]],
        [[ 96,  61]]
    ]) # Contour 0
]
Run Code Online (Sandbox Code Playgroud)

根据这个答案开头的定义,我们可以看到这种情况下的点被包装在一个附加列表中,例如[[ 98, 61]]。OpenCV 显然正确地处理了这个问题 - 我想这是一个功能。

如果我们仅使用 的第一个元素来删除外部列表contours,我们可以有效地将每个点转换为包含单个点的单独轮廓。

array([
    [
        [ 95,  61] # Point 0
    ], # Contour 0
    [
        [ 94,  62] # Point 0
    ], # Contour 1
    ... and so on
])
Run Code Online (Sandbox Code Playgroud)