How do I convert a DICOM file into RGB? - matlab

I'll explain my problem in Matlab. I have a multi-frame DICOM file, 70x70x50. I would like to convert it to RGB.
This is my code:
clear all;
close all;
clc;
% Lettura Dicom
img = dicomread('provaDICOM.dcm'); % 4-D int16
info = dicominfo('provaDICOM.dcm');
img2 = squeeze(img); % 70x70x50 int16
img3 = mat2gray(img2); % 70x70x50 double
% volumeViewer(img2);
% Conversione RGB
cmap = copper(256);
numslice = size(img3,3);
colored_MHA = zeros(size(img3, 1), size(img3, 2), numslice, 3);
for slice = 1 : numslice
colored_MHA(:,:,slice) = ind2rgb(img3(:,:,slice), cmap);
end
This is the error:
Unable to perform assignment because the size of the left side is 70-by-70 and the size of the right side is
70-by-70-by-3.
Error in Dicom (line 18)
colored_MHA(:,:,slice) = ind2rgb(img3(:,:,slice), cmap);

You need to reference an extra dimension on colored_MHA.
Try:
colored_MHA(:,:,:,slice) = ind2rgb(img3(:,:,slice), cmap);
More generally - the error is telling you that you're trying to put something big into something too small, and when you see this you can ask yourself why that is.

Related

How to read .tif style images from a directory

I am trying to run the following code to analyze multiple .tif images in several different directories. Upon running the code, the figures that are given are blank, followed by the error on line 49 "M must be provided for packed erosion". I first realized I spelt .tif as .tiff in the code, which I changed. Then I decided that I would just read off one .tif image by creating a Tiff object and wrapping the image path in the tiff object. The console threw an error, saying that the file was unable to be opened.
Code
%% Import Spheroid Directory
Path = 'C:\Users\18606\OneDrive\Documents\Spheroids For Brandon\Spheroids For Brandon\1-8WT';
if ~isfolder(Path)
errorMsg = sprintf('Error: The following folder does not exist:\n%s',Path);
uiwait(warndlg(errorMsg));
return;
end
%% Iterate over each subfolder with .tiff images
Content = fullfile(Path, '*.tif'); % Read Experiment directory with .tiff images
subFold = dir(Content);
imageFiles = []; % Create empty list array
for k = 1:length(subFold)
F = fullfile(Path, subFold(k).name); % For k subfolders, output the full file name and open each subfolder
fileID = fopen(F);
imageFiles{end+1} = fopen(fileID,'%s\n'); % Append fileID to imageFiles list
fclose(fileID);
end
disp(imageFiles(k)) % Display the image files for analysis
%% Image preprocessing
%Divide image "obj" into its respective RGB intensities
red = imageFiles(:,:,1);
green = imageFiles(:,:,1);
blue = imageFiles(:,:,1);
figure(1)
subplot(2,2,1); imshow(imageFiles); title('Original Image')
subplot(2,2,2); imshow(imageFiles); title('Red Plane')
subplot(2,2,3); imshow(imageFiles); title('Green Plane');
subplot(2,2,4); imshow(imageFiles); title('Blue Plane');
%Threshold the blue plane
figure(2)
level = 0.37;
bw2 = imbinarize(blue, level);
subplot(2,2,1); imshow(bw2); title('Blue plane threshold');
%% Image preprocessing continued
fill = imfill(bw2,'holes');
subplot(2,2,2); imshow(fill); title('Holes filled')
%Remove any blobs on border of image
clear = imclearborder(fill);
subplot(2,2,3); imshow(clear); title('Blobs removed');
%Remove blobs smaller than 7 pixels across
se = strel('disk',7);
open = imopen(fill, se);
subplot(2,2,4); imshow(open); title('Removed small blobs');
%% Measure the number of pixels in Image
%numberOfPixels = numel(inputFile);
%[pixelCounts, grayLevels] = imhist(inputFile);
%numberofPixels = sum(pixelCounts);
%% Measure the distance of migration in micromolars
diameter = regionprops(open, 'MajorAxisLength');
%Show result
figure(3)
imshow(imageFiles)
d = imdistline; %Includes a line to physically measure the object
Error Msg
>> RawData
Error using images.internal.morphop>ParseInputs
M must be provided for packed erosion.
Error in images.internal.morphop (line 23)
unpacked_M,mex_method] = ParseInputs(varargin{:});
Error in imerode (line 87)
B = images.internal.morphop(A,se,'erode',mfilename,varargin{:});
Error in imopen (line 73)
outputImage = imdilate(imerode(inputImage,se,'ispacked',M),se,'ispacked',M);
Error in RawData (line 49)
open = imopen(fill, se);
I have a hunch that the file path is being read incorrectly, but the program is reading something, otherwise it would have thrown the error specified in the code. I appreciate any help I can get on this matter.
There are many things in your code that don't make sense.
fileID = fopen(F);
imageFiles{end+1} = fopen(fileID,'%s\n'); % Append fileID to imageFiles list
This opens the file, then puts its file name in imageFiles{end+1}. This is the same as just doing imageFiles{end+1} = F, but more confusing.
Later, you use imageFiles as if it was an image:
red = imageFiles(:,:,1);
But it's not an image, it is a cell array with the names (with path) of a set of files!
imshow(imageFiles) will load the images in that array, and show them to you. But other than that, you never load the images, so all computations you do, you are doing on the names of the files rather than the pixel data.
You want to use imread to load the pixel data. Don't fopen the files, just imread them.

