我试图删除除最大轮廓之外的所有轮廓,同时将子轮廓保留在最大轮廓内。实际上我想从这里开始:Input Image至:Output Image不过,我不知道该怎么做(我无论如何都不是程序员,并且在整理以下内容时得到了帮助)。我拥有的代码不保留子轮廓。 Output of Below.
import cv2 as cv
import numpy as np
img = cv.imread('small_contour.jpg')
image_contours = np.zeros((img.shape[1], img.shape[0], 1), np.uint8)
image_binary = np.zeros((img.shape[1], img.shape[0], 1), np.uint8)
for channel in range(img.shape[2]):
ret, image_thresh = cv.threshold(img[:, :, channel], 127, 255, cv.THRESH_BINARY)
contours = cv.findContours(image_thresh, 1, 1)[0]
cv.drawContours(image_contours, contours, -1, (255,255,255), 3)
contours = cv.findContours(image_contours, cv.RETR_LIST,
cv.CHAIN_APPROX_SIMPLE)[0]
cv.drawContours(image_binary, [max(contours, key = cv.contourArea)],
-1, (255, 255, 255), -1)
cv.imwrite('fill_contour.jpg', image_binary)
cv.imshow('Small Contour', image_binary)
cv.waitKey(0)
最佳答案
您的代码在此行中的作用 cv.drawContours(image_binary, [max(contours, key = cv.contourArea)], -1, (255, 255, 255), -1)
是设置颜色(255, 255, 255)
image_binary
的像素对应于 cv.findContours
找到的较大轮廓的边界和内部像素.
创建 image_binary
你也在用高度交换宽度,这是一个错误。
您不需要保留 child :您应该使用 cv.RETR_TREE
为此,然后找到父亲的索引并查找所有轮廓,该父亲递归地为嵌套轮廓( child 的 child ......)进行递归。见 https://docs.opencv.org/4.1.0/d9/d8b/tutorial_py_contours_hierarchy.html但这对您的目标没有用。
您可以使用您当前拥有的结果作为原始图像的掩码,但代码需要一些修复,从名为 VS0L9.jpg
的链接图像开始.
请注意,我使用的是 cv2
, 改成 cv
.
加载图像
im = cv2.imread('VS0L9.jpg', cv2.IMREAD_GRAYSCALE)
找到轮廓(我使用 RETR_TREE)
contours, hierarchy = cv2.findContours(im, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
找到更大的轮廓:
bigger = max(contours, key=lambda item: cv2.contourArea(item))
初始化掩码(您尝试使用
image_binary
):the_mask = np.zeros_like(im)
在 mask 图像上绘制填充较大的轮廓,感兴趣的区域设置为 (255, 255, 255):
cv2.drawContours(the_mask, [bigger], -1, (255, 255, 255), cv2.FILLED)
此时,掩码看起来像代码的输出,但具有适当的宽度和高度。
使用带有原始图像的蒙版仅显示感兴趣的区域:
res = cv2.bitwise_and(im, im, mask = the_mask)
或者,或者:
res = im.copy()
res[the_mask == 0] = 0
现在
res
是想要的结果。
关于python - OpenCV Python 去除小轮廓,保存子轮廓,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62474223/