3

i have a large numpy array and labeled it with the connected component labeling in scipy. Now i want to create subsets of this array, where only the biggest or smallest labels in size are left. Both extrema can of course occur several times.

import numpy
from scipy import ndimage
....
# Loaded in my image file here. To big to paste
....
s = ndimage.generate_binary_structure(2,2) # iterate structure
labeled_array, numpatches = ndimage.label(array,s) # labeling
# get the area (nr. of pixels) of each labeled patch
sizes = ndimage.sum(array,labeled_array,range(1,numpatches+1)) 

# To get the indices of all the min/max patches. Is this the correct label id?
map = numpy.where(sizes==sizes.max()) 
mip = numpy.where(sizes==sizes.min())

# This here doesn't work! Now i want to create a copy of the array and fill only those cells
# inside the largest, respecitively the smallest labeled patches with values
feature = numpy.zeros_like(array, dtype=int)
feature[labeled_array == map] = 1

Someone can give me hint how to move on?

2 Answers 2

6

Here is the full code:

import numpy
from scipy import ndimage

array = numpy.zeros((100, 100), dtype=np.uint8)
x = np.random.randint(0, 100, 2000)
y = np.random.randint(0, 100, 2000)
array[x, y] = 1

pl.imshow(array, cmap="gray", interpolation="nearest")

s = ndimage.generate_binary_structure(2,2) # iterate structure
labeled_array, numpatches = ndimage.label(array,s) # labeling

sizes = ndimage.sum(array,labeled_array,range(1,numpatches+1)) 
# To get the indices of all the min/max patches. Is this the correct label id?
map = numpy.where(sizes==sizes.max())[0] + 1 
mip = numpy.where(sizes==sizes.min())[0] + 1

# inside the largest, respecitively the smallest labeled patches with values
max_index = np.zeros(numpatches + 1, np.uint8)
max_index[map] = 1
max_feature = max_index[labeled_array]

min_index = np.zeros(numpatches + 1, np.uint8)
min_index[mip] = 1
min_feature = min_index[labeled_array]

Notes:

  • numpy.where returns a tuple
  • the size of label 1 is sizes[0], so you need to add 1 to the result of numpy.where
  • To get a mask array with multiple labels, you can use labeled_array as the index of a label mask array.

The results:

enter image description here

enter image description here

enter image description here

1
  • GREAT, thank your very much! This works very well. I tried indexing it before but i didn't get the trick of adding 1 to the size of label 1 before.
    – Curlew
    Mar 8, 2013 at 16:42
3

first you need a labeled mask, given a mask with only 0(background) and 1(foreground):

labeled_mask, cc_num = ndimage.label(mask)

then find the largest connected component:

largest_cc_mask = (labeled_mask == (np.bincount(labeled_mask.flat)[1:].argmax() + 1))

you can deduce the smallest object finding by using argmin()..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.