首页 > 解决方案 > 二值化后如何从图像中去除粗线条伪影

问题描述

我遇到了一个问题,我想区分对象和背景(具有带背光的半透明白纸),即在背景中引入一条固定的粗线并与对象合并。我现在的算法是我从相机中获取图像,使用高斯模糊进行平滑处理,然后从 HSV 中提取值分量,使用 wolf 方法应用局部二值化来获取二值化图像,然后使用 OpenCV 连接分量算法删除一些小的伪影没有连接到这里看到的对象。现在只有这条线伪影与对象合并,但我只想要这张图片中看到的对象. 请注意,二进制图像中有 2 行,因此使用 8 个连接的逻辑来检测不形成循环的行是不可能的,这也是我的想法和尝试。这是代码

size = np.size(thresh_img)
skel = np.zeros(thresh_img.shape,np.uint8)
element = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
done = False

while( not done):
    eroded = cv2.erode(thresh_img,element)
    temp = cv2.dilate(eroded,element)
    temp = cv2.subtract(thresh_img,temp)
    skel = cv2.bitwise_or(skel,temp)
    thresh_img = eroded.copy()

    zeros = size - cv2.countNonZero(thresh_img)
    if zeros==size:
       done = True

# set max pixel value to 1
s = np.uint8(skel > 0)

count = 0
i = 0
while count != np.sum(s):
     # non-zero pixel count
     count = np.sum(s)
     # examine 3x3 neighborhood of each pixel
     filt = cv2.boxFilter(s, -1, (3, 3), normalize=False)
     # if the center pixel of 3x3 neighborhood is zero, we are not interested in it
     s = s*filt
     # now we have pixels where the center pixel of 3x3 neighborhood is non-zero
     # if a pixels' 8-connectivity is less than 2 we can remove it
     # threshold is 3 here because the boxfilter also counted the center pixel
     s[s < 1] = 0
     # set max pixel value to 1
     s[s > 0] = 1
     i = i + 1

非常感谢任何以代码形式提供的帮助。

标签: pythonnumpyopencvimage-processingimage-thresholding

解决方案


由于您已经在使用 connectedComponents ,因此最好的方法是排除那些较小的组件,还要排除那些触及图像边界的组件。您可以知道哪些将被丢弃,使用connectedComponentsWithStats()它还可以为您提供有关每个组件的边界框的信息。

或者,非常类似地,您可以切换connectedComponents()findContours()哪个直接为您提供组件,这样您就可以丢弃外部的和小的以检索您感兴趣的部分。


推荐阅读