How do I plot the intensity profiles of a sequence of images?
5 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
I have a sequence of over 200 images of a light beam. I need to plot the 3-D intensity profiles of each image as a sequence so I see how the profile changes. From these profiles, I need to extract the maximum intensity coordinates and the full width half maxima in both the x and y axes. In the end, I'd like to have a table that lists all these values for each image. My code currently works properly for a single iteration so I'm assuming that the problem lies in the way my loop is setup. My code is down below. I've also attached an image of what comes up when I run my program. Any help would be greatly appreciated.
%code
fileFolder = fullfile(matlabroot, 'toolbox', 'images', 'imdata');
dirOutput = dir('/Users/Name/Documents/MATLAB/image_*.tiff');
fileNames = {dirOutput.name}'
numFrames = numel(fileNames)
I = imread(fileNames{1});
sequence = zeros([size(I) numFrames], class(I));
sequence(:,:,1) = I;
%
for p = 2:numFrames
sequence(:,:,p) = imread(fileNames{p});
end
sequenceNew = stdfilt(sequence, ones(3));
test = 1;
while test == 1
test = 0;
for d = 0001:numFrames
%intensity plot info
Int = imread(fileNames{d});
[x,y] = size(Int);
X = 1:x;
Y = 1:y;
[xx,yy] = meshgrid(Y,X);
i = im2double(Int);
%max coordinates and FWHM x and y from plot
[mz,k] = max(i(:));
[ix,jy] = ind2sub(size(i),k);
[ix,jy,mz];
%max intensity coordinates in microns
%pixel size is 6.45x6.45 microns
ix = 6.45*ix;
jy = 6.45*jy;
[ix,jy,mz];
mhz = 0.5*mz;
hk = 0.5*k;
[ihx,jhy]=ind2sub(size(i),hk);
[ihx,jhy,mhz];
FWHMx = abs(ix-ihx)*2;
FWHMy = abs(jy-jhy)*2;
%table of data from plot
f = figure;
data = [ix,jy,mz,FWHMx,FWHMy];
colnames = {'X(Zmax) [um]', 'Y(Zmax) [um]', ...
'Zmax/Max Intensity', 'FWHMx [um]', 'FWHMy [um]'};
t = uitable(f, 'Data', data, 'ColumnName', colnames, 'ColumnWidth', {120});
t.Position(3) = t.Extent(3);
t.Position(4) = t.Extent(4);
%make subplot of table and intensity plot
subplot(2,1,1) = mesh(xx,yy,i); colorbar;
title('Intensity of Beam Image as a Function of Pixel Position');
xlabel('X(pixels)');
ylabel('Y (pixels)');
zlabel('Intensity (double precision corrected) [a.u.]');
pos = get(subplot(2,1,2, 'position'));
delete(subplot(2,1,2))
set(t,'units','normalized')
set(t, 'position', pos)
end
test = 1
end

4 commentaires
Réponses (2)
Walter Roberson
le 29 Juin 2015
Your line
hk = 0.5*k;
looks wrong to me. You are taking half of the linear index, which could land you in either half of the array "closer" to the origin. You can be sure that the column position will be halved (or half minus 1) but the row position could end up on either side. There is no reason I can think of to expect that the resulting position will have any relationship to the Full Width Half Maxima. You should be searching for a location whose value is closest to mhz (the half maximum) and then the distance of that point to the maxima gives you the full width at half maxima.
5 commentaires
Jessica Flores
le 29 Juin 2015
Modifié(e) : Walter Roberson
le 2 Juil 2015
Walter Roberson
le 2 Juil 2015
You start reading files "for p = 2", skipping the first file, but you use the data in that spot because you start the frame count "for d = 1"
There is no point in calculating the following values in your "for d" loop:
[x,y] = size(sequence(:,:,p));
X = 1:x;
Y = 1:y;
[xx,yy] = meshgrid(Y,X);
Those must be the same for all images.
You calculate
[ix,jy] = ind2sub(size(i),k);
and later
[ihx,jhy]=ind2sub(size(i),k);
at a time when you have not changed "k" or "i". Your ihx and jhy are therefore going to be the same as what you calculated at the time of the first call. But in meantime you have multiplied ix and jy by 6.45. Then you do
FWHMx = abs(ix-ihx)*2;
which reflects the ix that has been multiplied by 6.45 and subjects the one that has not. The difference is going to be (6.45-1)*ihx, which you then multiply by 2, giving 10.90 * ihx. And you call that your FWHMx. But at no point have you exactly searched the data to find the place that has half magnitude for z.
As I wrote above,
You should be searching for a location whose value is closest to mhz (the half maximum) and then the distance of that point to the maxima gives you the full width at half maxima. That would look like,
[mz,k] = max(i(:));
mhz = 0.5*mz;
[ix,iy] = ind2sub(size(i),k);
[minhalfdiff, poshalfdiff] = min(abs(i - mhz));
[ihx, ihy] = ind2sub(size(i), poshalfdiff);
halfwidth = sqrt((ihx - ix).^2 + (ihy - iy).^2);
Now convert ix, iy, ihx, ihy, halfwidth to microns by multiplying by the 6.45 for presentation purposes.
Thorsten
le 2 Juil 2015
Modifié(e) : Thorsten
le 2 Juil 2015
As far as I understood is the problem not the algorithm but that the loop seems to run only once.
First I would simply add a
d
within the for-loop to check whether the loop really runs only once. I tested a similiar program and it worked well.
Next you could add a
pause
after the subplot to see whether there are some subplots that are simply not displayed because the loop keeps running faster than the time needed for display.
You may then check Walter's comments on your algorithm.
0 commentaires
Voir également
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!