【问题标题】:Control frame rate of video player in Vision System toolbox?在视觉系统工具箱中控制视频播放器的帧速率?
【发布时间】:2016-03-11 18:32:10
【问题描述】:

如何在 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);

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

【问题讨论】:

    标签: matlab video matlab-cvst


    【解决方案1】:

    您正在以尽可能快的速度显示图像,并且可以使用当前代码检索和显示它们。如果你想要一个特定的帧率,我会使用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
    

    感谢horchler's comments 提高了解决方案的稳健性。

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

    其他想法

    comments made below by @neuronet 让我思考为什么这可能不是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 对象旨在简化结果的显示。

    也许这个功能会在未来实现,但现在这些是我对它为什么不存在的想法。

    【讨论】:

    • 很抱歉在修复其他错误时引入了错字——愚蠢的自动更正。我刚刚修正了另一个小错字。
    • @horchler 没问题。感谢您的敏锐眼光。
    • 为了进一步改进这个出色的答案,您可以在timerfcnif 语句中添加&& isOpen(videoPlayer)(您需要在之前调用show(videoPlayer); 或显示第一帧)。如果用户关闭窗口,这将运行cleanuponCleanup 也可以被利用。此外,timer 对象具有全局范围并且不会被删除,因此最好将 delete(tmr); 添加到 cleanup
    • @neuronet 我已经更新了这篇文章,表达了我对它的一些想法。
    • @neuronet 好吧,总有一些“影响”。
    猜你喜欢
    • 2014-07-05
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 2014-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    相关资源
    最近更新 更多