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?
Yes.
ndimage.label
(first invert the image, holes=black).ndimage.find_objects
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:
Output image (Middle size holes are gone):
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With