Wrong number of objects being returned

I have this MATLab code to count the number of objects in the image. There are two objects in the image I am choosing (a car and a cyclist). However, the program is returning a wrong output saying there are 0 objects. Can someone find the error in the code? Thanks.
The logic behind the code is:
1. Take two input images are given, one without objects and one with objects.
2. Convert the input images from RGB to Gray scale.
3. Compare the two images and find the difference.
4. Convert the image obtained to binary.
5. In the image, only open the blobs whose area is greater than 4000.
6. Display the count and density.
clc;
MV = imread('car.png'); %To read image
MV1 = imread('backgnd.png');
A = double(rgb2gray(MV)); %convert to gray
B= double(rgb2gray(MV1)); %convert 2nd image to gray
[height, width] = size(A); %image size?
h1 = figure(1);
%Foreground Detection
thresh=11;
fr_diff = abs(A-B);
for j = 1:width
for k = 1:height
if (fr_diff(k,j)>thresh)
fg(k,j) = A(k,j);
else
fg(k,j) = 0;
end
end
end
subplot(2,2,1) , imagesc(MV), title ({'Orignal Frame'});
subplot(2,2,2) , imshow(mat2gray(A)), title ('converted Frame');
subplot(2,2,3) , imshow(mat2gray(B)), title ('BACKGND Frame ');
sd=imadjust(fg); % adjust the image intensity values to the color map
level=graythresh(sd);
m=imnoise(sd,'gaussian',0,0.025); % apply Gaussian noise
k=wiener2(m,[5,5]); %filtering using Weiner filter
bw=im2bw(k,level);
bw2=imfill(bw,'holes');
bw3 = bwareaopen(bw2,5000);
labeled = bwlabel(bw3,8);
cc=bwconncomp(bw3);
Densityoftraffic = cc.NumObjects/(size(bw3,1)*size(bw3,2));
blobMeasurements = regionprops(labeled,'all');
numberofcars = size(blobMeasurements, 1);
subplot(2,2,4) , imagesc(labeled), title ({'Foreground'});
hold off;
disp(numberofcars); % display number of cars
disp(Densityoftraffic); %display number of vehicles
An empty image(of a road) with no objects(vehicles) in it
An image of the same road but with 2 objects(car and cyclist) in it
Try This it will help you in an optimize manner
clc
clear all
close all
im1 = imread('image1.png');
im2 = imread('image2.png');
gray1 = double(rgb2gray(im1));
gray2 = double(rgb2gray(im2));
absDif = mat2gray(abs(gray1 - gray2));
figure,imshow(absDif,[])
absDfbw = im2bw(absDif,0.9*graythresh(absDif));
figure,imshow(absDfbw,[])
absDfbw = bwareaopen(absDfbw,25);
absDfbw = imclose(absDfbw,strel('disk',5));
figure,imshow(absDfbw,[])
Results are:
Thank You

