[scikit-image] fill closed contour

Randy Heiland randy.heiland at gmail.com
Mon Jan 8 21:03:11 EST 2018


Argh. Nevermind... need to flip black/white on canny edges:  1-(edges*1)



On Mon, Jan 8, 2018 at 8:55 PM, Randy Heiland <randy.heiland at gmail.com>
wrote:

> Thanks Juan. I understand better what the  ndi.measurements.label can do
> for me now. I've tweaked my previous script and attached the resulting
> output. Does it make sense that I need to "thicken" the contours in order
> to get the desired features/regions, or is there something I'm still
> missing?
>
> ------------
> from skimage.morphology import disk
> from skimage.feature import canny
> from skimage.filters import rank
> from scipy import ndimage as ndi
> import matplotlib.pyplot as plt
> import numpy as np
>
> image = disk(100)
> for ix in range(200):
>   for iy in range(200):
>     xdel=ix-100
>     ydel=iy-100
>     if (xdel*xdel/50 + ydel*ydel/10) < 110:
>       image[iy,ix]=0
>     elif (xdel*xdel/10 + ydel*ydel/50) < 110:
>       image[iy,ix]=0
>
> edges = canny(image*255.)  # canny expect grayscale, i.e. 0-255 ??!
>
> thicken = rank.gradient(edges, disk(1)) < 5
> bdy = thicken.astype(np.uint8)*255
>
> labeled_array, num_features = ndi.measurements.label(edges*1)
> print("num_features (edges*1)=",num_features)
> labeled_array2, num_features2 = ndi.measurements.label(bdy)
> print("num_features (thick)=",num_features2)
>
> fill = ndi.binary_fill_holes(edges)
>
> fig, axes = plt.subplots(ncols=2, nrows=2, figsize=(6, 7))
> ax = axes.ravel()
>
> ax[0].imshow(edges*1, cmap=plt.cm.gray, interpolation='nearest')
> ax[0].set_title('Canny edges')
> ax[1].imshow(labeled_array, cmap=plt.cm.spectral, interpolation='nearest')
> ax[1].set_title('labeled_array')
>
> ax[2].imshow(bdy, cmap=plt.cm.gray, interpolation='nearest')
> ax[2].set_title('bdy')
> ax[3].imshow(labeled_array2, cmap=plt.cm.spectral, interpolation='nearest')
> ax[3].set_title('labeled_array2')
>
> plt.axis('off')
> plt.show()
>
> -->
> num_features (edges*1)= 216
> num_features (thick)= 6
>
> -Randy
>
>
> On Sun, Jan 7, 2018 at 11:36 PM, Juan Nunez-Iglesias <jni.soma at gmail.com>
> wrote:
>
>> Oh, I see what's happening. So, in your case, both void spaces are
>> actually holes from the perspective of the binary_fill_holes algorithm, so
>> they both get filled. I suggest you
>>
>> a) label both contours using ndi.label
>> b) use binary_fill_holes on each label separately
>> c) subtract the filled inner hole from the filled outer hole (you can
>> optionally add back in the inner contour if you care about that
>> single-pixel precision)
>>
>> This requires being able to robustly identify the inner and outer
>> contours, but I don't think that should be too hard? If you only have two,
>> you can certainly find them by finding the "larger" of the two bounding
>> boxes. You can use skimage.measure.regionprops for this.
>>
>> I hope that helps!
>>
>> Juan.
>>
>> On 8 Jan 2018, 12:21 PM +1100, Randy Heiland <randy.heiland at gmail.com>,
>> wrote:
>>
>> Sure - thanks.
>>
>> from skimage.morphology import disk
>> from skimage.feature import canny
>> from scipy import ndimage as ndi
>> import matplotlib.pyplot as plt
>>
>> image = disk(100)
>> for ix in range(200):
>>   for iy in range(200):
>>     xdel=ix-100
>>     ydel=iy-100
>>     if (xdel*xdel/50 + ydel*ydel/10) < 110:
>>       image[iy,ix]=0
>>     elif (xdel*xdel/10 + ydel*ydel/50) < 110:
>>       image[iy,ix]=0
>>
>> edges = canny(image*255.)  # canny expect grayscale, i.e. 0-255 ??!
>>
>> fill = ndi.binary_fill_holes(edges)   # I don't understand the params;
>> can I seed a region to fill?
>>
>> fig, axes = plt.subplots(ncols=3, figsize=(9, 3))
>> ax = axes.ravel()
>>
>> ax[0].imshow(image, cmap=plt.cm.gray, interpolation='nearest')
>> #ax[0].imshow(invert_img, cmap=plt.cm.gray)
>> #ax[0].set_title('Inverted image')
>> ax[0].set_title('Original image')
>>
>> ax[1].imshow(edges*1, cmap=plt.cm.gray, interpolation='nearest')
>> ax[1].set_title('Canny edges')
>>
>> ax[2].imshow(fill, cmap=plt.cm.spectral, interpolation='nearest')
>> ax[2].set_title('Fill')
>>
>> plt.show()
>>
>>
>>
>> On Sun, Jan 7, 2018 at 6:57 PM, Juan Nunez-Iglesias <jni.soma at gmail.com>
>> wrote:
>>
>>> Hi Randy, I was going to suggest binary fill holes. Do you mind posting
>>> your image and the code you’ve tried so we can troubleshoot?
>>>
>>> Thanks,
>>>
>>> Juan.
>>>
>>> On 8 Jan 2018, 9:48 AM +1100, Randy Heiland <randy.heiland at gmail.com>,
>>> wrote:
>>>
>>> If I have a binary image with, say, just a contour boundary (simple
>>> example: a white background with a black circle, i.e. an "o"), how can I
>>> fill the inside of the contour? I've played with both the watershed
>>> segmentation and the scipy.ndimage.binary_fill_holes, without success.
>>>
>>> thanks, Randy
>>> _______________________________________________
>>> scikit-image mailing list
>>> scikit-image at python.org
>>> https://mail.python.org/mailman/listinfo/scikit-image
>>>
>>>
>>> _______________________________________________
>>> scikit-image mailing list
>>> scikit-image at python.org
>>> https://mail.python.org/mailman/listinfo/scikit-image
>>>
>>>
>> _______________________________________________
>> scikit-image mailing list
>> scikit-image at python.org
>> https://mail.python.org/mailman/listinfo/scikit-image
>>
>>
>> _______________________________________________
>> scikit-image mailing list
>> scikit-image at python.org
>> https://mail.python.org/mailman/listinfo/scikit-image
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/scikit-image/attachments/20180108/f0374a09/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: synth_2x2b.png
Type: image/png
Size: 79839 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/scikit-image/attachments/20180108/f0374a09/attachment-0001.png>


More information about the scikit-image mailing list