Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scipy Binary Closing - Edge Pixels lose value

I am attempting to fill holes in a binary image. The image is rather large so I have broken it into chunks for processing.

When I use the scipy.ndimage.morphology.binary_fill_holes functions, it fills larger holes that belong in the image. So I tried using scipy.ndimage.morphology.binary_closing, which gave the desired results of filling small holes in the image. However, when I put the chunks back together, to create the entire image, I end up with seamlines because the binary_closing function removes any values from the border pixels of each chunk.

Is there any way to avoid this effect?

like image 429
Brian Avatar asked Jan 17 '13 18:01

Brian


Video Answer


2 Answers

Yes.

  1. Label your image using ndimage.label (first invert the image, holes=black).
  2. Find the hole object slices with ndimage.find_objects
  3. Filter the list of object slices based on your size criteria
  4. Invert back your image and perform binary_fill_holes on the slices that meet your criteria.

That should do it, without needing to chop the image up. For example:

Input image:

enter image description here

Output image (Middle size holes are gone):

enter image description here

Here is the code (inequality is set to remove the middle size blobs):

import scipy
from scipy import ndimage
import numpy as np

im = scipy.misc.imread('cheese.png',flatten=1)
invert_im = np.where(im == 0, 1, 0)
label_im, num = ndimage.label(invert_im)
holes = ndimage.find_objects(label_im)
small_holes = [hole for hole in holes if 500 < im[hole].size < 1000]
for hole in small_holes:
    a,b,c,d =  (max(hole[0].start-1,0),
                min(hole[0].stop+1,im.shape[0]-1),
                max(hole[1].start-1,0),
                min(hole[1].stop+1,im.shape[1]-1))
    im[a:b,c:d] = scipy.ndimage.morphology.binary_fill_holes(im[a:b,c:d]).astype(int)*255

Also note that I had to increase the size of the slices so that the holes would have border all the way around.

like image 139
fraxel Avatar answered Oct 05 '22 11:10

fraxel


Operations that involve information from neighboring pixels, such as closing will always have trouble at the edges. In your case, this is very easy to get around: just process subimages that are slightly larger than your tiling, and keep the good parts when stitching together.

like image 40
tom10 Avatar answered Oct 05 '22 09:10

tom10