error while masking an image

I just want to threshold it before applying algorithm.i tried it in one algorithm and got perfect result.but here i considered binary image and then masking.i just want the intervertebral disc(ellipse portion) which is in between vertebrae .can you suggest any other method?
close all;
clear all;
%%
Img = imread('Sub.png');
Img=rgb2gray(Img);%convert to single channel as data do not contain color image
Img=im2bw(Img,.16);
fig1=figure;
subplot(221)
imshow(Img); title('Original Image')
m1 = uint8(Img>35);
subplot(222), imshow(m1,[]); title('Mask m1');
m2=uint8(Img<300);
subplot(223), imshow(m2,[]); title('Mask m2');
sd = stdfilt( double(Img), ones(3,3));
m3= uint8(sd<18);
subplot(224), imshow(m3,[]); title('Mask m3');
fig2=figure;
I = uint8(Img.* m1);
I = uint8(I.* m2);
I = uint8(I.* m3);
subplot(221), imshow(I);
title('Masked Img')
i'm getting error as
I cannot view mask1 , mask 2, mask3 and also I'm getting error
Error using .*
Integers can only be combined with integers of the same class, or scalar doubles.
Error in test1 (line 22)
corrected code is
close all;
clear all;
%%
Img = imread('Sub.png');
Img=rgb2gray(Img);%convert to single channel as data do not contain color image
Img=im2bw(Img,.16);
fig1=figure;
subplot(221)
imshow(Img); title('Original Image')
m1 = uint8(Img>35);
subplot(222), imshow(m1,[]); title('Mask m1');
m2=uint8(Img<300);
subplot(223), imshow(m2,[]); title('Mask m2');
sd = stdfilt( double(Img), ones(3,3));
m3= uint8(sd<18);
subplot(224), imshow(m3,[]); title('Mask m3');
fig2=figure;
Img(~m1)=0;
Img(~m2)=0;
Img(~m3)=0;
subplot(221), imshow(Img);
title('Masked Img')
There are probably multiple issues with the code. While applying a mask using multiplication is technically possible, I recommend to use indexing instead:
Img(~mask)=0;
This code sets every pixel which is not in mask to zero.
There is probably another issue with your code. You are using uint8 to get a uint8 image, but the function does not rescale. If you input a normalized double image (values between 0 and 1) you will end up with a black image because it contains only 0 and 1 values. Use im2uint8 to convert images, but I think what you are trying to do here could be done on the double image as well.

error while drawing several x-marks on a binary image in matlab

