I'm trying to show the negative of an image and as you know it has a very simple code.
This is the original image:
When I use the code:
Out = 255-img;
%Out = uint8(OutNeg);
imshow(Out);
The result will be:
But using the code:
OutNeg = 255-img;
Out = uint8(OutNeg);
imshow(Out);
Will make the right answer:
Now I am wondering
1 - what does the function uint8() does in fact?
2 - Do these codes make the same results? In fact what is the usage of uint8?
Code1:
img2 = uint8(img1);
imshow(img2);
Code2:
imshow(img1,[0 255]);
3 - Do I need to normalize the image before showing it with the following code?
img2 = 255/(max(max(img1))-min(min(img1)))*(img1-min(min(img1)));
Or using uint8 or [0 255] does the same thing and no need to normalize??
4- what is the difference between normalizing, using uint8 and using [0 255]??????
please consider transformations like Log and power-low in your answers.
From help imshow:
If your grayscale image is single or double, the default display range is
[0 1]. If your image's data range is much larger or smaller than the default
display range, you may need to experiment with setting the display range to
see features in the image that would not be visible using the default
display range. For all grayscale images having integer types, the default
display range is [intmin(class(I)) intmax(class(I))].
By making your data an 8-bit unsigned integer (uint8) array, the data is expected by imshow to be on [0 255]. RTM.
Related
I am trying to open a .pgm image file in MATLAB, run a manipulation with a for loop and then save as another .pgm file. Before doing the manipulation I was testing to see if I could recreate the image:
clear
picture = imread('Picture.pgm');
sizePic = size(picture);
sizeX = sizePic(1);
sizeY = sizePic(2);
newPicture = zeros(sizeX,sizeY);
for i = 1:sizeX
for j = 1:sizeY
newPicture(i,j) = picture(i,j);
end
end
imwrite(newPicture, 'NewPicture.pgm');
However, the new image is almost all white with some black splotches (not the original). Shouldn't this just give me back the original image?
By default, picture created from imread(XXX.pgm) is either a uint8 or uint16 array, meaning the pixel values are in the range of [0 255] or [0 65535]. On the other hand, newPicture created from zeros is a double array, the expected pixel value for which is only [0 1]. Any value greater than 1 will be interpreted as 1 (white) in the saved image. When you assign a [0 255] value to such a double array, since most of the pixel values in picture is 1 and above, of course you will get mostly white pixels
When you work with images, always check the type of the image array. For example, it may be a good idea to always work with double type by explicitly converting the image returned by imread as such:
pictures=im2double(imread(xxx)).
I am having 60 images of size 250x250x3 . Now I want to add it as a stack of images.
ie, I want to create a 4-D array, which holds all the images in the form of a mat file. So, it should be of size 250 x 250 x 3 x 60 .
I have tried the following. But when I displays the image it is full of white with some small marks only. This was the code .
X=zeros(250,250,3,60)
for i=1:60
X(:,:,:,i)=image1 and so on on every every loop.
Any way to create this mat.
The problem:
It seems like yout images are stored as uint8 type. When you pre-allocated your X you defined it as double (by default).
When Matlab displays an image there is a difference between a uint8 type image and double type image: for uint8 Matlab expects the intensities to range between [0..255]. However, when it comes to double type images Matlab expects the values to range between [0..1]. Thus, assigning uint8 image values to double type you have a double type image with values in the range [0..255] - which Matlab displays as white.
Solutions:
There are several ways you can solve your problem:
Define X as a uint8 type
X = zeros( [255, 255, 3, 60], 'uint8' )
This will save memory as uint8 takes single byte whereas double takes 8.
Alternatively, you can cast your images to double using im2double function that changes the data type and the range of intensities to [0..1].
I have a set of values between 0 and 1. After i put these values between 0 and 255 I want to save them as a grayscale image in pgm format. The problem is the fact that after I save it as an image the values i get when i read the image are different from the previous matrix with values between 0 and 255.
Here is an simple example:
>> a=[0.5,1,0.3]
a =
0.5000 1.0000 0.3000
>> b=single(floor(255 * a))
%these are the values I want in the image
b =
127 255 76
imwrite(b, 'test.pgm');
% i don't want these values!!!
c=imread('test.pgm')
c =
255 255 255
what's happening? why matlab does not save my values? is this a conversion issue?
what's happening? why matlab does not save my values? is this a
conversion issue?
Yes, it's conversion issue and is not needed. MatLab automatically does conversion for you.
Hence, try storing a instead of b
imwrite(a, 'test.pgm');
Quoting from documentation of imwrite
imwrite(A,filename)
If A is a grayscale or RGB color image of data type double or single,
then imwrite assumes the dynamic range is [0,1] and automatically
scales the data by 255 before writing it to the file as 8-bit values
EDIT
If you want to stick to manual conversion, you need to type cast as uint8
b = uint8(floor(255 * a))
I think the values you write should be integers.
Try b = uint16(floor(255 * a))
I am trying to plot a set of data in grayscale. However, the image i get seems to be always blue.
I have a set of data, albedo that ranges from [0, 0.068], which is a 1X1 double.
My code is:
for all px,py
albedoMax = 0.0679; albedoMin = 0;
out_im(px,py) = 1/(albedoMax-albedoMin)*(albedo - albedoMin);
imshow(out_im);
drawnow;
end
Basically px,py are the image coordinates that i have to iterate over, and the formula is trying to map the input range of [0, 0.068] to [0 1]. However, by running this code, i notice that the output is always blueish. I was wondering what went wrong.
Thanks for the help.
Can't you make use of the rgb2gray function?
What you are making is one layer of the RGB image.
If you are creating a homogeneous blue image with constant color then the normalization is wrong. But if it is just the matter of being blue instead of being gray then just convert it using :
ImGray = rgb2gray(Im);
Do not forget to distribute the pixels like a grid/mesh, to fill all the image not just a part of it.
I have a small problem in saving data in a array. I want to save data in the form 10001010 <- 8 bits in a 2d array containing 100 rows and 100 columns. what i do now is
a = rand(100,100);
a = a * 127; // <<- this is done to make it 8 bits
To confirm what i have done i did a imshow to display the image.
When a is multiplied by 127 most of the grayscale pixels has turned to white but before the multiplication step it showed a nice grayscale image.
a = rand(100,100); after a = a * 127;
If you want 8-bit representation it's actually 0->255 since image intensities are unsigned. Matlab checks which class the image is when using imshow, if it's a double, the range 0->1 is expected. Hence you need to cast the image to uint8 after multiplying for it to show properly.
a = rand(100,100);
a = a*255;
a = uint8(a);
imshow(a);