Connecting Tech Pros Worldwide Forums | Help | Site Map

Increasing masked areas in an array?

Newbie
 
Join Date: Feb 2007
Posts: 15
#1: Dec 11 '07
Hi guys,

I've asked for help here once before with great results, I thought I'd try it again.

(I'm on Ubuntu 6.06 with python 2.4. Xemacs as editor.)

I have an image as a scipy array and I've made a mask array for it, sources (stars/galaxies/etc.) are flagged with 1, sky is 0. Now I want to blow up the size of each flagged source by a factor of 2, or close to it. Meaning, if I originally have

Expand|Select|Wrap|Line Numbers
  1. array([[  0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
  2.        [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
  3.        [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
  4.        [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
  5.        [  0,   0,   1,   1,   1,   0,   0,   0,   0,   0],
  6.        [  0,   0,   1,   1,   1,   0,   0,   0,   0,   0],
  7.        [  0,   0,   1,   1,   1,   0,   0,   0,   0,   0],
  8.        [  0,   0,   1,   1,   1,   0,   0,   0,   0,   0],
  9.        [  0,   0,   1,   1,   1,   0,   0,   0,   0,   0],
  10.        [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
  11.        [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
  12.        [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
  13.        [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
  14.        [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0]], dtype=int32)
I want to have
Expand|Select|Wrap|Line Numbers
  1. array([[  0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
  2.        [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
  3.        [  1,   1,   1,   1,   1,   1,   1,   1,   0,   0],
  4.        [  1,   1,   1,   1,   1,   1,   1,   1,   0,   0],
  5.        [  1,   1,   1,   1,   1,   1,   1,   1,   0,   0],
  6.        [  1,   1,   1,   1,   1,   1,   1,   1,   0,   0],
  7.        [  1,   1,   1,   1,   1,   1,   1,   1,   0,   0],
  8.        [  1,   1,   1,   1,   1,   1,   1,   1,   0,   0],
  9.        [  1,   1,   1,   1,   1,   1,   1,   1,   0,   0],
  10.        [  1,   1,   1,   1,   1,   1,   1,   1,   0,   0],
  11.        [  1,   1,   1,   1,   1,   1,   1,   1,   0,   0],
  12.        [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
  13.        [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
  14.        [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0]], dtype=int32)

Now, I thought wrong, and instead I wrote something that simply takes each pixel flagged with '1' and adds the indices of all its neighbouring pixels to the mask. But that only blows things up by one additional pixel at the borders of the source. Really not what I wanted. However, I could use the same technique if I knew the radius of each flagged "island" (at least approximately. and it will be different for every source). But it seems to me I'll have to got throught the image line by line to obtain the max and min indices of each group of neighbouring pixels. That would be incredibly slow, especially since I have over 3000 images (and many many things are being done to them, in addition to masking the sources).

I was wondering if you have some ideas. Maybe something like this already exists somewhere? Surely people have tried at some point to do exactly this, increase the masked area in an array by some factor??

Well, here's my code, it's looks really sad.




Expand|Select|Wrap|Line Numbers
  1. import pyfits as PF
  2. import scipy
  3. import sets
  4.  
  5. def maskObjects(image):
       #'image' is segmentation image from SExtractor
  6.     fits=PF.open(image)
  7.     data=fits[0].data
  8.     hdr=fits[0].header
  9.     data=data.astype(float)
  10.  
  11.      #for test purposes only
  12.     data=data[1000:1015,1000:1015]
  13.  
  14.     #make mask, mark source with '1', sky with '0'
  15.     mask=scipy.where(data>0,1,0)
  16.  
  17.     idx=[]
  18.     for i,value in enumerate(mask.flat):
  19.         if value:  idx.append(i)
  20.      idx_array=scipy.array(idx)
  21.     width,height=idx_array.shape
  22.  
  23.  
  24.  
  25.     left=sets.Set((idx_array-1).flat)
  26.     right=sets.Set((idx_array+1).flat)    
  27.     low_left=sets.Set((idx_array-1+width).flat)
  28.     low_right=sets.Set((idx_array+1+width).flat)
  29.     up_left=sets.Set((idx_array-1-width).flat)
  30.     up_right=sets.Set((idx_array+1-width).flat)
  31.     orig_set=sets.Set(idx)
  32.  
  33.    blownup=orig_set.update(left.update(right))
  34.    blownup.update(low_left.update(low_right))
  35.    blownup.update(up_left.update(up_right))
  36.  
  37.    # remove indices out of bounds here. - Later.
  38.    #max_idx=width*height-1
  39.  
  40.         

Newbie
 
Join Date: Feb 2007
Posts: 15
#2: Dec 11 '07

re: Increasing masked areas in an array?


I see I made a typo in my code



width,height=idx_array.shape

should instead be

width,height=mask.shape
Newbie
 
Join Date: Feb 2007
Posts: 15
#3: Dec 11 '07

re: Increasing masked areas in an array?


well, damn it all to hell!! My code doesn't even do what I thought it did, it doesn't increase the size of the masked area, instead it shifts the source twice! I don't get it, surely if a pixel has index x, then the pixel right under it would have index x+image_width??

See the original




this is the result of my "increased" masked area



I need coffee.
Newbie
 
Join Date: Feb 2007
Posts: 15
#4: Dec 17 '07

re: Increasing masked areas in an array?


Well, in case anyone cares, the above can be done correctly by modifying this code I found in the SciPy Cookbook at scipy.org/Cookbook. Import scipy somewhere.

Expand|Select|Wrap|Line Numbers
  1. def enlarge(a, x=2, y=None):
  2.     """Enlarges 2D image array a using simple pixel repetition in both dimensions.
  3.     Enlarges by factor x horizontally and factor y vertically.
  4.     If y is left as None, uses factor x for both dimensions."""
  5.     a = asarray(a)
  6.     assert a.ndim == 2
  7.     if y == None:    y = x
  8.     for factor in (x, y):
  9.         assert factor.__class__ == int
  10.         assert factor > 0
  11.     return a.repeat(y, axis=0).repeat(x, axis=1)
Reply