我正在尝试将视频转换为图像序列,在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
当我尝试使用此代码时,需要很长时间才能编译它。有没有办法在没有循环的情况下读取所有帧,所以我可以让它更快?
答案 0 :(得分:2)
无论你做什么,都需要很长时间。你正在做的是解压缩每一帧并将原始RGB帧放入内存。因此,花费在I / O上并将帧解码为RGB的时间。但是,从长远来看,对您来说更快的方法是先通过一次read
调用批量阅读一堆帧,然后再将它们用于以后使用。
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文件中,以便于加载和使用。