Changing colorspace in MATLAB - matlab

I'm trying to convert RGB color space to lαβ in MATLAB.
I tried running the script, I'm getting a rather different type of error.
>> C = makecform('srgb2lab')
C =
struct with fields:
c_func: #applycformsequence
ColorSpace_in: 'rgb'
ColorSpace_out: 'lab'
encoding: 'double'
cdata: [1×1 struct]
>> C(HCC1)
Array indices must be positive integers or logical values.
HCC1 is a tiff image loaded from my local PC. To add I'm using the online version of MATLAB.
EDIT: https://entuedu-my.sharepoint.com/:i:/g/personal/bchua024_e_ntu_edu_sg/Ee74d3QJH0FGk5OivZDobx0B9qrwOaNqVx8xnCJW20uxPQ?e=SCaouY
here's the link to the image I'm trying to convert.

I believe you are expected to apply this "cform" object using applycform()
Documentation for makecform shows this example:
rgb = imread('peppers.png');
cform = makecform('srgb2lab');
lab = applycform(rgb,cform);

Related

Making a copy of an image via a Loop not working

Idk why the code won't work. All it does is give me a blank white image. And if you don't declare a matrix before by zeros(x, y) then it works fine. Wth is wrong here?
I tried not declaring the zeros matrix before and only that works. I even tried doing img2(i,j) = img2(i,j)+img1(i,j)
function [imgOut] = scaleLoopBased(img,s)
%UNTITLED4 Summary of this function goes here
% creating a zero matrix of the given scale
[rows,columns]=size(img);
imgTemp=zeros(rows, columns);
for i=1:rows
for j=1:columns
imgTemp(i, j) = img(i, j);
end
end
imshow(imgTemp);
imgOut = imgTemp;
end
Blank white image
This is a result of your new image (of type double, what zeros creates by default) not having the same type as your original image (typically type uint8). You can fix this by initializing your new image to have the same data type as the original using the class function and passing an additional argument to zeros:
imgTemp = zeros(rows, columns, class(img));
The reason it works correctly when you don't initialize imgTemp is because MATLAB initializes the variable for you using the data type of img by default when you perform the first indexed assignment.
The imshow utility expects one of the standard image types in MATLAB. An image of type double is expected to have values spanning the range [0 1], while images of type uint8 will have values in the range [0 255]. In your example you likely have a matrix imgTemp that is of type double but has values spanning [0 255]. Another way to fix your issue is to explicitly tell imshow what value range to use for the display (since the default [0 1] doesn't work):
imshow(imgTemp, [0 255]);
Always be aware of the data type when manipulating or processing images. You may need to scale or convert back and forth, using a double type for calculations (since integers saturate) and a uint8 type for display and reading/writing to files.

Convert a Matrix of doubles to a grayscale .tif image

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
...

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!

Storing two variables image in one variable in matlab

I have an RGB image which I converted into index image using rgb2index. The resultant image is stored in two variable (as matlab requirement). But I want to have it in one variable for further processing. This is what I have tried. The resultant is black.
clc
clear all
close all
%%
I = imread ('Daniel1_SRGB.png');
[in_I,map] = rgb2ind(I,3,'nodither');
imshow (in_I,map)
imwrite (in_I,map,'new_image.PNG','png')
new_I = imread ('new_image.png');
imshow((new_image));
But if do imshow((new_image,map)) it gives me the correct answer. I want it to be independent of variable map.
To convert a indexed image to RGB use:
new_I = ind2rgb(in_I,map)
Not the most elegant solution but this works.
resR = reshape(map(in_I(:)+1,1), size(in_I));
resG = reshape(map(in_I(:)+1,2), size(in_I));
resB = reshape(map(in_I(:)+1,3), size(in_I));
res = cat(3, resR, resG, resB);
imshow(res);
Edit: Modified answer to include rayryeng's improvement.

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.