Issue with morphological filters

Juan Nunez-Iglesias jni.soma at gmail.com
Mon Mar 30 00:03:20 EDT 2015


Hmm, I must say I don't know what's going on with either the reconstruction or the binary_fill_holes. (Originally I thought the image was inverted but you tried both polarities...) My advice would be to look at a few iterations of morphological reconstruction manually and see what's going on...


Also, I would use the "grey" colormap, which is the most intuitive to look at (you used a reversed colormap for a couple of the images).




Finally, it may be that you need to fill each "blob" independently. If so, have a look at skimage.measure.regionprops.filled_image.


http://scikit-image.org/docs/dev/api/skimage.measure.html#regionprops




Juan.

On Sat, Mar 28, 2015 at 2:32 AM, Matteo <matteo.niccoli at gmail.com> wrote:

> Hello Juan
> Here it is: 
> http://nbviewer.ipython.org/urls/dl.dropbox.com/s/ancfxe2gx1fbyyp/morphology_test.ipynb?dl=0
> I get the same, odd results, with both ndimage's binary_fill_holes, and 
> reconstruction. IS it because of the structuring elements/masks?
> Thanks for your help.
> Matteo
> On Thursday, March 26, 2015 at 11:14:05 PM UTC-6, Juan Nunez-Iglesias wrote:
>> Hi Matteo,
>>
>> Can you try putting this notebook up as a gist and pasting a link to the 
>> notebook? It's hard for me to follow all of the steps (and the polarity of 
>> the image) without the images inline. Is it just the inverse of what you 
>> want? And anyway why aren't you just using ndimage's binary_fill_holes?
>>
>>  
>> https://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.ndimage.morphology.binary_fill_holes.html
>>
>> Juan.
>>  
>>
>>
>>
>> On Fri, Mar 27, 2015 at 9:09 AM, Matteo <matteo.... at gmail.com 
>> <javascript:>> wrote:
>>
>>  Hello Juan
>>
>> Thanks so much for your suggestions.
>> Once I convertedthe image as you suggested:
>>  # import back image
>> cfthdr=io.imread('filled_contour_THDR.png')
>> cfthdr = color.rgb2gray(cfthdr) > 0.5 
>>
>> I get good results with opening:
>>  # clean it up with opening
>> selem17 = disk(17)
>> opened_thdr = opening(cfthdr, selem17)/255
>> # plot it 
>> fig = plt.figure(figsize=(5, 5))
>> ax = fig.add_subplot(1, 1, 1)
>> ax.set_xticks([])
>> ax.set_yticks([])
>> plt.imshow(opened_thdr,cmap='bone')
>> plt.show()
>> # not bad
>>  
>>
>> With remove_small_objects the advantage is that it does not join blobs in 
>> the original:
>>  cfthdr_inv = ~cfthdr
>> test=remove_small_objects(cfthdr,10000)
>> # plot it 
>> fig = plt.figure(figsize=(5, 5))
>> ax = fig.add_subplot(1, 1, 1)
>> ax.set_xticks([])
>> ax.set_yticks([])
>> plt.imshow(test,cmap='bone')
>> plt.show() 
>>
>>
>> but with reconstruction done as this:
>>  # filling holes with morphological reconstruction
>> seed = np.copy(cfthdr_inv)
>> seed[1:-1, 1:-1] = cfthdr_inv.max()
>> mask = cfthdr_inv
>> filled = reconstruction(seed, mask, method='erosion')
>> # plot it 
>> fig = plt.figure(figsize=(5, 5))
>> ax = fig.add_subplot(1, 1, 1)
>> ax.set_xticks([])
>> ax.set_yticks([])
>> plt.imshow(filled,cmap='bone',vmin=cfthdr_inv.min(), vmax=cfthdr_inv.max
>> ())
>> plt.show() 
>>  
>> I get a completely white image. Do you have any suggestions as to why?
>>
>> Thank again. Cheers,
>> Matteo
>>
>>  
>> On Wednesday, March 25, 2015 at 6:29:43 PM UTC-6, Juan Nunez-Iglesias 
>> wrote:
>>
>> Hi Matteo,
>>
>> My guess is that even though you are looking at a "black and white" image, 
>> the png is actually an RGB png. Just check the output of 
>> "print(cfthdr.shape)". Should be straightforward to make it a binary image:
>>
>> from skimage import color
>>  cfthdr = color.rgb2gray(cfthdr) > 0.5
>>
>> Then you should have a binary image. (And inverting should be as simple as 
>> "cfthdr_inv = ~cfthdr") We have morphology.binary_fill_holes to do what you 
>> want.
>>
>> btw, there's also morphology.remove_small_objects, which does exactly what 
>> you did but as a function call. Finally, it looks like you are not using 
>> the latest version of scikit-image (0.11), so you might want to upgrade.
>>
>> Hope that helps!
>>
>> Juan.
>>  
>>
>>
>>
>> On Thu, Mar 26, 2015 at 8:48 AM, Matteo <matteo.... at gmail.com> wrote:
>>
>>   *Issues with morphological filters when trying to remove white holes in 
>> black objects in a binary images. Using opening or filling holes on 
>> inverted (or complement) of the original binary.*
>>
>> Hi there 
>>  
>> I have a series of derivatives calculated on geophysical data.
>>  
>> Many of these derivatives have nice continuous maxima, so I treat them as 
>> images on which I do some cleanup with morphological filter. 
>>  
>> Here's one example of operations that I do routinely, and successfully:
>>  
>> # threshold theta map  using Otsu method
>>  
>> thresh_th = threshold_otsu(theta)
>>  
>> binary_th = theta > thresh_th
>>  
>> # clean up small objects
>>  
>> label_objects_th, nb_labels_th = sp.ndimage.label(binary_th)
>>  
>> sizes_th = np.bincount(label_objects_th.ravel())
>>  
>> mask_sizes_th = sizes_th > 175
>>  
>> mask_sizes_th[0] = 0
>>  
>> binary_cleaned_th = mask_sizes_th[label_objects_th]
>>  
>> # further enhance with morphological closing (dilation followed by an 
>> erosion) to remove small dark spots and connect small bright cracks
>>  
>> # followed by an extra erosion
>>  
>> selem = disk(1)
>>  
>> closed_th = closing(binary_cleaned_th, selem)/255
>>  
>> eroded_th = erosion(closed_th, selem)/255
>>  
>> # Finally, extract lienaments using skeletonization
>>  
>> skeleton_th=skeletonize(binary_th)
>>  
>> skeleton_cleaned_th=skeletonize(binary_cleaned_th)
>>  
>> # plot to compare
>>  
>> fig = plt.figure(figsize=(20, 7))
>>  
>> ax = fig.add_subplot(1, 2, 1)
>>  
>> imshow(skeleton_th, cmap='bone_r', interpolation='none')
>>  
>> ax2 = fig.add_subplot(1, 3, 2)
>>  
>> imshow(skeleton_cleaned_th, cmap='bone_r', interpolation='none')
>>  
>> ax.set_xticks([])
>>  
>> ax.set_yticks([])
>>  
>> ax2.set_xticks([])
>>  ax2.set_yticks([])
>>
>>  Unfortunately I cannot share the data as it is proprietary, but I will 
>> for the next example, which is the one that does not work.
>>
>>  There's one derivative that shows lots of detail but not continuous 
>> maxima. As a workaround I created filled contours in Matplotlib
>>  
>> exported as an image. The image is attached.
>>  
>> Now I want to import back the image and plot it to test: 
>>  
>> # import back image 
>>  
>> cfthdr=io.imread('filled_contour.png') 
>>  
>> # threshold using using Otsu method 
>>  
>> thresh_thdr = threshold_otsu(cfthdr) 
>>  
>> binary_thdr = cfthdr > thresh_thdr 
>>  
>> # plot it 
>>  
>> fig = plt.figure(figsize=(5, 5)) 
>>  
>> ax = fig.add_subplot(1, 1, 1) 
>>  
>> ax.set_xticks([]) 
>>  
>> ax.set_yticks([]) 
>>  
>> plt.imshow(binary_thdr, cmap='bone') 
>>  
>> plt.show() 
>>  
>> The above works without issues. 
>>  
>>  
>>  
>> Next I want to fill the white holes inside the black blobs. I thought of 2 
>> strategies.
>>  
>> The first would be to use opening; the second to invert the image, and 
>> then fill the holes as in here: 
>>  
>> http://scikit-image.org/docs/dev/auto_examples/plot_holes_and_peaks.html 
>>  
>> By the way, I found a similar example for opencv here
>>  
>>
>> http://stackoverflow.com/questions/10316057/filling-holes-inside-a-binary-object
>>   
>> Let's start with opening. When I try: 
>>  
>> selem = disk(1) 
>>  
>> opened_thdr = opening(binary_thdr, selem) 
>>  
>> or:
>>  
>> selem = disk(1) 
>>  
>> opened_thdr = opening(cfthdr, selem) 
>>  
>> I get an error message like this: 
>>  
>> --------------------------------------------------------------------------- 
>>
>>  
>> ValueError                                Traceback (most recent call 
>> last) 
>>  
>> <ipython-input-49-edc0d01ba327> in <module>() 
>>  
>>       1 #binary_thdr=img_as_float(binary_thdr,force_copy=False) 
>>  
>> ----> 2 opened_thdr = opening(binary_thdr, selem)/255 
>>  
>>       3 
>>
>> ...
> -- 
> You received this message because you are subscribed to the Google Groups "scikit-image" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to scikit-image+unsubscribe at googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/scikit-image/attachments/20150329/68c14bd7/attachment.html>


More information about the scikit-image mailing list