首页 文章

一种有效的方式来实时缓冲高清视频而不会占用大量内存

提问于
浏览
4

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

我目前正在使用 queue 作为缓冲区(以推送'cv::Mat'数据),但这显然效率不高,因为几秒钟的图像很快就耗尽了所有的PC内存 . 我尝试使用'cv::imencode'压缩图像,但使用PNG没有太大区别,我需要一个使用 hard-drive memory 并且高效实时操作的解决方案 .

有人能建议一个非常简单有效的解决方案吗?

编辑:

这样每个人都明白我现在在做什么;这是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> _bufferQMutex _mutex 是全局变量 . 如果你_1186180_有一个抓取缓冲区的插槽并使用cv :: VideoWriter将其保存为视频 .

编辑:我认为理想的解决方案是我的 queue<cv::Mat> _buffer 使用 hard-drive memory 而不是 pc memory . 不确定哪个星球可行? :/

2 回答

  • 0

    我建议用x264或类似的方式研究实时压缩 . x264经常用于real-time encoding视频流,并且通过正确的设置,可以在中等功率的处理器中编码多个流或1080p视频流 . 我建议在doom9's forum或类似论坛中提问 .

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

  • 3

    UPDATED

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


    你提到你需要使用 Hard Drive Memory

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

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

    并将图像捕获写入如下:

    record.write(image);
    

    在网站上找到documentationsample program .

相关问题