Convert a Matrix of doubles to a grayscale .tif image - matlab

I have an nCol by nRow matrix of doubles that I want to convert into an nCol by nRow grayscale images of pixels. I don't want to cut this down to an image scaled to 256 channels. I'd be happy with using singles instead of doubles. I've looked through the Tiff class documentation from Mathworks but can't find a simple example for this.

I tried to read about Tiff class and yep it is very poor documented. But I found this going through trial and error:
lets say we have matrix
data = rand(100,200);
Lets save it as Tiff:
t = Tiff('new.tif','w') %create object of Tiff class
setTag(t,Tiff.TagID.ImageLength,size(data,1)) %define image dimentions
setTag(t,Tiff.TagID.ImageWidth,size(data,2))
setTag(t,'Photometric', Tiff.Photometric.MinIsBlack) %define the color type of image
%specifies how image data components are stored on disk
setTag(t,'PlanarConfiguration',Tiff.PlanarConfiguration.Chunky);
setTag(t,'BitsPerSample',64); %because 1 double = 8byte = 64bits
%Specify how to interpret each pixel sample (IEEEFP works with input doubles)
setTag(t,'SampleFormat',Tiff.SampleFormat.IEEEFP);
t.write(data)
t.close
Lets test this now:
datac = imread('new.tif')
whos datac
Name Size Bytes Class Attributes
datac 100x200 160000 double
And:
datac(:,1)
ans =
0.4921
0.6908
0.1544
0.4433
...

Related

Save concatenated images in MATLAB

