I'm reading frames of an AVI movie and doing some calculations on its frames. This is a part of my code:
clear; clc;
mov = mmreader('traffic.avi');
vidHeight = mov.Height;
vidWidth = mov.Width;
nFrames = mov.NumberOfFrames;
patchsize = 5;
frames(1:nFrames) = ...
struct( ...
'gray', zeros(vidHeight, vidWidth, 'double') ,...
'dx', zeros(vidHeight, vidWidth, 'double') ,...
'dy', zeros(vidHeight, vidWidth, 'double') ,...
'dt', zeros(vidHeight, vidWidth, 'double') , ...
'Sdx', zeros(vidHeight, vidWidth, 'double') , ...
'Sdy', zeros(vidHeight, vidWidth, 'double') , ...
'Sdt', zeros(vidHeight, vidWidth, 'double'));
h_sob_y = fspecial('sobel');
h_sob_x = h_sob_y';
h_sum = ones(patchsize);
for k = 1 : nFrames
frames(k).gray = double(histeq(rgb2gray(read(mov, k))))/255;
frames(k).dx = imfilter(frames(k).gray, h_sob_x);
frames(k).dy = imfilter(frames(k).gray, h_sob_y);
if k > 1
frames(k).dt = frames(k).gray - frames(k-1).gray;
end
frames(k).Sdx = imfilter(frames(k).dx, h_sum);
frames(k).Sdy = imfilter(frames(k).dy, h_sum);
frames(k).Sdt = imfilter(frames(k).dt, h_sum);
end
The problem is that it keeps consuming memory inside for loop. I first suspected read(mov, k)
, but it's not the problem. The more calculation I do (the more fields I set), the more memory gets allocated. The picture shows it, red rectangle show memory allocated when running the code above, the orange one is for the same code with last 3 lines commented (Sdx
, Sdy
and Sdt
). whos
method shows no change in number or size of variables before and after running for-loop (except for k
):
Name Size Bytes Class Attributes
frames 1x120 129074848 struct
h_sob_x 3x3 72 double
h_sob_y 3x3 72 double
h_sum 5x5 200 double
k 1x1 8 double
mov 1x1 60 mmreader
nFrames 1x1 8 double
patchsize 1x1 8 double
vidHeight 1x1 8 double
vidWidth 1x1 8 double
It gets worse when I add more fields, it consumes all the memory and displays an error message.
Am I missing something? How can I prevent this?
BTW, I'm using R2011a.
You're not actually pre-allocating a structure the way that you current have it written. You are assigning the same structure to all entries of
frames
. Because MATLAB does not actually make a copy until the data is modified, all elements offrames
point to onestruct
in memory.As an example
As you go through the loop and modify each
frame
entry, then a copy is made and updated causing the change in memory usage that you're describing.If you actually want to pre-allocate the data, you want to instead use something like
repmat
which will force a copy to be made of your initializationstruct
.As far as reducing your memory footprint, it really depends what you're trying to do. It may just be that your video is too large to fit in memory reliably and you may need to get clever in how you store and process it to conserve memory.