【问题标题】:How to process large video in Matlab with for loop and without memory error如何使用 for 循环在 Matlab 中处理大型视频且没有内存错误
【发布时间】:2012-07-27 22:56:38
【问题描述】:

我是 Matlab 处理的新手,我想在“for 循环”(或不使用它)内读取和处理大型视频(超过 200k 帧)。特别是,我想:

  1. 使用 VideoReader 阅读视频,
  2. 将视频细分为 n-epoch,每帧 1000 帧,
  3. 处理每个 epoch 1000 帧,读取:epoch 的第一帧,跳过两帧,读取帧,跳过两帧,以此类推(例如 i=1:3:nFrames),
  4. 考虑到我需要将读取的每个“RGB 帧”转换为 im2bw 的每个时期
  5. 转换后,我需要考虑第一个视频帧(“mov(1,1).cdata”)和在该时期内读取的每个帧,进行“corr2”2D 互相关,
  6. 将“corr2”的结果存储到向量中。

总之,这就是我需要做的。谢谢大家


这是我目前所拥有的,关于“corr2”:

for frame_ind = 1 : nFrames
  mov(frame_ind).cdata = im2bw(rgb2gray(read(xyloObj,frame_ind)),0.20);      
end

%% Corr2 to compare BW video frames
for frame_ind2 = 1:(frame_ind-1)
    R(frame_ind2)=corr2(mov(1,frame_ind2).cdata,mov(1,frame_ind2+1).cdata);
end

 TF= isnan(R); 
 g=sum(TF);
 f=(length(R)-g);


if (g~=(length(R))) 
  %%If Part has errors 
  disp('"Part_1" has video interferences/noise/problems, see "Testresult.txt" for more information.');
 else 
  %%If Part has not errors  
  displ=strcat('"Part_1" has not video interferences/noise/problems.');
 end

【问题讨论】:

  • 您是要一次处理三帧,还是要拍摄一帧、跳过两帧、拍摄下一帧、跳过两帧等...?此外,如果您的内存不足,请不要存储所有读取的帧,只需读取帧,处理它,读取下一帧覆盖先前的值...
  • 我想将整个视频细分为 1000 帧的 n-epoch,每个 epoch 都应该处理“...一帧,跳过两帧,拍摄下一帧,跳过两帧,等等。 "。
  • @8bit_Biker 因此,您不想从框架1, 4, 7, 10, ... end 开始,而是希望以三步从1:1000 开始,然后以三步从1001:2000 开始。对吗?
  • @8bit_Biker:还请描述您打算对帧进行何种类型的处理。例如,如果您需要对连续帧进行关联,显然我们必须存储最后两个帧。正如我所解释的,我的代码始终只存储一帧只是为了减少使用的内存..
  • @Amro:我可以用三个 for 循环来实现:一个用于前 1000 帧,一个从 1001 到 fix(nframes/1000),最后一个从 fix(nframes/1000) 到nFrames...我认为有更好的方法可以做到,但我无法正确设置。

标签: matlab memory video for-loop out-of-memory


【解决方案1】:

这是我的版本:

mov = VideoReader('movie.avi');
nFrames = mov.NumberOfFrames;

len = 1000;     %# epoch length
step = 3;       %# step size