I am trying to concatenate two 256x256 images and save them using imwrite. The saved image is supposed to be 256x512, but when I load the saved image, the size shows to be 343x434x3. How do I solve this?
the code I am using is:
new_name3 = strcat(f_name_image, '\', kk, '_', num2str(ff), '_pair.png');
pair = [orig_im noisy_image]; %concatenating two 256x256 images
imagesc(pair)
f = getframe(gca);
im = frame2im(f);
imwrite(im, new_name3);
Saving the image from the frame can be lossy without configuring additional options. To retain the pixel information save the concatenated image directly from the pair (here Image_Pair) array. Also, the third dimension in 343x434x3 represents the RGB colour channels of the image.
%Grabbing the two images%
Image_1 = imread('Image_1.jpeg');
Image_2 = imread('Image_2.jpeg');
%The file name for the concantenated images%
New_File_Name = "Image_3.jpeg";
%Concatenating the images%
Image_Pair = [Image_1 Image_2];
%Displaying the image pair%
imshow(Image_Pair);
%Saving the image to the "New_File_Name"%
imwrite(Image_Pair, New_File_Name);
%Loading the saved image to see if dimensions are consistent%
Saved_Image = imread('Image_3.jpeg');

How can I imwrite a double in Matlab?

I am producing 3500x7500 size double matrices in a loop that I want to export as tif files.
A section of the code
for k = 1:length(basinlist{1})
#some operation that produces GRID
imwrite(GRID,filename);
end
But, when I do this, the TIF file produced contains only 255 and output is in uint8. I read about it in the documentation, but I am not able to fix it. All I want is to retain the original values with no scaling or anything.
If this helps:
>> max(max(GRID))
ans =
1.5646e+04
>> min(min(GRID))
ans =
1.1119e+03
Suppose we want to create image with such colour depth that will fit to given data.
Data exported to image format are converted to uint8 by default (data range 0-2^8-1).
But Matlab (2011b) can operate with more uintX formats where X stands for X bits per value.
uint8 with span 0-255 (2^8)
uint16 with span 0-65 535 (2^16)
uint32 with span 0-4.29 e 9 (2^32)
uint64 with span 0-1.84 e 19 (2^64)
Code to export data without any loss:
for k = 1:length(basinlist{1})
#some operation that produces GRID
%% Convert GRID to roughest acceptable uint format
GRID=uint16(GRID);
%% Export
imwrite(GRID,filename);
end

How to convert nii format file into 2D image

I have a file with .nii extension. I don't know how to convert a .nii file into 2D format.My question is while converting .nii file into 2D, am I losing some information about the file.Which format is good? dicom or png or bmp.
nii = load_nii('im.nii');
size(nii.img);
returns
ans =
39 305 305
and it is in uint8 format
May I use squeeze or resize?How to apply resize to this image;whether it lose information?
Yes you can manipulate the image/sequence as you would with any array.
Here is a simple example with data available from the NIH here.
The data set is in 4D and is named "filtered_func_data.nii".
Let's load the dataset and access the img field of the resulting structure:
S = load_nii('filtered_func_data.nii')
Here, S is a structure with the following fields:
S =
hdr: [1x1 struct]
filetype: 2
fileprefix: 'filtered_func_data'
machine: 'ieee-be'
img: [4-D int16]
original: [1x1 struct]
And we can access the image data with the field img (you already figured that out):
A = S.img
If we check the size, we get:
size(A)
ans =
64 64 21 180
So the dataset consists in 64x64 images with a depth/number of slices of 21 and a number of frames of 180.
At this point we can manipulate A as we like to reshape, resize or anything.
Here is a simple code (animated gif) to loop through each slice of the 1st timepoint in the 4D array:
NumSlices = size(A,3)
figure(1)
filename = 'MRI_GIF.gif';
for k = 1:NumSlices
imshow(A(:,:,k,1),[])
drawnow
frame = getframe(1);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
if k == 1;
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append');
end
pause(.1)
end
Output:
Which looks pretty nice to me.
So in your case, you get a size of [39 305 305] and you can apply the same manipulations I did to play around with your data set, which is in 3D.
EDIT
With your data it's the same:
S = load_nii('Subject01.nii');
A = S.img;
NumSlices = size(A,3);
And then, if you want a 2D image you need to select a slice in the 3D array.
For example, the first slice is accessed like so:
A(:,:,1)
And so on for the rest.
To save images as png, use imwrite.
Hope that helps!

Matlab is opening a pgm image with different values using imread

I have a pgm image with 1251 different pixel values, ranging from 0 to 1250. I know this because I can open this image file with kate and see the values.
But when I open the same file using Matlab's imread, it also returns me 1251 different pixel values, but these values are not consecutive. The minimum value is 0 and the maximum value is 65483.
I want to iterate through these values in a for loop so I need to read the original and consecutive values as they exist in the file. How to do that in Matlab?
EDIT: That's the image if someone wants to try.
image
The values are scaled so that when you view the image it's not mostly black.
I tested that the scaling works with straight integer truncation by checking that:
[A] = imread( 'myfile.pgm', 'pgm' );
p = sort(unique(A(:));
q = uint16((0:1250) * 65535 / 1251)';
all(p == q) % returns 1
So, you can restore the image like this:
map = arrayfun( #(x) uint16(x * 1251 / 65536), 0:65535 );
B = arrayfun( #(x) map(x+1), A );

Matlab rgb2hsv dimensions

I am reading in the matlab documentation that rgb2hsv will return an m-by-n-by-3 image array, yet when I call it, I get a 1-by-3 vector. Am I misunderstanding something?
Here is an sample code:
image_hsv = rgb2hsv('filepath')
and as output
image_hsv =
0.7108 0.3696 92.0000
You cannot call rgb2hsv on a filepath - it must be called on a MATLAB image matrix. Try:
image_rgb = imread('filepath'); % load the image array to MATLAB workspace
image_hsv = rgb2hsv(image_rgb); % convert this array to hsv
You can see these matrices with:
>> whos image* % display all variables whose name begins with 'image'
Name Size Bytes Class Attributes
image_hsv 480x640x3 7372800 double
image_rgb 480x640x3 921600 uint8
What your original code was doing was converting your filepath string to ascii numbers, taking the first three values of this array as RGB values and converting these to HSV.
NOTE: This example highlights dangers with MATLAB's weak typing system, where data types are silently converted from one type to another. Also maybe a lack of correct input checking to the rgb2hsv function.