How to optimize imagesc plot with pixel labels to get a faster frame grab for creating a .avi

9 views (last 30 days)
Hello,
The code below is a portion of a larger code that I am using to analyze pixel by pixel temperature in different zones within the field of view. I typically have between 3000-9000 induvidual frames of data which are each 32X31, for below I used a random set of data with 4010 frames. Right now this currently grabs frames at a rate of about 1 frame per second, as I have so many frames this takes on order of hours to grab all of the frames. I would like to be able to create the .avi much faster, but I believe the slow down is due to the creation of F, specfically the text() pixel labels. The code runs through 50 layers without the added pixel lables in about 8 seconds, but it takes almost a minute with the labels.
Is there a better way to apply the pixel by pixel labels to an imagesc plot or a way to make my current code more efficient?
%Creating custom color map
gyr_map=[
0,1,0;0.02,1,0;0.04,1,0;0.06,1,0;0.08,1,0;0.10,1,0;0.12,1,0;0.14,1,0;0.16,1,0;0.18,1,0;...
0.20,1,0;0.220,1,0;0.24,1,0;0.27,1,0;0.29,1,0;0.31,1,0;0.33,1,0;0.35,1,0;0.37,1,0;0.39,1,0;...
0.41,1,0;0.43,1,0;0.45,1,0;0.47,1,0;0.49,1,0;0.51,1,0;0.53,1,0;0.55,1,0;0.57,1,0;0.59,1,0;...
0.61,1,0;0.63,1,0;0.65,1,0;0.67,1,0;0.69,1,0;0.71,1,0;0.73,1,0;0.76,1,0;0.78,1,0;0.80,1,0;...
0.82,1,0;0.84,1,0;0.86,1,0;0.88,1,0;0.90,1,0;0.92,1,0;0.94,1,0;0.96,1,0;0.98,1,0;1,1,0;...
1,1,0;1,0.98,0;1,0.96,0;1,0.94,0;1,0.92,0;1,0.90,0;1,0.88,0;1,0.86,0;1,0.84,0;1,0.82,0;...
1,0.80,0;1,0.78,0;1,0.76,0;1,0.73,0;1,0.71,0;1,0.69,0;1,0.67,0;1,0.65,0;1,0.63,0;1,0.61,0;...
1,0.59,0;1,0.57,0;1,0.55,0;1,0.53,0;1,0.51,0;1,0.49,0;1,0.47,0;1,0.45,0;1,0.43,0;1,0.41,0;...
1,0.39,0;1,0.37,0;1,0.35,0;1,0.33,0;1,0.31,0;1,0.29,0;1,0.27,0;1,0.24,0;1,0.22,0;1,0.20,0;...
1,0.18,0;1,0.16,0;1,0.14,0;1,0.12,0;1,0.10,0;1,0.08,0;1,0.06,0;1,0.04,0;1,0.02,0;1,0,0];
%Creating a random set of data within standard temperature range
Random_multi = randi([40 70],32,31,4010);
[multi_r,multi_c, multi_frames] = size(Random_multi);
x_cor=repmat(1:multi_c,multi_r,1); %x-cordinates
y_cor=(repmat(1:multi_r,multi_c,1))';%y-cordinates
n_frames=4010;
%Creating a column vector of stage labels
Stage1_labels=repmat({'Stage 1:'},[32080 1]);
Stage1_labels_str = convertCharsToStrings(Stage1_labels);
Stage2_labels=repmat({'Stage 2:'},[32080 1]);
Stage2_labels_str=convertCharsToStrings(Stage2_labels);
Stage3_labels=repmat({'Stage 3:'},[32080 1]);
Stage3_labels_str=convertCharsToStrings(Stage3_labels);
Stage4_labels=repmat({'Stage 4:'},[32080 1]);
Stage4_labels_str=convertCharsToStrings(Stage4_labels);
stage=vertcat(Stage1_labels_str,Stage2_labels_str,Stage3_labels_str,Stage4_labels_str);
%Creating a column vector of induvidual line numbers
Layer_number_rand=[1:128320]';
%Iterating through each frame of the multidimensional array & getting movie frame
for i=1:1:n_frames
lineindex=i*32;
figure(20)
imagesc(Random_multi(:,:,i))
grid on
colorbar
colormap(gyr_map)
caxis([40 70])
str_title=strcat('Temperature: ',stage(lineindex),num2str(Layer_number_rand(lineindex))); % Setting title with Temp:stage name:Line number
title(str_title)
str=strcat(' Frame: ',num2str(i));
annotation('textbox',[0 0 .1 .1],'String',str,'EdgeColor','k') %Creating left corner box to display the frame number
% Generate pixel Labels
t = num2cell(Random_multi(:,:,i)); % extact temperature values into cells
t = cellfun(@num2str, t, 'UniformOutput', false); % convert to string
% % Draw Image and Label Pixels
text(x_cor(:), y_cor(:), t, 'HorizontalAlignment', 'Center','Fontsize',5)
F(i)=getframe(figure (20));
clf(figure (20))
end
Tempobj=VideoWriter('Random Data.avi');
%Tempobj.FrameRate=2;
open(Tempobj);
for kk=1:length(F)
writeVideo(Tempobj,F(kk));
end
close(Tempobj)

Accepted Answer

darova
darova on 20 May 2020
Move every possible operations outside the for loop
Some exaplanations
Simple example
clc,clear
% create new object 'plot' for each frame
tic
x = linspace(0,20);
for i = 1:100
y = sin(x+i/10);
plot(x,y)
drawnow
end
toc
% create 'plot' object once and change the data for each frame
tic
h = plot(0,0);
for i = 1:100
y = sin(x+i/10);
set(h,'xdata',x,'ydata',y)
drawnow
end
toc
results
Elapsed time is 0.984396 seconds. % new object
Elapsed time is 0.344684 seconds. % change the data only
See attached script
  2 Comments
HarleyR
HarleyR on 21 May 2020
Thank You! I knew that I needed to not create a new object each time but I wasn't sure how to accomplish that, your attached code was exactly what I needed. At this point is the speed only constrained by Matlab iself? I am wondering if there anything I can do to manipulate my input data to speed it up?
darova
darova on 21 May 2020
  • At this point is the speed only constrained by Matlab iself? I am wondering if there anything I can do to manipulate my input data to speed it up?
What do you mean?

Sign in to comment.

More Answers (0)

Products


Release

R2018a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!