0

I performed an image downsampling with averaging operation. The image is divided into 2 by 2 blocks, then it is downsampled by 4 times. New pixel values of the downsampled image are replaced with the mean of each block as follows:

img = imread('cameraman.tif');
avgfilter = fspecial('average', [2 2]);
avgimg = filter2(avgfilter, img);
down1 = avgimg(1:2:end,1:2:end);
imshow(down1);

I used a grayscale image as input. However, I'm getting a complete white image as output on downsampling. Why is this happening? Please help.

rayryeng
  • 102,964
  • 22
  • 184
  • 193
Celine
  • 115
  • 1
  • 5
  • 13
  • Maybe you have to increase the bit depth first? GIF is only 8 bits per pixel. – Mark Ransom Oct 04 '14 at 03:14
  • I tried with jpg also.Again getting the same output – Celine Oct 04 '14 at 03:16
  • @MarkRansom - The problem was the way the OP was trying to display the image. After using `filter2`, the output is of a `double` precision image where the intensities are expected to be within the range of `[0,1]` where the original image was of type `uint8`. The dynamic range of the intensities of the output image are well beyond `[0,1]` that when trying to visualize the image, the image looks saturated (a.k.a. all white). The OP needs to convert back to `uint8` to properly visualize the results. – rayryeng Oct 04 '14 at 04:38
  • @rayryeng I was just guessing, an answer from somebody who knows what they're doing is worth a lot more. I already gave you a +1. – Mark Ransom Oct 04 '14 at 04:40
  • @MarkRansom hahah thanks :) actually, that image name was a typo in the post (which I corrected). It should have been `cameraman.tif`. That is a built-in image that is part of the MATLAB environment's system path. I'm actually not sure why the OP decided to use GIF... Good deduction on the limited colour palette of GIF though. – rayryeng Oct 04 '14 at 04:41

1 Answers1

3

The reason why this is happening is because your average image after you use filter2 is a double type image. You're not the first person (and probably not the last person...) to experience this mixup with imshow. In fact, almost all of the problems that I have solved with regards to imshow here on StackOverflow is because of this small mixup with imshow.

You have to be cognizant of the type of image you are trying to display with imshow before you decide to use the function. Images of type double are expected to have its intensities / colour channels to be in the range between [0,1]. Anything below 0 is set to black while anything beyond 1 is set to white, which is why you are getting a completely white image.

You need to convert back to uint8 to properly display the image. As such, try doing this before you show your image:

down1 = uint8(down1);
imshow(down1);

When I do this, this is what I get when I show the downsampled image.

enter image description here


Minor comment

FWIW, when it comes to image filtering, I would personally use imfilter instead. imfilter is designed for image filtering where filter2 is for more generic 2D signals. One thing that is good about imfilter is that it will output an image of the same type where filter2 will default to double. I would stay away from filter2 unless you're forced to use it on images.

As such, replace your filter2 syntax with:

avgimg = imfilter(img, avgfilter);

If you do this instead, you don't need to cast your image back to uint8. You will be able to visualize the results properly with imshow.

rayryeng
  • 102,964
  • 22
  • 184
  • 193