读取视频文件
此示例说明如何从特定时间或帧索引开始读取视频帧,读取指定区间内的帧,或读取视频中的所有帧。
从指定时间或帧索引开始读取帧
从距离视频文件开头 0.5 秒处开始读取文件的一部分。然后,从帧索引 100 开始读取到视频文件结束。
为示例视频文件 xylophone_video.mp4
创建一个 VideoReader
对象。
vidObj = VideoReader("xylophone_video.mp4");
通过设置 CurrentTime
属性,指定应从距离文件开头 0.5 秒处开始读取。
vidObj.CurrentTime = 0.5;
使用 readFrame
方法读取视频帧,直至文件结束。
while hasFrame(vidObj) vidFrame = readFrame(vidObj); imshow(vidFrame) pause(1/vidObj.FrameRate) end
您也可以使用 read
方法从指定的帧索引开始读取视频帧,直到视频结束。将要读取的索引指定为 [100 Inf]
。read
方法返回从索引 100 开始到视频文件结束的所有帧。
vidframes = read(vidObj,[100 Inf]);
清除 VideoReader
对象。
clear vidObj
读取指定区间内的帧
通过指定时间或帧区间来读取视频文件的一部分。
读取 0.6 到 0.9 秒之间的视频帧。首先,创建一个 VideoReader
对象和一个用来保存帧的结构体数组。
vidObj = VideoReader("xylophone_video.mp4"); s = struct("cdata",zeros(vidObj.Height,vidObj.Width,3,"uint8"),colormap=[]);
然后,通过设置 CurrentTime
属性,指定应从距离文件开头 0.6 秒处开始读取。
vidObj.CurrentTime = 0.6;
一次读取一帧,直至 CurrentTime
到达 0.9 秒处。将每个视频帧中的数据追加到结构体数组。查看结构体数组中的帧数。s
是 1×10 结构体数组,表示读取了 10 个帧。有关将结构体数组 s
中的帧显示为影片的信息,请参阅 movie
函数参考页。
k = 1; while vidObj.CurrentTime <= 0.9 s(k).cdata = readFrame(vidObj); k = k+1; end whos s
Name Size Bytes Class Attributes s 1x10 2305344 struct
您也可以通过使用帧索引来读取指定区间内的所有帧。例如,将要读取的帧的范围指定为 [18 27]
。read
方法返回一个 m×n×p×10 数组(其中每个帧的大小为 m×n×p),表示读取 10 个帧。
frames = read(vidObj,[18 27]);
whos frames
Name Size Bytes Class Attributes frames 240x320x3x10 2304000 uint8
清除 VideoReader
对象。
clear vidObj
读取所有帧
从视频中读取所有帧,一次读取一帧或一次读取所有帧。
创建一个 VideoReader
对象,并显示视频中的总帧数。
vidObj = VideoReader("xylophone_video.mp4");
vidObj.NumFrames
ans = 141
使用 readFrame
方法读取所有帧,一次读取一帧,并显示这些帧。
while hasFrame(vidObj) frame = readFrame(vidObj); imshow(frame) pause(1/vidObj.FrameRate) end
您也可以一次读取所有视频帧。read
方法返回一个视频帧的 m×n×p×141 数组(其中每个帧的大小为 m×n×p)。
allFrames = read(vidObj);
whos allFrames
Name Size Bytes Class Attributes allFrames 240x320x3x141 32486400 uint8
清除 VideoReader
对象。
clear vidObj
视频读取的故障排除和提示
在 Windows® 平台上,您无法修改或删除由工作区中的
VideoReader
对象引用的 AVI 文件。要从工作区中删除VideoReader
对象,请使用clear
函数。对于某些 MP4 文件,
NumFrames
属性在 Windows、Mac 和 Linux® 平台上可能返回不同值。这种差异是由底层平台特定 API 的差异造成的。当
CurrentTime
属性的值等于Duration
属性的值时,hasFrame
方法可能会返回逻辑值1
(true
)。此行为是所使用的底层平台特定 API 的限制所致。不推荐通过将
CurrentTime
属性设置为接近于Duration
值的值来查找视频文件中的最后一帧。对于某些文件,即使CurrentTime
值小于Duration
值,该操作也会返回错误,即指示已到达文件结尾。如果文件持续时间长于视频流的持续时间,并且在靠近文件结尾时没有可读取的视频,通常会发生此问题。不推荐使用
Duration
属性限制从视频文件中读取数据。请使用hasFrame
方法检查是否存在可读取的帧。最好是连续读取数据,直至文件报告不再存在可读取的帧。Windows 系统上的视频读取性能:为了在 Windows 上达到更好的
MP4
和MOV
视频文件读取性能,MATLAB® 使用系统的图形硬件进行解码。但是,在某些情况下,使用图形卡进行解码可能会降低系统性能,具体取决于系统上的特定图形硬件。如果您注意到系统上的视频读取性能降低,可以通过键入以下命令来禁用硬件加速:matlab.video.read.UseHardwareAcceleration('off')
。您可以通过键入以下命令重新启用硬件加速:matlab.video.read.UseHardwareAcceleration('on')
。
另请参阅
VideoReader
| mmfileinfo
| movie
| read
| readFrame