这是我的代码,我试图从二值图像中删除掩模(噪声)。我得到的是噪音周围留下的白线。我知道,在结果中有一条轮廓线围绕着噪声,形成了最终的白线。有什么帮助吗?
原始图像

掩码和结果

代码
import numpy as np
import cv2
from skimage import util
img = cv2.imread('11_otsu.png')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
#cv2.drawContours(img, contours, -1, (0,255,0), 2)
# create an empty mask
mask = np.zeros(img.shape[:2], dtype=np.uint8)
# loop through the contours
for i, cnt in enumerate(contours):
# if the contour has no other contours inside of it
if hierarchy[0][i][2] == -1:
# if the size of the contour is greater than a threshold
if cv2.contourArea(cnt) <70:
cv2.drawContours(mask, [cnt], 0, (255), -1)
# display result
cv2.imshow("Mask", mask)
cv2.imshow("Img", img)
image = cv2.bitwise_not(img, img, mask=mask)
cv2.imshow("Mask", mask)
cv2.imshow("After", image)
cv2.waitKey()
cv2.destroyAllWindows()发布于 2020-11-17 17:11:39
您的代码非常好,只需进行以下调整,它就会正常工作:
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) # Use cv2.CCOMP for two level hierarchy
if hierarchy[0][i][3] != -1: # basically look for holes
# if the size of the contour is less than a threshold (noise)
if cv2.contourArea(cnt) < 70:
# Fill the holes in the original image
cv2.drawContours(img, [cnt], 0, (255), -1)发布于 2020-11-17 16:20:30
与其尝试寻找内部轮廓并填充它们,我可以建议使用cv2.floodFill代替吗?整体填充操作通常用于填充闭合对象内的孔。具体地说,如果您将种子像素设置为图像的左上角,然后整体填充图像,则将填充的是背景,而闭合对象则保持不变。如果你反转这张图片,你会发现闭合物体内部的所有像素都有“洞”。如果你取这个倒置的图像,并使用非零位置来直接设置原始图像,那么你就会填满这些洞。
因此:
im = cv2.imread('8AdUp.png', 0)
h, w = im.shape[:2]
mask = np.zeros((h+2, w+2), dtype=np.uint8)
holes = cv2.floodFill(im.copy(), mask, (0, 0), 255)[1]
holes = ~holes
im[holes == 255] = 255
cv2.imshow('Holes Filled', im)
cv2.waitKey(0)
cv2.destroyAllWindows()首先,我们读取您提供的图像,它是阈值图像,在“噪声过滤”之前,然后获得它的高度和宽度。我们还使用输入掩码来告诉我们要在泛洪填充上操作哪些像素。使用全零掩码意味着您将对整个图像进行操作。同样重要的是要注意,在使用蒙版之前,蒙版需要有一个1像素的边界。我们使用左上角作为初始点来泛洪填充图像,反转它,将任何“洞”像素设置为255并显示它。请注意,一旦该方法完成,输入图像就会发生变化,因此您需要传入一个副本以保持输入图像不变。此外,cv2.floodFill (使用OpenCV 4)返回一个包含四个元素的元组。我将让您查看文档,但是您需要这个元组的第二个元素,即已填充的图像。
因此,我们得到:

发布于 2020-11-17 16:14:59
我认为使用cv2.GaussianBlur()方法可能会对您有所帮助。将图像转换为灰度后,使用此方法对其进行模糊处理(顾名思义,这是一个高斯过滤器)。下面是文档:https://docs.opencv.org/4.3.0/d4/d86/group__imgproc__filter.html
https://stackoverflow.com/questions/64871134
复制相似问题