官术网_书友最值得收藏!

1.5 視頻讀取與輸出

OpenCV中視頻的讀和寫操作,分別是通過cv::VideoCapture和cv::VideoWriter兩個類來實現的。

· 1.5.1 視頻讀取

cv::VideoCapture類是讀取視頻的,cv::VideoCapture既支持視頻文件的讀取,也支持從視頻捕捉設備中讀取視頻。cv::VideoCapture類的對象創建方式有以下3種。

cv::VideoCapture capture(const string& filename,);
// 第一種:從輸入文件名對應的文件中讀取
cv::VideoCapture capture(int device);
// 第二種:從視頻捕捉設備 ID中讀取視頻
cv::VideoCapture capture();
//第三種:調用無參構造函數創建對象

第一種方式是從文件(AVI格式或者MP4格式等)中讀取視頻,對象創建完成以后,OpenCV將會打開文件并準備讀取它。如果打開成功,將可以開始讀取視頻的幀,通過cv::VideoCapture類的成員函數isOpened()返回的true結果可以判斷打開讀取對象成功(建議在打開視頻或攝像頭時都使用該成員函數,以判斷是否打開成功)。

第二種方式是從視頻捕捉設備中讀取視頻。這種情況下,可以給出一個標識符,用于表示想要訪問的視頻捕捉設備,及其與操作系統的握手方式。對于視頻捕捉設備而言,這個標識符就是一個標識數字——如果只有一臺視頻捕捉設備,那么就是0,如果系統中有多臺視頻捕捉設備,那么增加標識數字的值即可。

第三種方式僅創建一個捕獲對象,而不提供任何關于打開的信息。對象創建以后通過成員函數open()來設定打開的信息。open()操作也有以下兩種方式。

cv::VideoCapture cap;
cap.open( "my_video.avi"); //第一種方式打開視頻文件
cap.open(0); //第二種方式打開視頻捕捉設備

打開視頻后,需要將視頻幀讀取到cv::Mat矩陣中,共有兩種方式,一種是read()操作,另一種是>>操作。示例如下。

cv::Mat frame;
cap.read(frame); //讀取方式一
cap >> frame; //讀取方式二

綜上,視頻的讀取操作步驟如下。

(1)創建cv::VideoCapture的對象。

cv::VideoCapture capture("D:/images/test1.mp4");

參數類型為const string&,即從文件中讀取,若設置為0則讀取視頻捕捉設備。

(2)驗證視頻讀取是否成功。

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

(3)驗證完成,開始讀取視頻。

cv::Mat frame;
capture >> frame;

用戶可以將VideoCapture對象像流一樣讀入Mat類型的對象(即圖像)中。

下面將創建例1-4來展示視頻文件的讀取操作。

例1-4:視頻文件讀取。

項目完整代碼文件(main.cpp文件)如下(需在1-4.pro文件中加入OpenCV配置信息,此處不再重復,詳情可參考例1-3)。

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{
VideoCapture capture("D:/images/test1.mp4");
if (!capture.isOpened())
{
cout << "Read video Failed !" << std::endl;
return -1;
}
Mat frame;
namedWindow("video test");
int frame_num = capture.get(cv::CAP_PROP_FRAME_COUNT);
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;
}
}
destroyWindow("video test"); //銷毀窗口
capture.release(); //釋放對象
return 0;
}

注意,上面的代碼中使用cv::VideoCapture類的成員函數get()和設定標識cv::CAP_PROP_FRAME_COUNT獲取了讀取視頻的總幀數。同樣,可以通過指定其他標識來獲取讀取視頻或視頻捕捉設備的其他屬性。

程序運行結果如圖1-51所示。

圖1-51 例1-4程序運行結果

· 1.5.2 視頻輸出

cv::VideoWriter類用于寫入視頻,該類使用起來比cv::VideoCapture類稍微復雜一些。cv::VideoWriter類的對象的創建有兩種方式,第一種是使用構造函數,第二種是使用open()函數,具體示例如下。

第一種方式。

     cv::VideoWriter out(
const string& filename, // 輸出文件名
int fourcc, // 編碼形式,使用 CV_FOURCC()宏
double fps, // 輸出視頻幀率
cv::Size frame_size, // 單幀圖像的大小
bool is_color = true // 如果是false,則可傳入灰度圖像,true為彩色圖像
);

第二種方式。

     cv::VideoWriter out;
out.open(
"my_video.mpg", //輸出文件名
CV_FOURCC('D','I','V','X'), // MPEG-4 編碼
30.0, // 輸出視頻幀率
cv::Size( 640, 480 ), // 單幀圖像分辨率為 640像素×480像素
true // 只可傳入彩色圖像,false為灰度圖像
);

其中需要注意的是FOURCC編碼形式,操作時常用以下函數把4個字符連接起來形成一個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-jpg codec。
  • CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec。
  • CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec。
  • CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec。

向創建的cv::VideoWriter對象寫入圖像也有兩種方式,即write()操作和<<操作,示例如下。

     cv::VideoWriter::write(
const Mat& image // 寫入圖像作為下一幀
);
out << frame;

下面通過創建例1-5展示完整的視頻讀取(同例1-4,需要在1-5.pro文件中加入OpenCV配置信息)、處理及輸出操作。

例1-5: 讀取視頻。

具體代碼如下。

#include<stdio.h>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{
Mat frame;
string filename = "D:/images/test1.mp4";
VideoCapture cap(filename);
VideoWriter out;
out.open("D:/images/out.mp4",
cv::VideoWriter::fourcc('D','I','V','X'),
cap.get(CAP_PROP_FPS),
Size(cap.get(CAP_PROP_FRAME_WIDTH),cap.get(CAP_PROP_FRAME_HEIGHT)),
true);
if (!cap.isOpened())
{
cout << "Video load failed!" << endl;
return -1;
}
while (1)
{
cap >> frame;
if (frame.empty())
{
cout << "Video process finished!" << endl;
return 0;
}
imshow("video",frame);
if (waitKey(10) == 'q') break;
out << frame;
}
cap.release();
return 0;
}

注意,上面的代碼中使用cv::VideoCapture類的成員函數get()和設定標識CAP_PROP_FPS獲取讀取視頻的幀率。標識CAP_PROP_FRAME_WIDTH和CAP_PROP_FRAME_HEIGHT分別表示獲取的視頻圖像的長度和寬度。

程序運行結果如圖1-52所示。

圖1-52 例1-5程序運行結果

主站蜘蛛池模板: 锡林浩特市| 名山县| 皋兰县| 永寿县| 邢台市| 南木林县| 沙雅县| 永靖县| 周至县| 中江县| 甘孜县| 元阳县| 嘉黎县| 会理县| 安龙县| 繁峙县| 榆社县| 邢台市| 株洲市| 湘乡市| 女性| 江安县| 胶南市| 吴堡县| 铁岭县| 仁怀市| 泰宁县| 永济市| 乐平市| 蕉岭县| 泸州市| 富平县| 彩票| 兴隆县| 甘洛县| 龙里县| 个旧市| 泸州市| 新营市| 桃园市| 林西县|