I am trying to draw several x-marks on a binary image to some co-ordinates.
My output should look like this
To do this i have written some codes below
clear all;
% Here four co-ordinates are provided as an example. In my main code the co- ordinates will be hundred or thousands
position{1}.x = 10;
position{1}.y = 10;
position{2}.x = 20;
position{2}.y = 20;
position{3}.x = 30;
position{3}.y = 30;
position{4}.x = 40;
position{4}.y = 40;
% Read image as binary
image = imread('test34.jpg');
figure('name','Main Image'),imshow(image);
gray_image=rgb2gray(image);
level = graythresh(gray_image);
binary_image = im2bw(image,level);
% Define color of the x-marker and initializing shapes which i want to draw
red = uint8([255 0 0]);
markerInserter = vision.MarkerInserter('Shape','X-mark','BorderColor','Custom','CustomBorderColor',red);
i = 1;
% The loop will continue to the number of co-ordinates which will never be predefined in my main code
while i<=numel(position)
% Converting binary to RGB for only once.
if i == 1
rgb = repmat(binary_image, [1, 1, 3]);
else
rgb = repmat(binary_image, [1, 1, 1]);
end
% Position where x-marks will be drawn
Pts = int32([position{i}.x position{i}.y]);
% Draw x-marks
binary_image = step(markerInserter, rgb, Pts);
i = i+1;
end
figure('name','binary_image'),imshow(binary_image);
But i am getting these errors
Error using images.internal.imageDisplayValidateParams>validateCData
(line 119)
If input is logical (binary), it must be two-dimensional.
Error in images.internal.imageDisplayValidateParams (line 27)
common_args.CData = validateCData(common_args.CData,image_type);
Error in images.internal.imageDisplayParseInputs (line 78)
common_args = images.internal.imageDisplayValidateParams(common_args);
Error in imshow (line 227)
[common_args,specific_args] = ...
Error in test2 (line 39)
figure('name','binary_image'),imshow(binary_image);
I have tried some examples but they are experimented on RGB image while i need it on binary image and that's where i am getting errors.
Why i am getting these errors and what will be the solution?
Please provide explanation with proper code.
You code seems a bit complicated (to me) for what it is intended. Here is a simple example demonstrating how to draw red crosses using scatter on a binary image. As you see, the image in itself is binary and the markers are in color, so the 'net' image is no longer binary... Also, there is no need to convert your RGB image to graylevels before applying im2bw.
And don't forget to use hold on to avoid discarding the image when adding the markers!
Here is the code with comments:
clear
clc
close all
%// Read image
MyImage = imread('peppers.png');
%// Convert to binary. No need to use rgb2gray.
MyBWImage = im2bw(MyImage(:,:,2));
%// Define some x- and y positions for markers
xpositions = linspace(10,300,40);
ypositions = linspace(20,500,40);
imshow(MyBWImage)
%// IMPORTANT!!
hold on
%// Draw markers
scatter(xpositions.',ypositions.',80,'r','x')
With output:
Is this what you meant?

problems with imshow() and rgb2gray() in MATLAB

Good afternoon,
when running the following code:
testImage = double(imread(testfile));
figure; imshow(testImage)
greyTestImage = rgb2gray(testImage);
figure; imshow(greyTestImage)
I get unclear and mostly blank Images, I was unable to fx it using the colormap. The following is teh original image and the two resulting figures:
1:
2:
3:
You have to know the format of the image you are trying to read. To make this sure, I always use the following piece of code in my programs when I want to convert user defined image from unknown format to uint8 grayscale :
% load image
[filename, pathname] = uigetfile({'*.*'},'image file');
fullFilename = [pathname filename];
% Get image info, read it accordingly
info = imfinfo(fullFilename);
if(strcmp('truecolor',info.ColorType))
I = imread(fullFilename);
Igray = uint8(rgb2gray(I));
clear I
elseif(strcmp('grayscale',info.ColorType))
Igray = uint8(imread(fullFilename));
elseif(strcmp('indexed',info.ColorType))
[I,map] = imread(fullFilename);
Igray = uint8(ind2gray(I,map));
clear I map
else
error('statPart:FormatImage','Image format error');
end
clear info
Also, this : testImage = double(imread(testfile)); won't work if you assume testfile is uint8 and want to convert it to double (in double intensity shall range from 0 to 1). You have to do testImage = double(imread(testfile)) / 255;
Hope this help.
Cheers
Have you tried converting to 8 bit unsigned integers?
testImage = double(imread('PEYXW.jpg'));
figure; imshow(uint8(testImage))
greyTestImage = rgb2gray(uint8(testImage));
figure; imshow(greyTestImage)
This is probably an issue with the image you are loading.
The input to the rgb2gray function needs to be a 3-channel color image (MxNx3 matrix for the R,G,B channels).
If you use a built-in Matlab sample image, you can effectively do:
imdata = imread('ngc6543a.jpg');
figure; imshow(imdata)
Then:
test = rgb2gray(imdata);
Actually, Matlab provides the function Im2double instead of double to convert images to double precison:
testImage = im2double(imread(testfile));
figure; imshow(testImage)
greyTestImage = rgb2gray(testImage);
figure; imshow(greyTestImage)
In double precision, image RGB values are between 0 and 1, for uint8 they range between 0 and 127. When you use the double function, all RGB values keep their value, but they are in double precision. This means that any RBG tiple with values >= 1 will result in a double >= 1 and thus produce a white space in your image.
im2doubleactually scales the values to the range [0 1].