Why MATLAB keeps consuming memory when setting fields of a preallocated struct?

319 views Asked by At

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):

enter image description here

  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.

1

There are 1 answers

0
Suever On

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 of frames point to one struct in memory.

As an example

a = [1,2,3];

%// No copy is made yet (memory usage remains the same)
b = a;

%// Copy is made and then modified (memory usage doubles)
b(1) = 2;

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 initialization struct.

frames = repmat(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')), nFrames, 1);

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.