【OpenCV3】視訊讀寫cv::VideoCapture和cv::VideoWriter
阿新 • • 發佈:2019-01-07
OpenCV3和OpenCV2類似,視訊的讀、寫操作,分別通過cv::VideoCapture和cv::VideoWriter兩個類來實現。
1、視訊的讀取操作cv::VideoCapture
cv::VideoCapture既支援視訊檔案的讀取,也支援從攝像機中視訊的讀取。cv::VideoCapture物件的建立方式有以下三種:
- cv::VideoCapture capture(
- const string& filename, // 輸入檔名
- );
-
cv::VideoCapture capture(
- int device // 視訊捕捉裝置 id
- );
- cv::VideoCapture capture();
第二種方式是從攝像機中讀取視訊,這種情況下,我們會給出一個識別符號,用於表示我們想要訪問的攝像機,及其與作業系統的握手方式。對於攝像機而言,這個標誌符就是一個標誌數字——如果只有1個攝像機,那麼就是0,如果系統中有多個攝像機,那麼只要將其向上增加即可。識別符號另外一部分是攝像機域(camera
domain),用於表示攝像機的型別,這個域值可以是下面任一預定義常量。
以這種方式建立視訊捕獲物件時,我們所傳遞的識別符號是域索引和攝像機索引的和。例如:
[cpp] view plain copy print?- cv::VideoCapture capture(cv::CAP_IEEE1394 + 1);
這個例子中cv::VideoCapture將嘗試開啟第2個(編號從0開始)1394攝像機。多數情況下,由於我們只有一個攝像機,因此沒必要指定攝像機的域,此時使用cv::CAP_ANY是一種高效的方式(也即是0,所以不用特意指定)。
第三種方式僅僅建立一個捕獲物件,而不提供任何關於開啟的資訊。建立以後通過成員函式open()來設定開啟的資訊。open()操作也有以上兩種方式。
- cv::VideoCapture cap;
- cap.open( "my_video.avi" );
將視訊幀讀取到cv::Mat矩陣中,有兩種方式:一種是read()操作;另一種是 “>>”操作。 [cpp] view plain copy print?
- cv::Mat frame;
- cap.read(frame); //讀取方式一
- cap >> frame; //讀取方式二
下面是讀取視訊並顯示的示例程式碼: [cpp] view plain copy print?
- #include <opencv2/opencv.hpp>
- #include <iostream>
- void video_capture_test()
- {
- cv::VideoCapture capture("test.mp4");
- if (!capture.isOpened())
- {
- std::cout << "Read video Failed !" << std::endl;
- return;
- }
- cv::Mat frame;
- cv::namedWindow("video test");
- int frame_num = capture.get(cv::CAP_PROP_FRAME_COUNT);
- std::cout << "total frame number is: " << frame_num << std::endl;
- for (int i = 0; i < frame_num - 1; ++i)
- {
- capture >> frame;
- //capture.read(frame); 第二種方式
- imshow("video test", frame);
- if (cv::waitKey(30) == 'q')
- {
- break;
- }
- }
- cv::destroyWindow("video test");
- capture.release();
- return;
- }
上面的程式碼,我們使用了cv::VideoCapture的成員函式get()並設定標識cv::CAP_PROP_FRAME_COUNT獲取了讀取視訊的幀總數。同樣,我們可以指定其他標識,來獲取讀取視訊或攝像頭的其他屬性。另外,我們也可以使用成員函式set(),設定相應屬性的值。cv::VideoCapture中提供的屬性標識如下圖所示。
2、視訊的寫操作cv::VideoWriter
cv::VideoWriter物件的建立有兩種方式,第一種是使用建構函式的形式,第二種使用open()的方式,具體如下:
- cv::VideoWriter out(
- const string& filename, // 輸入檔名
- int fourcc, // 編碼形式,使用 CV_FOURCC()巨集
- double fps, // 輸出視訊幀率
- cv::Size frame_size, // 單幀圖片的大小
- bool is_color = true// 如果是false,可傳入灰度影象
- );
- cv::VideoWriter out;
- out.open(
- "my_video.mpg", //輸出檔名
- CV_FOURCC('D','I','V','X'), // MPEG-4 編碼
- 30.0, // 幀率 (FPS)
- cv::Size( 640, 480 ), // 單幀圖片解析度為 640x480
- true// 只輸入彩色圖
- );
同樣,向建立後的cv::VideoWriter物件寫入影象也有兩種方式,即write()操作和“<<”操作: [cpp] view plain copy print?
- cv::VideoWriter::write(
- const Mat& image // 寫入影象作為下一幀
- );
- my_video_writer << my_frame;