【问题标题】:How to remove edge noises from an object in an image如何从图像中的对象中去除边缘噪声
【发布时间】:2019-02-27 12:00:33
【问题描述】:

我创建了一个衣服蒙版来从图像中提取衣服对象,但是蒙版中包含一些白噪声,下图是插图(外面的黑色区域是背景)。

我想去除遮罩中的“白”边缘噪点,我尝试过使用简单的方法检查像素值是否>= 240,结果有所改善但仍然不完美,如下图:

我想完全消除白噪声,但不知道该怎么做。我正在使用 python opencv,如果有人可以帮助我,我将不胜感激。

谢谢!

【问题讨论】:

    标签: python opencv mask noise


    【解决方案1】:

    通过扩大阈值图像,我能够从图像中取出稍大一点的部分并移除所有白色,但从一些无害区域移除了 1px 的边缘。

    结果如下:

    这是基于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) 在原始图像上屏蔽它。

    【讨论】:

    • 谢谢,是的,我需要处理不同颜色的图像。我试过你的代码,它适用于深色图像,但对于浅色图像,神奇的“10”参数往往会在衣服上产生洞。我也尝试调整该参数,但是很难为深色和浅色图像获得“完美”的参数。
    【解决方案2】:

    我会建议一个简单的管道来消除你的边缘噪音:

    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)
    

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

    【讨论】:

    • 虽然它确实去除了白色轮廓,但它也去除了衬衫上的所有细节。
    • 请解释一下删除所有细节是什么意思。
    • 我的意思是,原件在衬衫的前面有详细的火花。在您的输出中,图像是模糊的。
    • 感谢 unlut,但需要详细信息
    猜你喜欢
    • 1970-01-01
    • 2021-05-18
    • 2011-09-28
    • 2014-05-22
    • 2021-08-16
    • 2023-04-05
    • 2011-12-30
    • 2019-06-03
    • 1970-01-01
    相关资源
    最近更新 更多