4

我正在编写一个程序,该程序涉及使用 OpenCV 实时处理来自网络摄像机的视频。我希望能够捕获(在处理过程中的任何时间)以前的图像(例如十秒)并保存到视频文件中。

我目前正在使用队列作为缓冲区(推送'cv :: Mat'数据)来执行此操作,但这显然效率不高,因为几秒钟的图像很快就会耗尽所有PC内存。我尝试使用 'cv::imencode' 压缩图像,但使用 PNG 并没有太大区别,我需要一个使用硬盘驱动器内存并高效进行实时操作的解决方案。

谁能提出一个非常简单有效的解决方案?

编辑:

只是为了让每个人都明白我现在在做什么;这是 10 秒缓冲区的代码:

void run()
{
    cv::VideoCapture cap(0);
    double fps = cap.get(CV_CAP_PROP_FPS);
    int buffer_lenght = 10;     // in seconds
    int wait = 1000.0/fps;
    QTime time;


    forever{
        time.restart();
        cv::mat image;
        bool read = cap.read(image);

        if(!read)
            break;

        bool locked = _mutex.tryLock(10);

        if(locked){
            if(image.data){
                _buffer.push(image);

                if((int)_buffer.size() > (fps*buffer_lenght))
                    _buffer.pop();
            }
            _mutex.unlock();
        }

        int time_taken = time.elapsed();
        if(time_taken<wait)
            msleep(wait-time_taken);

    }

    cap.release();
}

queue<cv::Mat> _buffer并且QMutex _mutex是全局变量。如果您熟悉 QT、信号和插槽等,我有一个插槽可以抓取缓冲区并使用 cv::VideoWriter 将其保存为视频。

编辑:我认为理想的解决方案是让我queue<cv::Mat> _buffer使用硬盘内存而不是电脑内存。不确定这在哪个星球上是可能的?:/

4

2 回答 2

3

我建议研究使用x264或类似的实时压缩。x264 经常用于视频流的实时编码,并且通过正确的设置,可以在功率适中的处理器中对多个流或 1080p 视频流进行编码。我建议在doom9 的论坛或类似的论坛中提问。

x264 是一个免费的 h.264 编码器,可以实现 100:1 或更好的(相对于原始)压缩。x264 的输出可以以比未压缩(或无损压缩)视频更高的效率存储在您的内存队列中。

于 2012-12-28T21:11:40.350 回答
0

更新

您可以做的一件事是使用将图像存储到硬盘imwrite并将其文件名更新到队列。当队列已满时,在弹出文件名时删除图像。
在您的视频写入槽中,加载从队列中弹出的图像并将它们写入您的VideoWriter实例


你提到你需要使用硬盘内存

在这种情况下,请考虑使用OpenCV HighGUI VideoWriter。您可以创建一个 VideoWriter 的实例,如下所示:

VideoWriter record("RobotVideo.avi", CV_FOURCC('D','I','V','X'), 
    30, frame.size(), true);

并将图像捕获写入如下:

record.write(image);

在网站上查找文档示例程序

于 2012-12-28T21:22:06.360 回答