将视频转换为图像序列MATLAB

我正在尝试将视频转换为图像序列,在mathworks中,我看到了这样的代码

阅读并播放电影文件xylophone.mp4.

xyloObj = VideoReader('xylophone.mp4');

nFrames = xyloObj.NumberOfFrames;
vidHeight = xyloObj.Height;
vidWidth = xyloObj.Width;

预分配电影结构.

mov(1:nFrames) = ...
    struct('cdata',zeros(vidHeight,vidWidth, 3,'uint8'),...
           'colormap',[]);

一次读一帧.

for k = 1 : nFrames
    mov(k).cdata = read(xyloObj,k);
end

当我尝试这段代码时,需要很长时间才能编译它.有没有办法在没有循环的情况下读取所有帧,所以我可以让它更快?

最佳答案 无论你做什么,都需要很长时间.你正在做的是解压每个帧并将原始RGB帧放入内存.因此,花费在I / O上并将帧解码为RGB的时间.但是,从长远来看,对您来说可能更快的是首先使用单个读取调用批量读取一堆帧,然后可以在以后使用它们.

read方法允许您指定一个两元素向量作为第二个输入,告诉MATLAB您想要读取的帧范围.例如,如果要读取前10帧,请执行以下操作:

video = read(xyloObj, [1 10]);

video是一个4-D数组,其中第一个维度是帧的高度,第二个维度是宽度,第三个维度是颜色通道的数量(通常为3),第四个维度是帧号.因此,如果您想访问第i帧,您可以:

frame = video(:,:,:,i);

此外,如果您在没有第二个参数的情况下调用read,则会从​​头到尾读取所有帧.因此,您也可以这样做:

video = read(xyloObj);

在xylophone.mp4文件(在我的电脑上),有141帧,在我的电脑上执行上述操作大约需要13秒.我的配置是运行MATLAB R2013a的Mac OS Yosemite 10.10.3,在Intel Core i7 2.3 GHz上运行16 GB RAM.这从我们之前谈到的内容中有意义,现在这些帧可用作4D矩阵.

因此,也许可以工作的一件事是使用read并且只读取所有帧而不进行循环.如果这很慢,那么也许你可以一次读取每10或20帧左右,处理帧,然后进入下一批……所以这样的事情:

for idx = 1 : 20 : nFrames
    if idx + 20 > nFrames
        endIndex = nFrames;
    else
        endIndex = idx + 20;
    end
    video = read(xyloObj, [idx endIndex-1]);

    %// Continue processing
end

但是,如果您只使用read命令而没有任何第二个输入,如果您可以等待大约13秒左右,那就完全没问题了.除此之外,如果你真的想在以后使用这些帧,你可以随时使用save并将帧存储在MAT文件中,以便于加载和使用.

点赞