Resampling an image of Unequal Dimensions - matlab

I have an 3d image of dimensions(182 x 218 x 182).
How could I downsample this image in MATLAB to an image of equal dimensions (like 128 x 128 x 128)?

Try this:
im=rand(2,3,4); %%% input image
ny=3;nx=3;nz=5; %% desired output dimensions
[y x z]=...
ndgrid(linspace(1,size(im,1),ny),...
linspace(1,size(im,2),nx),...
linspace(1,size(im,3),nz));
imOut=interp3(im,x,y,z);
I stole this answer from resizing 3D matrix (image) in MATLAB

Related

Matlab change a set of images to 2D grayscale but error occur

I was trying to turn a set of images to 2D grayscale image in order to do Surf feature extraction. In the set, some of the images are already in 2D scale so when I tried to run a loop.
This error message happens:
MAP must be a m x 3 array.
Here is my code:
for ii=1:numImages
img = readimage(imdsTrain,ii);
RGB = rgb2gray(img)
points = detectSURFFeatures(RGB);
[surf1, valid_points] = extractFeatures(RGB, points);
figure; imshow(RGB); hold on;
plot(valid_points.selectStrongest(10),'showOrientation',true);
title ('Ct-scan image with Surf feature')
end;
Is there any solution that can solve this problem?
Matlab's rgb2gray will fail if you give it a grayscale image (an image with only one color channel).
If you are sure that your images are either m x n X 3 or m x n x 1, you could check for the m x n x 3 case before attempting to do the rgb2gray. If your image is already a grayscale image no conversion is needed or can be done via rgb2gray.
Something like this:
img = readimage(imdsTrain,ii);
[rows, columns, colors] = size(img)
if colors > 1
RGB = rgb2gray(img)
end
Now getting the error MAP must be a m x 3 array suggests that whatever you supplied rgb2gray got interpreted as a colormap. So I would check if all your images are indeed three dimensions, as you are assumimg.

How can I make a synthetic image in MATLAB?

I am using MATLAB 2015b to make a synthetic image as following (without green circle)
It maybe hard to make the star image for me. Hence, I used a simple shape as square as below code. However, I cannot create similar intensity as example image. If it is possible, would you help me to make the image? I think that the image has two components: intensity following Gaussian distribution and inhomogeneous intensity. Thank all
%% Gray image
rows = 256;
columns = 256;
grayImage = ones(rows, columns, 'uint8').*200;
xCoords= [80 180 180 80 80];
yCoords = [80 80 180 180 80];
mask = poly2mask(xCoords, yCoords, rows, columns);
grayImage(mask) = 80;
%% First component Gray+noise
im_normal=double(grayImage./max(grayImage(:)));
im_noise= imnoise(im_normal,'gaussian',0,0.02);
%% Second component: Inhomogeneous term
X = 1:rows; % X is a vector from 1 to imageSize
X0 = (X / rows) -0.2; % rescale X
Xm = meshgrid(X0, X0); % 2D matrices
%% Output image
Out_Img=im_noise.*Xm;
subplot(121);imshow(grayImage);
subplot(122);imshow(Out_Img,[]);
This is my current result
I would try the following approach:
Find an approximation for the homogeneity field of the star image using gaussian blur:
homogeneity = imfilter(I,fspecial('disk',15),'replicate');
subtract the homogeneity field from the input image.
Segment the star shape manually
Calculate the histogram of the star using imhist function and the segmentation mask from previous stage. Divide it by the sum of the histogram. Thus you will get the probability vector which represents the star.
do the same thing with the background - calculate the probability vector which represents the background.
when generating the output:
a. for each pixel inside of the square, generate a grayscale value randomly, using the probability vector from stage 2.
b. for each background pixel, generate a grayscale value randomly using the probability vector from stage 3.
c. finally - add the homogeneity field from stage 1 to your result.

How to concatenate 3 histograms on the same graph in Matlab

I have calculated 3 histograms for an rgb image using imhist function in Matlab, one for each channel. I want to plot these histograms on the same graph, where for instance, the histogram for the first (red) channel stretches on the x axis from 0 to 255, the histogram for the second channel stretches from 256 to 511, and finally the histogram for the third channel stretches from 512 to 767.
How can I do this?
Assuming uint8 precision, each call to imhist will give you a 256 x 1 vector, and so you can concatenate these together into a single 768 x 1 vector. After, call bar with the histc flag. Assuming you have your image stored in im, do this:
red = imhist(im(:,:,1));
green = imhist(im(:,:,2));
blue = imhist(im(:,:,3));
h = [red; green; blue];
bar(h, 'histc');
As an example, using the onion.png image that's part of the image processing toolbox:
im = imread('onion.png');
This is what the image looks like:
Using the above code to plot the concatenated histogram produces this graph:

