控制视觉系统工具箱中视频播放器的帧速率?

Control frame rate of video player in Vision System toolbox?

如何在 Matlab 的视觉系统工具箱中控制视频播放器的播放速率?具体来说,我想放慢视频速度。例如,这里是如何加载和显示电影的简单示例 from the documentation:

videoFReader = vision.VideoFileReader('viplanedeparture.mp4');
videoPlayer = vision.VideoPlayer;
while ~isDone(videoFReader)
  videoFrame = step(videoFReader);
  step(videoPlayer, videoFrame);
end
release(videoPlayer);
release(videoFReader);

我在用户指南中搜索了如何在此类示例中以简单的方式更改帧速率,但一无所获。

您显示图像的速度与使用当前代码检索和显示图像的速度一样快。如果你想要一个特定的帧率,我会使用 timer 来根据你想要的帧率调用你的更新方法。这是一个应该非常健壮的简短示例。

videoFReader = vision.VideoFileReader('viplanedeparture.mp4');
videoPlayer = vision.VideoPlayer;

framerate = 10; % in frames/second

t = timer('ExecutionMode', 'fixedRate', ...
          'Period', 1 / framerate, ...
          'TimerFcn', @(tmr,evnt)timerfcn(tmr, videoFReader, videoPlayer), ...
          'ErrorFcn', @(tmr,evnt)cleanup(tmr, videoFReader, videoPlayer));

show(videoPlayer);
start(t)

function timerfcn(tmr, reader, player)
    % While we have more to read, read and display it.
    if ~isDone(reader) && isOpen(player)
        step(player, step(reader));
    else
        cleanup(tmr, reader, player)
    end
end

function cleanup(tmr, reader, player)
    % Callback to ensure proper cleanup of objects
    if isvalid(tmr) && strcmpi(tmr.Running, 'on')
        stop(tmr);
        delete(tmr)
    end

    release(player);
    release(reader);
end

感谢 提高了解决方案的稳健性。

另一种方法是在 while 循环的底部放置一个 pause(1/framerate) 语句,但这不会考虑实际执行 loading/displaying 所需的任何时间,所以无法保证帧速率非常一致。

其他想法

让我思考为什么这可能不是 VideoFileReaderVideoPlayer 的功能。

VideoFileReader

正如@neuronet 所述,如果在使用 VideoFileReader 读取的视频文件中指定了帧速率,难道不能自动使用吗?

答案是,如果 可以 可以使用,但有充分的理由 使用它。由于使用 VideoFileReader.step() 获取新帧,因此必须将其实现为 step().

上的某种速率限制器

在这种特殊情况下,视频被用于显示目的;然而,情况并非总是如此。很多时候,您可能希望逐帧加载视频以进行一些分析(跟踪对象等)。现在想象一下,我的视频文件的帧速率设置为每秒 1 帧 (fps)。假设我想将此视频加载到 MATLAB 中,跟踪画面中的人物,并向用户报告在视频播放过程中有多少人通过了视野。

如果 VideoFileReader.step() 被写入以便它仅以文件中指定的帧速率返回图像,这意味着我可以进行的 最快 处理将是每秒一帧。如果是这样的话,最终用户只需要自己看视频,我们就会失业!

另一个重要的考虑因素是,如果您确实想要 处理 视频帧 将其显示到 VideoPlayer 对象之前,您需要以某种方式考虑处理时间(显然 VideoFileReader 对此一无所知)。

VideoPlayer

另一种选择是为 VideoPlayer 对象本身设置 FrameRate 属性。

虽然这也可以完成,但目前的实现方式是不可能的。当前要显示新帧,您必须显式调用 VideoPlayer.step() 方法。它遇到了与 VideoFileReader 相同的情况。它必须作为 step() 方法的速率限制器来实现。

The Mathworks 使这项工作可行的一种可能方法是使用 step() 更新图像的替代方法。例如,一个 NextImageFcn 回调什么的。然后VideoPlayer可以根据指定的帧率在内部设置一个定时器,并在必要时执行回调(类似于我们的定时器回调)。

另一种选择是让 VideoPlayer 接受一个 VideoFileReader 对象作为输入。然后它可以使用此对象获取有关视频的信息(帧速率等)并以适当的速度显示图像。

这里的主要问题是,它只服务于一小部分用户。这是因为 MATLAB(和计算机视觉工具箱)的主要目标不是视频播放系统,而是旨在对视频和 VideoPlayer 对象旨在简化结果的显示。

也许将来会实现此功能,但目前我的想法是为什么它不存在。