使用cv::VideoCapture類讀取視頻文件、使用cv::VideoWriter類寫入視頻文件,使用思路和方法與C++中處理文件的fstream文件流方法類似。
完整流程如下(各別步驟可以省略或合併):
1、創建對象;
2、與文件綁定 (1,2步也可以通過構造函數合併到一起完成);
3、讀取(析取)或寫入;
- 對於讀取,VideoCapture中重載的運算符 >> 析取器每次讀取一幀 (文件流fstream中重載的 >> 析取器每次讀取直到遇到空格或換行符)
- 對於寫入,VideoCapture中重載的運算符 << 每次向VideoCapture對象中寫入一幀。
4、釋放對象 (調用release()成員函數)
讀取視頻的代碼範例如下:
cv::VideoCapture cap; //創建VideoCapture對象
cap.open("my_video_dir.avi"); //將視頻文件綁定到所創建的VideoCapture對象上
if(!cap.isOpened()){ //檢查是否能正常打開視頻文件
std::cout<<"fail to open video"<<std::endl;
}
cv::Mat frame;
while(true){
//方法一:>>析取器
cap>>frame; //每個循環從cap中解析一幀,賦給frame,
//方法二:read()成員函數
cap.read(frame); //與cap>>frame等價
//方法三:使用grab()與retrieve()的組合,其中grab()只是完成把圖像拷入buffer,不做圖像的解碼,有時想快速定位圖像時可以使用grab()快速“跳過”不感興趣的幀。retrieve()完成圖像解碼。
cap.grab();
cap.retrieve(frame);
if(frame.empty()) break; //直到capt中圖像全部被解析完成,跳出循環
/* do anything to frame */
cv::imshow("Frame after processing",frame); //顯示圖像
cv::waitKey(3); //暫停3ms
if(cv::waitKey(3)==27) break; //等待3ms,且如果在這段時間內按Esc鍵(ASCII碼爲27),退出
if(cv::waitKey(1)==23) cv::waitKey(0); //等待1ms,如果按空格鍵Space(ASCII碼爲23),暫停(waitKey(0)表示一直等待)
}
cap.release();
寫入視頻代碼範例如下:
cv::VideoWriter output;
out.open("path_to_save_video.avi",CV_FOURCC('M','J','P','G'),30,cv::Size(1280,760));
if(!output.isOpened()){
std::cout<<"fail to open"<<std::endl;
}
方法一:
output<<frame; //frame爲準備寫入的圖像
方法二:
output.write(frame);
/* write as many frames as you want */
output.release();