Rishi
Rishi

Reputation: 13

imshow() not showing changed pixel values

I converted a RGB iamge to gray and then to binary. I wanted that the white pixels of binary image be replaced by pixel value of gray image. Though the command window shows that all 1s are replaced with gray pixel value but same is not reflected in the image. The binary image (bw) and the new image (newbw) looks exactly. Why so ?

clc;clear all;close all;
i = imread('C:\Users\asus\Documents\Academics 2014 (SEM 7)\DIP\matlabTask\im1.jpg');
igray = rgb2gray(i);
bw = im2bw(igray);
[m,n]=size(bw);
newbw = zeros(m,n);
for i=1:m
 for j=1:n

    if bw(i,j)==1         
        newbw(i,j)=igray(i,j);  

    else
        newbw(i,j)=bw(i,j); 
    end
 end
end

subplot(311),imshow(igray),subplot(312),imshow(bw),subplot(313),imshow(newbw)  

Upvotes: 1

Views: 400

Answers (1)

rayryeng
rayryeng

Reputation: 104464

The reason why is because when you are creating your new blank image, this is automatically created as double type. When doing imshow, if you provide a double type image, the dynamic range of the pixel intensities are expected to be between [0,1] where 0 is black and 1 is white. Anything less than 0 (negative) will be shown as black, and anything greater than 1 will be shown as white.

Because this is surely not the case in your image, and a lot of the values are going to be > 1, you will get an output of either black or white. I suspect your image is of type uint8, and so the dynamic range is between [0,255].

As such, what you need to do is cast your output image so that it is of the same type as your input image. Once you do this, you should be able to see the gray values displayed properly. All you have to do now is simply change your newbw statement so that the variable is of the same class as the input image. In other words:

newbw = zeros(m,n,class(igray));

Your code should now work. FWIW, you're not the first one to encounter this problem. Almost all of my questions that I answer when using imshow are due to the fact that people forget that putting in an image of type double and type uint* behave differently.


Minor note

For efficiency purposes, I personally would not use a for loop. You can achieve the above behaviour by using indexing with your boolean array. As such, I would replace your for loop with this statement:

newbw(bw) = igray(bw);

Whichever locations in bw are true or logical 1, you copy those locations from igray over to newbw.

Upvotes: 2

Related Questions