[scikit-image] fill closed contour

Randy Heiland randy.heiland at gmail.com
Mon Jan 8 21:30:40 EST 2018


Sorry to be dense, but could you elaborate on "labeling the holes rather
than edges"? What lines would I tweak in my script?

On Mon, Jan 8, 2018 at 9:20 PM, Juan Nunez-Iglesias <jni.soma at gmail.com>
wrote:

> Ah, your issue with the thickening was that label by default does not
> consider diagonally-adjancent pixels as adjacent. You need to pass
> connectivity=2 for this to be the case. But actually labelling the holes
> rather than the edges is a rather better option. =) The final image looks
> very pretty and could make a nice company logo. =P
>
> On 9 Jan 2018, 1:03 PM +1100, Randy Heiland <randy.heiland at gmail.com>,
> wrote:
>
> 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
>>>
>>>
>>
> _______________________________________________
> 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/946b76f9/attachment-0001.html>


More information about the scikit-image mailing list