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))
Related
I have a 3D image and a mask, both size [256x256x160]. The mask is a binary image of 0 and 255. After applying the mask on the image like so:
masked_image = image.*mask;
I get a masked_image that has totally wrong intensity values. In fact, its values are nowhere to be found on the original image. They are just too big. All I want to achieve is extract the original image's intensities at the location of the mask and calculate the mean value of that ROI. I can see from imshow that the mask is aligned properly on the image. However, applying the mask is unsuccessful and I don't understand why.
Your mask shouldn't be scaled from 0 to 255. It should contain only 0 or 1 to use it the way you want. Any one of these alternatives would work:
masked_image = image.*logical(mask);
% Or...
masked_image = image.*(mask > 0);
% Or...
masked_image = image.*(mask./255);
Converting the mask to 0 and 1 rather than 0 and 255 solved the problem.
The extracted ROIs now have the correct intensity.
Thanks for the clarification.
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.
I have an image which I want to use it in MATLAB. But, I am looking for a method by which I be able to automatically find that my image is binary (0 and 1) or continuous. Is there any solution of piece of code?
For starters you cannot formally talk about binary or continuous images. Digital images have a discrete set of values, taken from a finite value set depending on their format and pixel bit-wise representation.
For example a "binary" image would have 2 levels of gray (white and black), represented by 0 or 1 or any other combination of values, e.g. an image of levels 0, 255 is still "binary". A grayscale image for an 8-bit representation (i.e. 8 bits per pixel) will have 2^8 discrete levels of intensity from min 0 (black) to max 255 (white).
Thus you can test for the number of unique levels of gray, i.e. unique values in your input image:
I = imread(image_filename);
if length(unique(I))==2,
flag_binary = true
end
Examples:
I = imread('cameraman.tif');
>> disp(flag_binary)
0
I = imread('circles.png');
>> disp(flag_binary)
1
From your question I'm guessing you are dealing only with images of the logical or double class. The first should be used for real binary images but unfortunately, that's not always the case when using code out in the wild.
It seems to me your problem is to distinguish between a real image of double class (all values between 0 and 1) or a binary image as class double (all values are 0 or 1). The best way to do it is the following which returns true if the image only has the values 1 and 0:
bool = all ((image(:) == 1) + (image(:) == 0));
This is a line from isbw() in Octave image package where you can use isbw (img, "non-logical")
Calculate the histogram using imhist. If there are more than two distinct grayvalues in the histogram your image is not binary.
I have a double matrix in matlab and I want to convert it to an HSV image where supposedly similar double values will appear with same color. I already converted to RGB with mat2gray but I want to to convert directly from double matrix to hsv image. Is it possible?
Thanks
You're asking if you can do what image and imagesc do. Yes, you can. You just need to interpolate into the 'hsv' colormap. The following code snippet demonstrates how to do this. It assumes your values are scaled between 0 and 1; you can easily change that though.
im = [0 .5 1; .7 .6 .2; .9 .3 .4];
cm = colormap('hsv');
cdata = interp1(linspace(0,1,length(cm)),cm,im);
figure;image(cdata)
cdata will be a (row x col x 3) matrix, you can use image directly to see it, or do whatever else you need to from there.
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);