将视频转换为图像序列 MATLAB
Convert Video to Image Sequence 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
调用批量读取一堆帧,然后它们可供稍后使用。
read
方法允许您指定一个双元素向量作为第二个输入,告诉 MATLAB 您要读取的帧范围。例如,如果您想读取前 10 帧,请执行以下操作:
video = read(xyloObj, [1 10]);
video
是一个 4 维数组,其中第一维是框架的高度,第二维是宽度,第三维是颜色通道数(通常为 3),第四维维度是帧数。因此,如果您想访问第 i
帧,您可以:
frame = video(:,:,:,i);
此外,如果您在没有第二个参数的情况下调用 read
,则会从头到尾读入所有帧。因此,您也可以这样做:
video = read(xyloObj);
在 xylophone.mp4
文件(在我的电脑上)中,有 141 帧,在我的电脑上执行上述操作大约需要 13 秒。我的配置是 Mac OS Yosemite 10.10.3 运行ning MATLAB R2013a,在 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 文件中,以便于加载和使用。
我正在尝试将视频转换为图像序列,在 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
调用批量读取一堆帧,然后它们可供稍后使用。
read
方法允许您指定一个双元素向量作为第二个输入,告诉 MATLAB 您要读取的帧范围。例如,如果您想读取前 10 帧,请执行以下操作:
video = read(xyloObj, [1 10]);
video
是一个 4 维数组,其中第一维是框架的高度,第二维是宽度,第三维是颜色通道数(通常为 3),第四维维度是帧数。因此,如果您想访问第 i
帧,您可以:
frame = video(:,:,:,i);
此外,如果您在没有第二个参数的情况下调用 read
,则会从头到尾读入所有帧。因此,您也可以这样做:
video = read(xyloObj);
在 xylophone.mp4
文件(在我的电脑上)中,有 141 帧,在我的电脑上执行上述操作大约需要 13 秒。我的配置是 Mac OS Yosemite 10.10.3 运行ning MATLAB R2013a,在 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 文件中,以便于加载和使用。