Filter out large segments

Tony Yu tsyu80 at gmail.com
Sun Dec 16 21:46:08 EST 2012


Hi again,

On Sun, Dec 16, 2012 at 7:09 PM, Parand Darugar <darugar at gmail.com> wrote:

> Hello,
>
> Not sure if it's appropriate to ask algorithm questions on this mailing
> list, please let me know if it's not.
>

Algorithm questions are definitely welcome.


> I'd like to filter out large contiguous regions out of my image - I only
> care about smaller items. Following the Image Segmentation
> example/tutorial, I'm able to find and label the large segments using an
> Otsu threshold and ndimage.label.
>
> Now I'd like to replace these large segments with "white", where "white"
> is the max value find in my grayscale image (basically I'd like to blank
> them out).
>
> I'm not quite following how this is done in the tutorial:
>
> >>> label_objects, nb_labels = ndimage.label(fill_coins)
> >>> sizes = np.bincount(label_objects.ravel())
> >>> mask_sizes = sizes > 20
> >>> mask_sizes[0] = 0
> >>> coins_cleaned = mask_sizes[label_objects]
>
> How does the coins_cleaned = mask_sizes[label_objects] line clean the
> image?
>

In case you didn't follow the `bincount` part: The `sizes` array is a count
of frequency of each label; so large labeled regions would have a large
size. The index is matched to the integer label: the count for label `i` is
stored in `sizes[i]`.

`mask_sizes` just looks for all labeled region larger than 20 pixels and
stores a boolean array (i.e. mask). So if the region labeled `i` has more
than 20 pixels then `mask_sizes[i]` is True. Also, `i = 0` values are set
to 0 because `i = 0` is reserved as the background label.

Based on your question, you probably understood all that, but I just wanted
to make sure we're on the same page. Now, the line that you actually asked
about is a bit of a numpy trick: It uses `label_objects` to pick values
from `mask_sizes`. A pixel labeled `i` (in `label_objects`) will grab the
value in `mask_sizes[i]` (i.e. True or False); that value will then get
placed in the output array at the same array position as the pixel in
`label_objects`.

That explanation was a bit confusing. Perhaps a short example will help:


>>> import numpy as np
>>> values = np.array([0, 0, 0, 1]) # stand-in for `mask_sizes`
>>> picker = np.array([[0, 1, 2, 3],
...                    [3, 0, 1, 2],
...                    [2, 3, 0, 1],
...                    [1, 2, 3, 0]])  # stand-in for `label_objects`
 >>> print values[picker]
[[0 0 0 1]
 [1 0 0 0]
 [0 1 0 0]
 [0 0 1 0]]


All the values in the picker labeled 3 are set to 1 in the output because
that was the value at `values[3]`. All other values were 0.



> Generally speaking, given the labeled segments (label_objects from the
> tutorial), how would I apply operations to the original image - for
> example: set all of the pixels in "image" that are parts of objects labeled
> 3 and 9 to 0.577 .
>

Something like this should work:


>>> mask_low = image < 3
>>> mask_high = image > 9
>>> image[mask_low & mask_high] = 0.577


Also, how do I get smarter about how the system works so I don't ask
> elementary questions? Is there a good high level tutorial that'll
> familiarize me with the computation model for skimage / ndimage ?
>

Well, I think these questions are more focused on numpy, which forms the
core of skimage. There are tons of numpy tutorials out there, but I don't
have a particular favorite. Someone on the numpy mailing list pointed to
the following tutorial:

http://scipy-lectures.github.com/intro/numpy/index.html

So that might be worth a look.

Best,
-Tony


>
> Best,
>
> Parand
>
> --
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/scikit-image/attachments/20121216/68b0e102/attachment.html>


More information about the scikit-image mailing list