4

OpenCV を使用して、ネットワーク カメラからのビデオをリアルタイムで処理するプログラムを作成しています。(処理中にいつでも) 以前の画像 (たとえば、10 秒分) をキャプチャして、ビデオ ファイルに保存できるようにしたいと考えています。

私は現在、バッファとしてキューを使用してこれを行っています(「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 を使用してビデオとして保存するスロットがあります。

編集: 理想的な解決策は、 PC メモリではなくハード ドライブ メモリ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

更新しました

できることの1つは、画像を使用してハードディスクに保存しimwrite、ファイル名をキューに更新することです。キューがいっぱいになったら、ファイル名をポップするときに画像を削除します。
ビデオ書き込みスロットで、キューからポップされた画像をロードし、VideoWriterインスタンスに書き込みます


ハードドライブメモリを使用する必要があるとおっしゃいました

その場合は、OpenCVHighGUIVideoWriterの使用を検討してください。以下のようにVideoWriterのインスタンスを作成できます。

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

そして、以下のように画像キャプチャを書き込みます。

record.write(image);

Webサイトでドキュメントサンプルプログラムを見つけてください。

于 2012-12-28T21:22:06.360 に答える