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)
我正在尝试编写一段代码来检查轮廓(使用 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)