Reputation: 13
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
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.
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