OpenCV讀寫視頻文件解析


OpenCV讀寫視頻文件解析

一.視頻讀寫類

視頻處理的是運動圖像,而不是靜止圖像。視頻資源可以是一個專用攝像機、網絡攝像頭、視頻文件或圖像文件序列。
OpenCV 中,VideoCapture 類和 VideoWriter 類為視頻處理中所涉及的捕獲和記錄任務提供了一個易用的 C++API。

cv::VideoCapture

1、對象的構造函數,如下面的例子:

cv::VideoCapture capture("D:\\Camera Road 01.avi");

參數為const string&,即讀入彩色圖像,若設置為0則讀取攝像頭。

2、驗證視頻讀入是否成功,如下:

if (!capture.isOpened())
    {
        std::cout << "Vidoe open failed!" << std::endl;
        return -1;
    }

3、驗證完成后,就可以開始讀取視頻啦!

cv::Mat frame;
capture >> frame;

VideoCapture對象的操作可以像流一樣讀入到Mat類型的對象(即圖像)中。

cv::VideoWriter

這個類是用來寫入一個視頻的,使用起來比capture麻煩一些。

構造函數 cv::VideoCapture(const string& path,int fourcc,double fps, Size framesize, bool isColor=true)

需要注意的是fourcc,cv::VideoWriter::fourcc(char c1,char c2,char c3,char c4)

常用的格式有

  • CV_FOURCC('P','I','M','1') = MPEG-1 codec
  • CV_FOURCC('M','J','P','G') = motion-jpeg codec
  • CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec
  • CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 codec
  • CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec
  • CV_FOURCC('U', '2', '6', '3') = H263 codec
  • CV_FOURCC('I', '2', '6', '3') = H263I codec
  • CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec

二.視頻讀寫示例 

剩下的就與VideoCapture差不多了,不過是輸出流的操作。

下方的 recVideo 示例是一個簡短的代碼片段,可以讓你了解如何使用一個默認攝像機作為一個捕捉設備來抓取幀,對它們進行邊緣檢測,並且將新的轉換視頻幀作為一個文件保存。而且,創建兩個窗口同時顯示原始幀和處理過的幀。

recVideo 示例的代碼為:

1.  #include <opencv2/opencv.hpp>
2.  #include <iostream>
3.  using namespace std;
4.  using namespace cv;
5.   
6.  int main(int, char **)
7.  {
8.      Mat in_frame, out_frame;
9.      const char win1[]="Grabbing...", win2[]="Recording...";
10.    double fps=30;//每秒的幀數
11.    char file_out[]="recorded.avi";
12.   
13.    VideoCapture inVid(O) ; //打開默認攝像機
14.    if ( !inVid.isOpened () ) { //檢查錯誤
15.        cout << "Error! Camera not ready...\n";
16.        return -1;
17.    }
18.    //獲取輸入視頻的寬度和高度
19.    int width = (int)inVid.get(CAP_PROP_FRAME_WIDTH);
20.    int height = (int)inVid.get(CAP_PR〇P_FRAME_HEIGHT);
21.    VideoWriter recVid(file out,VideoWriter::fourcc('M','S','V','C'), fps, Size(width, height));
22.    if (!recVid.isOpened()) {
23.        cout << "Error! Video file not opened...\n";
24.        return -1;
25.    }
26.    //為原始視頻和最終視頻創建兩個窗口
27.    namedWindow(win1);
28.    namedWindow(win2);
29.    while (true) {
30.        //從攝像機讀取幀(抓取並解碼)
31.        inVid >> in frame;
32.        //將幀轉換為灰度
33.        cvtColor(in_frame, out_frame, C0L0R_BGR2GRAY);
34.        //將幀寫入視頻文件(編碼並保存)
35.        recVid << out_frame ?
36.        imshow (win1, in_frame);// 在窗口中顯示幀
37.        imshow(win2, out_frame); // 在窗口中顯示幀
38.        if (waitKey(1000/fps) >= 0)
39.            break;
40.    }
41.    inVid.release(); // 關閉攝像機
42.    return 0;
43.}

在本示例中,應該快速瀏覽以下這些函數:

  • double VideoCapture::get(int propId):這個函數為一個 VideoCapture 對象返回指定的屬性值。在 videoio.hpp 頭文件中包含了基於 DC1394(IEEE 1394 數碼相機規范)屬性的一個完整列表。
  • static int VideoWriter::fourcc(char c1,char c2,char c3,char c4):這個函數把四個字符連接起來形成一個 fourcc 碼。在示例中,MSVC 代表微軟視頻(僅在 Windows 上可用)。
  • bool VideoWriter::isOpened():如果寫入視頻的對象被成功初始化,這個函數返回 true。例如,使用一個不正確的編解碼器會產生一個錯誤。
  • VideoCapture&VideoCapture::operator>>(Mat&image):這個函數抓取、解碼並返回下一幀。這個方法和布爾函數 VideoCapture::read(OutputArray image)等價。可以使用這個函數而不使用函數 VideoCapture::grab(),然后使用 VideoCapture::retrieve()。
  • VideoWriter&VideoWriter::operator<<(const Mat&image):這個函數寫入下一幀。這個方法和布爾函數 VideoWriter::write(const Mat&image)等價。
    在本示例中,有一個讀取/寫入循環,可同時地獲取並處理窗口事件。waitKey(1000/fps)函數調用負責執行這個任務。在這個示例中,1000/fps 表示返回外部循環之前等待的毫秒數。盡管不精確,但對於錄制的視頻仍能獲取每秒幀數的一個近似度量。
  • void VideoCapture::release():這個函數釋放視頻文件或采集設備。盡管在本示例中沒有必要顯式地包含,但為了說明它的使用,示例中仍包含了這個函數。

 


免責聲明!

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



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