Loop through a 3d vector in Matlab

I've a 3D vector holding images in Matlab, its 480x640x1400. I want to loop through the 1400 images. For I want to get the median of the first 10 images (from 1-->10) and save it as a one 480x640 image then get the images from 2-->11 and get the median and save it as another image and so on (3-->12)....
So for example:
images is the 3D vector holding images with size 480x640x1400
images2 is the required 3D vector holding the median of the images with size 480x640x1400.
This is the script I'm using:
l=dir('*.mat');
filenames={l.name}';
nfiles=length(filenames)
idx=1;
strtidx=1;
endidx=nfiles;
step=1;
waitbar(0);
for i=strtidx:step:1
tmp = load(filenames{i},'images');
idx=1;
for j=strtidx:step:1000
for k=j:step:j+9
tmp2(k)=tmp(:,:,k);
end
mm=median(tmp2,3);
images2(j)=mm;
end
save(filenames{i}, 'images2', '-append');
waitbar(i/nfiles);
close all;
end
Assuming you have a matrix with the dimensions you described called Images. Firstly it could be a normal matrix of images, or a cell matrix. Are these colour images? Secondly you only have 1400 images, not 1401, Matlab indexes from 1 not from 0.
If it is a normal array of single channel images (i.e. greyscale) then you want this:
for imageNumber = 1:size(Images,3)-9 %loop along the third dimension
NewImages(:, :, imageNumber) = findMedian(Images(:,:,imageNumber:imageNumber + 9)) %findMedian is your own function that you must write that outputs the median of 10 images as a 480 x 640 matrix.
end

Interpolating along the 2-D image slices

I have a set of 100 2-D image slices of the same size. I have used MATLAB to stack them to create a volumetric data. While the size of the 2-D slices is 480x488 pixels, the direction in which the images are stacked is not wide enough to visualize the volume in different orientation when projected. I need to interpolate along the slices to increase the size for visualization.
Can somebody please give me an idea or tip about how to do it?
Edit: Anotated projected microscopy-images
The figure 1 is the top-view of the projected volume.
The figure 2 is the side-view of the projected volume.
When I change the rotation-angle, and try to visualize the volume in different orientation, e.g. side-view (figure 2), is what I see as in figure 2.
I want to expand the side view by interpolating along the image slices.
Here is an adapted example from the MATLAB documentation on how to visualize volumetric data (similar to yours) using isosurfaces:
%# load MRI dataset: 27 slices of 128x128 images
load mri
D = squeeze(D); %# 27 2D-images
%# view slices as countours
contourslice(D,[],[],1:size(D,3))
colormap(map), view(3), axis tight
%# apply isosurface
figure
%#D = smooth3(D);
p = patch( isosurface(D,5) );
isonormals(D, p);
set(p, 'FaceColor',[1,.75,.65], 'EdgeColor','none')
daspect([1 1 .5]), view(3), axis tight, axis vis3d
camlight, lighting gouraud
%# add isocaps
patch(isocaps(D,5), 'FaceColor','interp', 'EdgeColor','none');
colormap(map)
MATLAB has a function interp3 that can be used for interpolation, assuming that the data is uniformly discretised.
Check out the documentation.
Hope this helps.
EDIT: The MATLAB function interp3 works as follows:
vi = interp3(x, y, z, v, xi, yi, zi);
I assume that your "stack" of slices defines the arrays x, y, z, v as 3D arrays, where x, y are the coordinates of the pixels in the plane, z is the "height" of each slice and v is the actual image slices, maybe as "intensity" values for the pixels.
If you want to interpolate new image slices at intermediate z values you could specify these levels in the zi array. The arrays xi, yi would again represent the coordinates of the pixels in the plane.
I created a function to interpolate along image slices. Below is the code:
function res = interp_along_slices( vol, scale )
% Interpolation along the image slices
% Get the size of the volume
[r c p] = size(vol);
% Pre-allocate the array:
% the third dimension is scale times the p
vol_interp = zeros(r,c,scale*p);
% interpolate along the image slices
for inr = 1:r;
for jnr = 1:c;
xi = vol(inr,jnr,:);
vol_interp(inr,jnr,:) = interp(xi, scale);
end;
end;
res = vol_interp;
end