OpenCV入門系列(7):讀取攝像頭,保存為視頻文件


在前一篇中已經實現了讀取攝像頭並實時顯示,本文將重要講述如何把它保存為視頻文件。

關鍵代碼

CvVideoWriter* writer = cvCreateVideoWriter(filePath,CV_FOURCC('P','I','M','1'),24,cvGetSize(frame));
cvWriteFrame(writer, frame);
cvReleaseVideoWriter(&writer);

原理比較簡單,第一行cvCreateVideoWriter可創建一個writer,在創建時,可指定文件路徑、視頻編碼格式、幀率和大小等參數。第二行是向writer中寫入一幀圖片。當寫了很多幀,結束時,再調用cvReleaseVideoWriter釋放writer。

完整代碼

#include "cv.h"
#include "highgui.h"

int main(int argc, char** argv) {
    cvNamedWindow("win");

    CvCapture* capture = cvCreateCameraCapture(0);
    IplImage* frame = cvQueryFrame(capture);


    char* writePath = "d:\\my.mpg";
    CvVideoWriter* writer = cvCreateVideoWriter(
        writePath,
        CV_FOURCC('P','I','M','1'),
        24,
        cvGetSize(frame)
    );

    while(1) {
        frame = cvQueryFrame(capture);
        if(!frame) break;

        cvWriteFrame(writer, frame);
        cvShowImage("win", frame);

        char c = cvWaitKey(1000/24);
        if(c==27) break;
    }

    cvReleaseVideoWriter(&writer);
    cvReleaseCapture(&capture);
    cvDestroyWindow("win");
    return 0;
}    

代碼比較簡單,無須解釋即可看明白。下面講幾個需要注意的地方。

編碼格式的選擇

cvCreateVideoWriter函數中需要指定一個編碼格式。在《學習OpenCV》的例子中,使用了CV_FOURCC('M','J','P','G')(即Motion JPEG)的格式。我本以為例子中推薦的編碼方式,肯定是最通用的,沒想到保存下來的視頻文件怎么都播放不了。后來改成CV_FOURCC('P','I','M','1')(即MPEG-1)才能正常播放。關於它支持的編碼格式還有很多,具體有哪些不記得了,因為我找不到那個網頁了

使用-1作為編碼格式

有資料說,在windows 32位系統上,可以使用-1作為編碼格式,這樣在程序運行時,會彈出一個對話框讓人選擇編碼方式。但在我的win7 x64上,沒有提示。(也有群友說他那里有提示)

關於幀率

在代碼中有兩個地方涉及幀率,一個是保存的視頻文件需要指定幀率,一個是從攝像頭讀取畫面時需要按一定的幀率。在我理解,如果這兩個幀率相同,保存的視頻文件中的畫面速度應該和正常速度是一樣的。於是我給視頻文件設了24,給讀取攝像頭的代碼設為每隔1000/24毫秒讀取一次。然而結果讓我很意外,因為不論我怎么調整,保存的視頻文件的播放速度都非常快。

經過思考與測試,最終發現,原來我的攝像頭每秒最多只能獲取6幀圖片。所以視頻文件的幀率也必須小於等於6。

如何獲取攝像頭的幀率

據說可以使用:

double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);

來取攝像頭的幀率,但我試了取不到,值總為0。

有群友說需要在前面先取一幀,再去取幀率,我試了還不行。可能攝像頭比較弱,或者windows自帶的驅動比較弱,拿不到。

有一個笨辦法,就是手動計算。在取一幀畫面前后計時,算出其幀率。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM