Series of dicom images into specific format in matlab - matlab

I have series of matlab images which belong to a single patient. I found some code online, but it is sowing some error. I want something like this, Image
Here is the code I have.
% Preallocate the 256-by-256-by-1-by-20 image array.
X = repmat(int16(0), [256 256 1 20]);
% Read the series of images.
for p=1:20
filename = sprintf('brain_%03d.dcm', p);
X(:,:,1,p) = dicomread(filename);
end
% Display the image stack.
montage(X,[])
I found this code from here:
https://www.mathworks.com/company/newsletters/articles/accessing-data-in-dicom-files.html
Error using montage>validateColormapSyntax (line 339)
An indexed image can be uint8, uint16, double, single, or logical.
Error in montage>parse_inputs (line 259)
cmap = validateColormapSyntax(I,varargin{2});
Error in montage (line 114)
[I,cmap,mSize,indices,displayRange,parent] = parse_inputs(varargin{:});
Error in Untitled2 (line 9)
montage(X,[]);

The syntax for calling the montage function has changed since that code sample was written (back in 2002!). As noted in the comments section of the File Exchange submission for the sample DICOM data files, the new correct syntax is this:
montage(X, 'DisplayRange', []);
You were getting that error since the new syntax interprets montage(X, []); as if X were an indexed color image (which isn't allowed to be a signed int16 type, according to the error) with an empty color map [].

Related

How to make a GIF from a set of MATLAB images

I have an array of values which I turn into a color image like so:
my_img = imagesc(my_data(:,:,tidx)); axis off; colormap('default'); c=colorbar; c.FontSize=26; c.FontWeight='bold';
I want to know if it's possible to loop through all the index values in my_data and turn them into a GIF.
I tried this:
for tidx = 5:64
my_img = imagesc(my_data(:,:,tidx)); axis off; colormap('default'); c=colorbar; c.FontSize=26; c.FontWeight='bold';
imwrite (my_img, int2str(tidx)+"_cspattern.png");
end
Which gave me this error:
Error using imwrite (line 427)
Expected DATA to be one of these types:
numeric, logical
Instead its type was matlab.graphics.primitive.Image.
I looked it up and tried this solution out:
for tidx = 5:64
my_img = imagesc(my_data(:,:,tidx)); axis off; colormap('default'); c=colorbar; c.FontSize=26; c.FontWeight='bold';
IMG_to_write = uint8(normalize(my_img, 'range', [0 255]));
imwrite(IMG_to_write, int2str(tidx)+"_cspattern.png");
end
But that just gave me this error:
Error using normalize>checkSupportedArray (line 159)
Invalid data type. First argument must be a real numeric or logical array, a table or a timetable.
Error in normalize (line 86)
checkSupportedArray(A,method,methodType,false);
Error in GenerateFigures (line 18)
IMG_to_write = uint8(normalize(SavePattern, 'range', [0 255]));
I feel as if I am overthinking this because there must be a simple way to load the data I want and save it as an image or series of images.
imagesc produces a graphics object, not a data array. It’s meant for displaying images into figures, not saving them into files. You need to hand imwrite your image data directly, along with your desired color map.
for tidx = 5:64
imwrite(my_data(:,:,tidx),parula(),int2str(tidx)+"_cspattern.png");
end
If you want to scale each image so that the full color range is used, the way imagesc does, you can do this manually.
for tidx = 5:64
my_data_slice = double(my_data(:,:,tidx));
my_data_slice = my_data_slice - min(my_data_slice,[],'all');
my_data_slice = my_data_slice / max(my_data_slice,[],'all')*255;
my_data_slice = uint8(my_data_slice);
imwrite(my_data_slice,parula(),int2str(tidx)+"_cspattern.png");
end

Reading frame after converting Matlab pdollar toolbox code to Octave

I want to read a video using pdollar toolbox. I have few video files upon whom I am trying to apply the acfDetect classier. However, I don't get the correct output. On checking, I found that the data of the frame (the matrix) do not match, for Matlab and Octave. The question will be clear with the attached pics. I tried to print the value of the frame and this is what I get:
Matlab output:
Octave output:
As a hit an trial, I saw that multiplying Octave values by 255 (RGB max) gives me an approx to the Matlab values. But when I do so, I get the following error:
> >> runonVideos
processing 11-50-48--11-50-58_resized.mp4 ...
error: rgbConvertMex: For floats all values in I must be smaller than 1.
error: called from
rgbConvert at line 80 column 2
chnsPyramid at line 133 column 2
acfDetect_modified>acfDetectImg at line 74 column 2
acfDetect_modified at line 41 column 19
pedestrianDetection at line 33 column 11
runonVideos at line 8 column 5
Essentially, Matlab gets the same value (0-255) but doesn't give any such error for the function stated here: rgbConvertMex.I am unable to understand where exactly is the problem.
If I am able to get the same value as in Matlab, my problem will be solved to a large extent.
The Octave code is here:
> % Output text file
outFile = fopen(['C:\devwork\matlab\boosted\detection\',videoFname(1:end-4),'_detections.txt'],'w+');
% videoPlayer = vision.VideoPlayer;
vObj = VideoReader('C:\devwork\matlab\boosted\resizedVideos\11-50-48--11-50-58_resized.mp4');
%fprintf vObj;
% videoFwriter = vision.VideoFileWriter('result3_newAnnLdcf+.mp4','FileFormat','MPEG4','FrameRate',vObj.FrameRate);
tic
while hasFrame(vObj)
frame = readFrame(vObj);
%fprintf(frame);
% frame = imresize(frame,0.5);
bbs = acfDetect_modified(frame,detector);
% displayFrame = frame;
bbs = bbs(:,1:4);
bbs = round(bbs);
% if ((bbs(1,:) >= 1152) || (bbs(2,:) >= 648))
% disp('BB exceeds bounds')
% disp(bbs)
% end
% displayFrame = insertShape(displayFrame,'Rectangle',bbs,'LineWidth',2,'Color','red');
fprintf(outFile,'%d ',reshape(bbs,numel(bbs),1));
fprintf(outFile,'\n');
% videoPlayer.step(displayFrame);
% step(videoFwriter,displayFrame);
end
toc
fclose(outFile);
fprintf('done \n');
% release(videoPlayer);
% release(videoFwriter);
end
Edit 1: In Matlab, I tried changing v=v*255 to v=uint8(v)
But now I get all values as either 0 or 1.
Edit 2:
Screenshot of the code:
Screenshot of the output:
Edit 3: As suggested, code line 31 in Octace was changed to:v=uint8(v*255);
This does give result in integers but they are still not same as that of Matlab. I am guessing it must be some issue with my multiplication factor of 255. But this is still not resolved.
Screenshot of the new output:
The function you're looking for is im2uint8, which is provided by the image package.
This can take an input of class double in the range [0,1] and convert it to a uint8 image, with corresponding values in the range [0,255] accordingly.

MATLAB - error using imtransform()

I got an error when trying to run the imtransform() line in my code. I got:
Error using imtransform>parse_inputs (line 438)
XData and YData could not be automatically determined.
Try specifying XData and YData explicitly in the call to
IMTRANSFORM.
Error in imtransform (line 265)
args = parse_inputs(varargin{:});
Error in main (line 9)
newImage = imtransform(rgbImage,tf); %# Transform the image
I used the function tf = maketform() to generate the transformation itself.
So, in order to figure out what wrong with my code i simplified as much as I can the function:
function U = fisheye_inverse(X)
U = X;
end
and my code looked like this:
rgbImage = imread('IMG-20150622-WA0046.jpg'); %# Read the image
tf = maketform('custom',2,2,[],... %# Make the transformation structure
#fisheye_inverse,options);
newImage = imtransform(rgbImage,tf); %# Transform the image
imshow(newImage);
and still the code yell at me this error again.
I looked at a similar problem Here that posted here in the past, but no one answer the question in the end.
Thanks in advance, Gal :)

Using imfreehand within your program

For instance, I start my program as follows reading some image:
I=input('image name: ','s');
img=double(imread(I));
I'm planning to work only on some portion of that image. So, I noticed that I may need h=imfreehand for this purpose.
Thus, I have inserted h=imfreehand under the two lines above. What I got is a white screen. So, how can I get the image and select the region I want? The other thing is, how can I tell my program to work only on that region I have selected?
Thanks.
UPDATE
I did the following in a portion of my code:
figure, imshow(img);
h = imfreehand;
position = wait(h);
% post processing
se=strel('disk',3);
erosion=imerode(h,se);
result_image=imsubtract(h,erosion);.
But, I got the following error:
Error using imerode
Expected input number 1, IM, to be one of these types:
numeric, logical
Instead its type was imfreehand.
Error in morphop>CheckInputImage (line 335)
validateattributes(A, {'numeric' 'logical'}, {'real' 'nonsparse'}, ...
Error in morphop>ParseInputs (line 166)
A = CheckInputImage(A, func_name);
Error in morphop (line 14)
[A,se,pre_pad,...
Error in imerode (line 123)
B = morphop(A,se,'erode',mfilename,varargin{:});
Error in program (line 155)
erosion=imerode(h,se);
Is it to do with erosion? What can be done in this case?
`
Following the advice in the matlab documentation try this:
I=input('image name: ','s');
img=imread(I);
figure, imshow(img);
h = imfreehand;
position = wait(h);
Edit:
The documentation suggests as an alternative
figure, imshow(img);
h = imfreehand(gca);
Try passing the handle of the plot to imfreehand()
I=input('image name: ','s');
img=double(imread(I));
figure;
ih=image(img);
h=imfreehand(ih)
Sorry, I don't have the image processing toolbox to test this.
Seems like converting your image (possibly uint8) to double causes a problem.
I would either do:
use the original coding of the image (for example img_uint8 = imread('coins.png') is coded using integers). The problem is that you won't probably be able to use imfreehand as it needs to read double or single precision float.
convert the image using img_double = double(imread('coins.png')) so that imfreehand will work. The conversion however causes a display problem that you can bypass with imshow(img_double,[]) that is an analogue of imshow(img_double, [min(min(img_double)), max(max(img_double))]). It forces imshow to correctly use the full range of data (255 Vs. 255.0)
The best option is therefore the second one.
To use imfreehand, #Try Hard gave a nice code h = imfreehand or h = imfreehand(gca)

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.