Search code examples
python-3.xnumpyscikit-image

How to reduce image portion with numpy.compress method ? (numpy+scikit-image)


Hi using the sample image phantom.png I'm following some operations with numpy + skimage libraries and after some modifications the last one exercise ask for:

Compress the size of center spots by 50% and plot the final image.

These are the steps I do before.

I read the image doing

img = imread(os.path.join(data_dir, 'phantom.png'))

Then apply following to make it black and white

img[np.less_equal(img[:,:,0],50)] = 0
img[np.greater_equal(img[:,:,0],51)] = 255

Took couple of slices of the image (the black spots) with given coordinates

img_slice=img.copy() 
img_slice=img_slice[100:300, 100:200]
img_slice2=img.copy() 
img_slice2=img_slice2[100:300, 200:300]

Now flip them

img_slice=np.fliplr(img_slice)
img_slice2=np.fliplr(img_slice2)

And put them back into an image copy

img2=img.copy()
img2[100:300, 200:300]=img_slice 
img2[100:300, 100:200]=img_slice2

And this is the resulting image before the final ("compress") excersise:

enter image description here

Then I'm asked to "reduce" the black spots by using the numpy.compress method.

The expected result after using "compress" method is the following image (screenshot) where the black spots are reduced by 50%:

But I have no clue of how to use numpy.compress method over the image or image slices to get that result, not even close, all what I get is just chunks of the image that looks like cropped or stretched portions of it.

enter image description here

I will appreciate any help/explanation about how the numpy.compress method works for this matter and even if is feasible to use it for this.


Solution

  • You seem ok with cropping and extracting, but just stuck on the compress aspect. So, crop out the middle and save that as im and we will compress that in the next step. Fill the area you cropped from with white.

    Now, compress the part you cropped out. In order to reduce by 50%, you need to take alternate rows and alternate columns, so:

    # Generate a vector alternating between True and False the same height as "im"
    a = [(i%2)==0 for i in range(im.shape[0])]
    
    # Likewise for the width
    b = [(i%2)==0 for i in range(im.shape[1])]
    
    # Now take alternate rows with numpy.compress()
    r = np.compress(a,im,0)
    
    # And now take alternate columns with numpy.compress()
    res = np.compress(b,r,1)
    

    Finally put res back in the original image, offset by half its width and height relative to where you cut it from.