%# indices of each epoch
indices = bsxfun(@plus, 1:step:len, (0:ceil(nFrames/len-1))'*len);   %#'
indices = num2cell(indices,2);
indices{end}(indices{end}>nFrames) = [];

%# loop over each epoch
corr_coef = cell(size(indices));
for e=1:numel(indices)
    %# read first image in epoch
    img1 = read(mov, indices{e}(1));
    img1 = rgb2gray(img1);            %# instead of im2bw(img1, graythresh(img1))

    %# read rest of images in epoch
    corr_coef{e} = zeros(1,numel(indices{e})-1);
    for f=2:numel(indices{e})
        img2 = read(mov, indices{e}(f));
        img2 = rgb2gray(img2);

        %# compute corr2 between the two images
        corr_coef{e}(f-1) = corr2(img1,img2);
    end
end

元胞数组corr_coef包含每个时期的相关系数,其中每个元胞在第一帧和第(i+1)帧之间包含corr2的向量corr_coef{e}(i)

请注意,如果其中一帧是恒定的(例如全黑),则 2D 相关系数只是 NaN(formula‌​ 中的零除以零)

【讨论】:

  • 请注意,如果其中一帧是恒定的(例如全黑),则 2D 相关系数只是 NaN(formula 中的零除以零)
  • 谢谢..我现在就试试看! ;)
  • 同样的问题......正如我为另一个答案所写的......它返回全NaN数组......这是不可能的......可能corr2函数的索引存在一些问题...... .无论如何...谢谢大家的帮助!!!
  • 再说一次,我们不知道您的视频文件,所以我们无能为力。调试您的代码并查看单独的 corr2() 输出。
  • 好的,这就是我在我的代码中写的..试着看看这个..(阅读“问题”的顶部)
【解决方案2】:
% create video handle and get number of frames
vidObj = VideoReader(video_file);
nFrames = get(vidObj, 'NumberOfFrames');

blocksize = 1000;
BlocksIDs = 1:blocksize:nFrames;
nBlocks = numel(BlocksIDs);

frame_step = 3;

% cell array with all correlations values grouped by block
xcorrs_all_blocks = cell(1, nBlocks);

for j = 1 : nBlocks

    % if this is the last block, process until the last frame
    if j == nBlocks
        last_frame = nFrames;
    % otherwise, read until next block
    else
        last_frame = BlocksIDs(j + 1);
    end
    % compute the frame numbers that we want to look at
    frame_indices = BlocksIDs(j) : frame_step : last_frame;
    nFrames = numel(frame_indices);

    first_frame = [];
    % pre-allocate array holding the in-block corr2 values.
    xcorrs_this_block = nan(1, nFrames-1);

    for k = 1 : nFrames

        % read-in raw frame from video file.
        raw_frame = read(vidObj, frame_indices(k));            
        % determine level for bw conversion - this might help.
        level = graythresh(raw_frame);
        raw_frame = im2bw(raw_frame, level);

        if k == 1
            % save current frame as first frame for later corr2 processing
            first_frame = raw_frame;
        else
            % calc the correlation between the first frame in the block and each successive frame
            xcorrs_this_block(k-1) = corr2(first_frame, raw_frame);
        end


    end

    % save all xcorr values into global cell array.
    xcorrs_all_blocks{j} = xcorrs_this_block;

end

【讨论】:

  • 我希望这行得通……我现在就试试……非常感谢
  • @8bit_Biker 我不知道你的视频是什么样的。我也不知道im2bw 是否是正确的做法(再说一次,我不知道你的视频)。尝试使用level = graythresh(I); 计算阈值。我已将graythresh 代码添加到我的答案中。也许有帮助。
  • 也许它的 corr2 函数应该有一些错误:我有一个视频有一些黑色和一些白色的帧,但 corr2 认为都是平等的......事实上,“xcorrs_all_blocks”充满了“南”。相反,我期望一些系数(范围从 0 到 1)取决于帧是否与第一个视频帧更相似或更相似。为什么??
  • @8bit_Biker,我对你的视频一无所知,但计算 corr2 时似乎出了点问题。在那里设置一个断点,看看输出是什么。你确定xcorrs_all_blocks 的所有值都是 NaN 吗? xcorrs_all_blocks{1}(1)呢?
  • 我的视频是一系列黑帧。有时会出现一些带有黑色背景和白色字符串的帧(一种视频干扰/噪音)。目标是确定视频中是否有这个“特殊帧”。我想使用 corr2 函数来处理帧。视频是 25fps,为了提高处理速度,我想考虑一帧三帧
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-25
  • 2018-04-21
  • 2018-03-20
  • 2022-12-04
  • 2021-08-08
  • 1970-01-01
相关资源
最近更新 更多