我正在尝试删除除最大轮廓以外的所有轮廓,同时将子轮廓保留在最大轮廓内。实际上,我想从这里开始: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)
答案 0 :(得分:1)
您在代码cv.drawContours(image_binary, [max(contours, key = cv.contourArea)], -1, (255, 255, 255), -1)
中执行的操作是将(255, 255, 255)
的像素image_binary
的颜色设置为{{1}找到的较大轮廓的边界和内部像素}}。
创建cv.findContours
时,您也在将宽度与高度交换,这是一个错误。
您不需要保留孩子:您应该使用image_binary
,然后找到父亲的索引并查找所有轮廓,并由该父亲对嵌套轮廓(孩子的孩子)进行递归处理...)。请参见https://docs.opencv.org/4.1.0/d9/d8b/tutorial_py_contours_hierarchy.html,但这对您的目标没有用。
cv.RETR_TREE
的链接图像开始。
请注意,我正在使用VS0L9.jpg
,只需更改为cv2
。
加载图像
cv
找到轮廓(我使用了RETR_TREE)
im = cv2.imread('VS0L9.jpg', cv2.IMREAD_GRAYSCALE)
找到更大的轮廓:
contours, hierarchy = cv2.findContours(im, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
初始化掩码(您对bigger = max(contours, key=lambda item: cv2.contourArea(item))
进行的尝试)
image_binary
在蒙版图像上绘制较大轮廓的填充,将关注区域设置为(255,255,255):
the_mask = np.zeros_like(im)
这时,掩码看起来像代码的输出,但是具有适当的宽度和高度。 将遮罩与原始图像一起使用以仅显示感兴趣的区域:
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
是理想的结果。
答案 1 :(得分:0)
您可以使用形态学重建,以侵蚀图像作为标记。
import cv2
img = cv2.imread('VS0L9.jpg', cv2.IMREAD_GRAYSCALE)
thresh = cv2.threshold(img, 40, 255, cv2.THRESH_BINARY)[1]
kernel=cv2.getStructuringElement(cv2.MORPH_RECT, (17,17))
kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
marker = cv2.erode(thresh,kernel,iterations = 5)
while True:
tmp=marker.copy()
marker=cv2.dilate(marker, kernel2)
marker=cv2.min(thresh, marker)
difference = cv2.subtract(marker, tmp)
if cv2.countNonZero(difference) == 0:
break
cv2.imwrite('out.png', marker)
cv2.imshow('result', marker )