Speed up image analysis code?

8 views (last 30 days)
Luke G.
Luke G. on 13 Mar 2019
Commented: Image Analyst on 13 Mar 2019
Hi All,
First time poster here, but I always appreciate the answers I see from this community. Thanks in advance for your comments! So, I adapted some code that ImageAnalysis posted on this forum so that I can convert RGB videos to grayscale images with timestamps on them. I later use these grayscale images for things such as particle image velocimetry (PIV) analysis in PIVLab, so maintaining image quality is somewhat important.
The issue is that I'm now running this code on upwards of ten videos that are each 10+ minutes long each time I collect video data. I would love to speed up this code as much as possible. I have never looked into methods for speeding up image analysis. Any thoughts or suggestions on the code below are greatly appreciated.
% NAME: Video Reader, Slicer, & Writer
% FUNCTION: Converting RGB videos in .mp4 format to grayscale images.
% CREDITS: 1) "ExtractFramesFromMovie" article on MATLAB Wiki
% 2) "ashkan" on StackOverflow
%% General housekeeping:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
fontSize = 14;
%% Reading & Slicing
% Change the current folder to the folder of this m-file.
% (The line of code below is from Brett Shoelson of The Mathworks.)
if(~isdeployed)
cd(fileparts(which(mfilename)));
end
% Get movie filename data - for later use
folder = pwd;
uiwait(msgbox({'Please select your video file(s) on the following screen.'},'Success','modal'));
mviFileName = uigetfile('*.mp4','Multiselect','on');
movieFullFileName = fullfile(folder, mviFileName);
numFiles = length(mviFileName);
if numFiles >= 1
for k = 1 : numFiles
% constructs multimedia reader object
vidObj = VideoReader(mviFileName{k});
% calculates the number of frames
numFrames = (vidObj.Duration)*(vidObj.FrameRate);
% determines vid width & height
vidHeight = vidObj.Height;
vidWidth = vidObj.Width;
numberOfFramesWritten = 0;
figure;
% enlarges figure to fit the full screen
set(gcf, 'units','normalized','outerposition',[0 0 1 1 ]);
writeToDisk = true;
% Extract out the various parts of the filename.
[~, baseFileName, extensions] = fileparts(movieFullFileName{k});
% Make up a special new output subfolder for all the separate
% movie frames that we're going to extract and save to disk.
% (Don't worry - windows can handle forward slashes in the folder name.)
folder = pwd; % Make it a subfolder of the folder where this m-file lives.
outputFolder = sprintf('%s/Frames from %s', folder, baseFileName);
% Create the folder if it doesn't exist already.
if ~exist(outputFolder, 'dir')
mkdir(outputFolder);
end
for frame = 1 : numFrames
% Reads next available frame in video:
thisFrame = readFrame(vidObj);
% Converts frame from RGB to grayscale.
grayFrame = rgb2gray(thisFrame);
% Displays frames, as they update, in a plot
imshow(grayFrame, 'InitialMagnification', 'fit');
caption = sprintf('Frame %4d of %0.1f', frame, numFrames);
title(caption, 'FontSize', 14);
% Adds timestamp to each frame
t = (vidObj.CurrentTime);
timeNow = sprintf('%0.3f',t);
displayText = ['t = ' timeNow ' s'];
% Defining text box properties
textColor = 'white';
textBackground = 'black';
text(40, 1000, displayText, 'Fontsize', 20, 'Color', textColor, ...
'BackgroundColor', textBackground);
drawnow; % Force refreshes the window
% Write the image array to the output file, if requested.
if writeToDisk
% Construct an output image file name.
outputBaseFileName = sprintf('Frame %4.4d.png', frame);
outputFullFileName = fullfile(outputFolder, outputBaseFileName);
% Stamp the name and frame number onto the image.
% At this point it's just going into the overlay,
% not actually getting written into the pixel values.
% Extract the image with the text "burned into" it.
frameWithText = getframe(gca);
% frameWithText.cdata is the image with the text
% actually written into the pixel values.
% Write it out to disk.
imwrite(frameWithText.cdata, outputFullFileName, 'png');
end
end
end
close all;
else
fprintf(' Folder %s has no files in it.\n', thisFolder);
end
Cheers,
Luke

Answers (1)

Image Analyst
Image Analyst on 13 Mar 2019
You're not doing any image analysis - just video processing. Nothing is being measured.
If you have the Computer Vision System Toolbox, you can use insertText() instead of getframe() - it might be faster (would have to try it and see).
  2 Comments
Image Analyst
Image Analyst on 13 Mar 2019
I've added annotation to the tags.
One other way to speed it up might be to not compress the image. Save it in .BMP or .TIFF. It's not necessarily faster since having more data to write to disk might take the same time as the time to compress it. You'd have to try it and see.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!