如何删除blob边框上的单个像素?

flo*_*ree 6 c++ python matlab opencv image-processing

我有一个如下所示的二进制图像.如何删除blob边框上的单个像素?

在此输入图像描述

如果你不想要,不需要提供完整的代码,你可以解释一些算法或指向正确的方向.

flo*_*ree 6

我设法通过使用 midtiby 建议的命中和未命中变换来解决这个问题。我使用以下内核来检测顶部、右侧、底部和左侧的单像素。

-1 -1 -1     1 -1 -1      1  1  1     -1 -1  1
-1  1 -1     1  1 -1     -1  1 -1     -1  1  1
 1  1  1     1 -1 -1     -1 -1 -1     -1 -1  1
Run Code Online (Sandbox Code Playgroud)

其中-1代表背景,1代表前景, 代表0不关心(在本例中未使用)。

四次命中和未命中变换的结果将用作掩模以删除单个像素。以下是 Python/OpenCV 的完整代码:

import numpy as np
import cv2

def hitmiss(src, kernel):
    im = src / 255
    k1 = (kernel == 1).astype('uint8')
    k2 = (kernel == -1).astype('uint8')
    e1 = cv2.erode(im, k1, borderType=cv2.BORDER_CONSTANT)
    e2 = cv2.erode(1-im, k2, borderType=cv2.BORDER_CONSTANT)
    return e1 & e2

if __name__ == "__main__":
    im = cv2.imread('blobs.png', cv2.CV_LOAD_IMAGE_GRAYSCALE)
    _, im_binary = cv2.threshold(im, 50, 255, cv2.THRESH_BINARY)

    kernel = np.array([[-1,-1, 1], 
                       [-1, 1, 1], 
                       [-1,-1, 1]])

    im_mask = np.zeros(im_binary.shape, np.uint8)

    im_mask |= hitmiss(im_binary, kernel)
    im_mask |= hitmiss(im_binary, np.fliplr(kernel))
    im_mask |= hitmiss(im_binary, kernel.T)
    im_mask |= hitmiss(im_binary, np.flipud(kernel.T))

    im_dst = im_binary & ((1 - im_mask) * 255)
    cv2.imwrite('dst.png', im_dst)
Run Code Online (Sandbox Code Playgroud)

给定这个输入图像:

在此输入图像描述

该脚本将产生以下输出:

在此输入图像描述