1

我正在阅读 AVI 电影的帧并对其帧进行一些计算。这是我的代码的一部分:

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

问题是它一直在 for 循环中消耗内存。我首先怀疑read(mov, k),但这不是问题。我做的计算越多(我设置的字段越多),分配的内存就越多。如图所示,红色矩形表示运行上述代码时分配的内存,橙色表示相同代码,最后 3 行注释(SdxSdySdtwhos方法显示在运行 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                

当我添加更多字段时情况会变得更糟,它会消耗所有内存并显示错误消息。

我错过了什么吗?我怎样才能防止这种情况?

顺便说一句,我正在使用 R2011a。

4

1 回答 1

2

实际上并没有按照您当前编写的方式预先分配结构。您正在为 的所有条目分配相同frames的结构。因为 MATLAB 在修改数据之前实际上不会进行复制,所以内存中的所有元素都frames指向一个 struct

举个例子

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;

当您遍历循环并修改每个frame条目时,会制作并更新一个副本,从而导致您所描述的内存使用量发生变化。

如果你真的想预先分配数据,你想使用类似的东西repmat来强制复制你的初始化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);

至于减少你的内存占用,这真的取决于你想要做什么。可能只是您的视频太大而无法可靠地放入内存,您可能需要巧妙地存储和处理它以节省内存。

于 2016-05-16T02:34:24.620 回答