Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove single pixels on the borders of a blob?

I have a binary image like shown below. How do I remove the single pixels on the borders of the blobs?

enter image description here

No need to give the full code if you don't want to, you can explain some algorithms or point me to the right direction.

like image 563
flowfree Avatar asked Apr 23 '14 08:04

flowfree


1 Answers

I managed to solve this problem by using the hit and miss transform as suggested by midtiby. I used the following kernels to detect the top, right, bottom, and left single-pixels.

-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

where -1 represent the background, 1 represent the foreground, and 0 for don't care (not being used in this case).

The result of the four hit and miss transform will be used as the mask to remove the single pixels. Below is the full code in 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)

Given this input image:

enter image description here

The script will produce this output:

enter image description here

like image 64
flowfree Avatar answered Oct 19 '22 04:10

flowfree