OpenCV VideoCapture - eiichiromomma/CVMLAB GitHub Wiki

(OpenCV) VideoCapture

VideoCaptureに関する話いろいろ

バッファのクリア

WebCamで重たい処理を回していると、数秒前のフレームが処理に出てくる。フレームドロップして構わないのでサッサと新しいフレームで処理したい時のやり方。

正攻法

CV_CAP_PROP_BUFFERSIZEを使う。ただし、IEEE1394 v2のみで使えるとか(カメラがない)。

cv::VideoCapture cam;
cam.open(0);
cam.set(cv::CV_CAP_PROP_BUFFERSIZE, 3);

で、使える筈だが普通のUSBカメラだと

VIDEOIO ERROR: V4L2: setting property #38 is not supported

と怒られる。

泥縄

フレームを空回ししてしまえば良いらしい。時間を厳密に扱いたい場合には使うべきではないがよく効く。 (下の例では3枚空回ししてるが処理系により異なる)

cv::VideoCapture cam;
cam.open(0);
cv::Mat frame;
cam >> frame;
while(1){
    //ものすごく重たい処理
    
    //処理が終了
    
    // 古いフレームを使い切る
    for (int i = 0; i < 3; i++){
        cam.grab(); //cam >> frame;でもあまり変わらない。
    }
    cam >> frame;
}

CV_CAP_PROP_FPSが効かない

WebCamの場合、解像度とFOURCCとFPSをセットにして合わせる必要がある。 Linuxの場合v4l2-ctlとかで調べられる。

例 YUV 4:2:2 (YUYV)で1280x720 (8.000fps)の場合

cam.set(cv::CV_CAP_PROP_FRAME_WIDTH, 1280);
cam.set(cv::CV_CAP_PROP_FRAME_HEIGHT, 720);
cam.set(cv::CV_CAP_PROP_FRAME_FOURCC, CV_FOURCC('Y', 'U', 'Y', 'V'));
cam.set(cv::CV_CAP_PROP_FRAME_FPS, 8);