如何消除图像中物体的边缘噪声

时间:2018-09-24 00:31:01

标签: python opencv mask noise

我创建了一个服装遮罩以从图像中提取服装对象,但是遮罩中包含一些白噪声,下面是插图(外部黑色区域是背景)。

我想消除蒙版中的“白色”边缘噪声,并且我尝试使用幼稚的方法来检查像素值是否大于等于240,结果有所改善,但仍然不够完美,如下所示:

我想完全消除白噪声,但不确定如何去做。我正在使用python opencv,如果有人可以帮助我,我将不胜感激。

谢谢!

2 个答案:

答案 0 :(得分:1)

我建议使用一个简单的管道来消除边缘噪声:

import numpy as np
import cv2

gray = cv2.imread("t1yfp.jpg", cv2.IMREAD_GRAYSCALE)

#  eliminate white blobs
kernel = np.ones((5, 5), np.float32)/25
processedImage = cv2.filter2D(gray, -1, kernel)
gray[processedImage > 100] = 0

#  eliminate pixels with very large value
gray[gray > 230] = 0

#  eliminate last remeaning outlier white pixels
gray = cv2.medianBlur(gray, 5)



#  display result
cv2.imshow("res", gray)
cv2.waitKey(0)

最后一步之后,图像蒙版内的白色像素也将被消除。您也许可以使用平均滤波器来恢复它们。结果如下:
enter image description here

答案 1 :(得分:0)

通过对阈值图像进行放大,我可以从图像中略微咬一口并去除所有白色,但是从某些无辜区域中删除了1px的边缘。

这是结果:

enter image description here

这是基于this answer的代码:

import cv2
import numpy as np

# Create binary threshold
img = cv2.imread('shirt.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, gray = cv2.threshold(gray, 220, 255, cv2.THRESH_BINARY)

# Dilate the image to join small pieces to the larger white sections
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
gray = cv2.dilate(gray, kernel)

# Create the mask by filling in all the contours of the dilated edges
mask = np.zeros(gray.shape, np.uint8)
_, contours, _ = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
    if 10 < cv2.contourArea(cnt) < 5000:
        #  cv2.drawContours(img, [cnt], 0, (0, 255, 0), 2)
        cv2.drawContours(mask, [cnt], 0, 255, -1)

# Erode the edges back to their orig. size
# Leaving this out creates a more greedy bite of the edges, removing the single strands
#  mask = cv2.erode(mask, kernel)

cv2.imwrite('im.png', img)
cv2.imwrite('ma.png', mask)

mask = cv2.cvtColor(255 - mask, cv2.COLOR_GRAY2BGR)
img = img & mask
cv2.imwrite('fi.png', img)

这个答案的优点是轮廓部分,如果您弄错了魔术数字10(我假设这可能不是您要运行此代码的唯一图像,则可以让您保留较小尺寸的白色区域)。 )如果不需要这样做,则代码可能会简单得多,只需1)提取原始阈值,2)扩展阈值,3)将其掩盖在原始图像上即可。