Python 通过等高线时出错:元组索引超出范围

Python Error while going through a contour : tuple index out of range

我正在尝试编写一段代码来检查轮廓(使用 cv2.FindContour 获得)是否触及图像的边界。轮廓是一个元组对象。

到目前为止,我的代码如下所示:

for a in range(len(contours)):
     contoursNew = []
     if not np.any(contours[a][:,0,:]) == 0 \
        or not np.any(contours[a][:,0,0]) == (np.size(self.imageDeBase, 1)-1) \
        or not np.any(contours[a][:,0,0]) == (np.size(self.imageDeBase, 0)-1) :
          contoursNew.append(contours[a])
                    
     contours = tuple(contoursNew)

这应该比较轮廓每个点的坐标 (x;y) 以查看它们中的任何一个是否在图像的边界之一上。如果 none 在边界上,那么我们将轮廓保存在 contourNew 中,这是一个列表,循环完成后,我们将其设为元组。

但是,此代码不起作用:这是终端将出现的错误 return:

    if np.any(contours[a][:,0,:]) == 0 \

IndexError: tuple index out of range

我尝试打印轮廓[a] 看看效果如何,但我遇到了同样的错误,意思是不起作用的部分是 contours[a]。可能我没有正确操作元组,但我不知道该怎么做。

有人可以帮我吗?谢谢!!

编辑:关于 cv2.findContour() 文档是这么说的: 这个方法return有两个值。轮廓和层次结构。 contours 是图像中所有轮廓的 Python 列表。每个单独的轮廓都是对象边界点的 (x,y) 坐标的 Numpy 数组。

试试这个

    for contour in contours:
         contoursNew = []
         if not np.any(contour[:,0,:]) == 0 \
            or not np.any(contour[:,0,0]) == (np.size(self.imageDeBase, 1)-1) \
            or not np.any(contour[:,0,0]) == (np.size(self.imageDeBase, 0)-1) :
              contoursNew.append(contour)
                        
         contours = tuple(contoursNew)

我不确定你的比较,np.any() returns 一个布尔值,但你将它与 int 和元组进行比较。也许应该是这样的?

 if not np.any(contour[:,0,:] == 0) \
            or not np.any(contour[:,0,0] == (np.size(self.imageDeBase, 1)-1)) \
            or not np.any(contour[:,0,0] == (np.size(self.imageDeBase, 0)-1)) :

我用 3 个轮廓创建了下图,以说明如何绘制边界上 的那些:

# Reading the image, obtaining binary image and finding contours:
img = cv2.imread(r'C:\Users4316\Desktop\Stack\c1.png')
img2 = img.copy()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
th = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
contours, hierarchy = cv2.findContours(th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

每个轮廓的形状都是(number_of_points, 1, 2)。在下文中,我首先将每个轮廓数组重塑为 (number_of_points, 2) 使其更易于理解。每个重塑轮廓都存储在 c_modified 中。接下来,我使用 np.any() 检查每个轮廓的至少一个点是否存在于图像的任一边界上。如果不是,画出来:

for i, c in enumerate(contours):
    c_modified = c.reshape(len(contours[i]), 2)
    if not((np.any(c_modified[:,0] == img.shape[0] - 1)) |    # is any point in contour present on left boundary of image
           (np.any(c_modified[:,1] == img.shape[0] - 1)) |    # is any point in contour present on top boundary of image
           (np.any(c_modified[:,0] == img.shape[1] - 1)) |    # is any point in contour present on right boundary of image
           (np.any(c_modified[:,1] == img.shape[1] - 1))):    # is any point in contour present on bottom boundary of image
        
        img2 = cv2.drawContours(img2, [c], -1, (0, 255, 255), 2)