OpenCV捕获视频和摄像头
從文件中捕獲視頻
其實使用OpenCV讀取視頻相當(dāng)簡單,只需要初始化一個VideoCapture對象,打開視頻文件,逐幀讀取。
程序
下面是簡單的OpenCV代碼:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #include <opencv2\highgui\highgui.hpp> #include <iostream> ? usingnamespace cv; usingnamespace std; ? intmain(intargc,?char**argv) { ????//打開視頻文件 ????VideoCapture cap("Girls'Generation.avi"); ????if(!cap.isOpened()) ????{ ????????cout <<?"不能打開視頻文件"<< endl; ????????return-1; ????} ????//從3000ms開始播放視頻 ????//cap.set(CV_CAP_PROP_POS_MSEC, 3000); ? ????//獲取視頻的幀速率 ????doublefps = cap.get(CV_CAP_PROP_FPS); ????cout <<?"幀/秒:"<< fps << endl; ? ????namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); ????while(true) ????{ ????????Mat frame; ????????//從視頻中讀取一個幀 ????????boolbSuccess = cap.read(frame); ????????if(!bSuccess) ????????{ ????????????cout <<"不能從視頻文件讀取幀"<< endl; ????????????break; ????????} ????????//在MyVideo窗口上顯示當(dāng)前幀 ????????imshow("MyVideo", frame); ????????//如果30ms沒有按下鍵,就返回-1,當(dāng)按下ESC鍵返回27 ????????if(waitKey(30)==27) ????????{ ????????????cout <<?"按下ESC鍵"<< endl; ????????????break; ????????} ????} ? ????return0; } |
解釋
| 1 | VideoCapture::VideoCapture(conststring& filename) |
這是VideoCapture類為數(shù)不多的構(gòu)造函數(shù)的一個。這個構(gòu)造函數(shù)打開視頻文件并為讀取視頻流初始化VideoCapture對象。
這個類的析構(gòu)函數(shù)會釋放對象關(guān)聯(lián)的所有內(nèi)存。因此,不需要在程序中顯示的釋放內(nèi)存。
| 1 | boolVideoCapture::IsOpened() |
如果調(diào)用VideoCapture構(gòu)造函數(shù)成功,這個方法返回true,否則返回false。
檢查VideoCapture初始化是否成功是有必要的。如果失敗,程序應(yīng)該退出,否則當(dāng)從VideoObject中讀取幀的時候,程序就會崩潰了。
| 1 | boolVideoCapture::set(intpropId,?doublevalue) |
這個方法改變VideoObject對象的屬性,如果成功,返回true,否則返回false。你應(yīng)該在你的代碼中嘗試修改視頻流的一些屬性。在我的代碼中,我改變了CV_CAP_PROP_POS_MSEC屬性。
它的參數(shù):
- int propID –?這個參數(shù)指定你要更改的屬性。這個參數(shù)有很多可選項,這里列出一部分。
- CV_CAP_PROP_POS_MSEC – 視頻的當(dāng)前位置(毫秒)
- CV_CAP_PROP_POS_FRAMES –?視頻的當(dāng)前位置(幀)
- CV_CAP_PROP_FRAME_WIDTH – 視頻流的寬度
- CV_CAP_PROP_FRAME_HEIGHT – 視頻流的高度
- CV_CAP_PROP_FPS – 幀速率(幀/秒)
- CV_CAP_PROP_FOURCC?– 編碼器的四字符編碼
- double value – 給propID分配的值。
| 1 | doubleVideoCapture::get(intpropId) |
這個函數(shù)返回指定的propId的屬性值。它的可選項和set函數(shù)的propID一樣。
| 1 | boolVideoCapture::read(Mat& image); |
這個函數(shù)抓取視頻的下一幀,解碼并存儲在‘image’變量中。在這個函數(shù)內(nèi)部會調(diào)用VideoCapture::grap()和VideoCapture::retrieve()。可以使用這2個函數(shù)代替VideoCapture::read()函數(shù)。如果操作成功,返回true,否則返回false。
| 1 | waitKey(30) |
這個函數(shù)等待30毫秒。如果在指定的時間按下鍵,它會返回鍵的ASCII值。如果這個值是27,程序就會執(zhí)行if塊。如果在30毫秒內(nèi)沒有按下鍵,程序返回-1,程序繼續(xù)while循環(huán)。
| 1 | VideoCapture::~VideoCapture() |
VideoCapture對象的析構(gòu)函數(shù)會釋放對象所有關(guān)聯(lián)的內(nèi)存。在程序退出main方法時,析構(gòu)函數(shù)會隱式調(diào)用。
總結(jié)
首先,這個程序從文件中捕獲一個視頻,然后進(jìn)入一個無限循環(huán)。在這個循環(huán)中,它從捕獲的視頻中連續(xù)地抓取幀,解碼,然后顯示在窗口中并等待30毫秒。如果視頻沒有更多的幀或按下了ESC鍵,程序就會跳出無限循環(huán)。
注意:使用waitKey(int)函數(shù)非常重要,因為imshow(string&, MAT)函數(shù)需要時間在窗口上繪制圖像,正是waitKey(int)提供了這個時間。
從攝像頭中采集視頻
程序
下面的程序和上面的最大不同是VideoCapture構(gòu)造函數(shù)的參數(shù)。這里我給VideoCapture的構(gòu)造函數(shù)提供攝像頭的編號來代替一個文件名。下面是OpenCV代碼:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #include <opencv2\highgui\highgui.hpp> #include <iostream> ? usingnamespace cv; usingnamespace std; ? intmain(intargc,?char**argv) { ????// 打開第1個攝像頭 ????VideoCapture cap(0); ? ????if(!cap.isOpened()) ????{ ????????cout <<?"不能打開攝像頭!"<< endl; ????????return-1; ????} ? ????//獲取視頻幀的寬度 ????doubledWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); ????//獲取視頻幀的高度 ????doubledHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); ? ????cout <<?"視頻幀尺寸 : "<< dWidth <<?" x "<< dHeight << endl; ? ????namedWindow("MyVideo", CV_WINDOW_AUTOSIZE); ? ????while(1) ????{ ????????Mat frame; ? ????????boolbSuccess = cap.read(frame); ? ????????if(!bSuccess) ????????{ ????????????cout <<?"不能從視頻流中讀取幀!"<< endl; ????????????break; ????????} ? ????????imshow("MyVideo", frame); ? ????????if(waitKey(30) == 27) ????????{ ????????????cout <<?"ESC鍵被按下"<< endl; ????????????break; ????????} ????} ????return0; ? } |
解釋
| 1 | VideoCapture::VideoCapture(intdevice) |
這是VideoCapture 3個構(gòu)造函數(shù)的一個。這個構(gòu)造函數(shù)打開給定編號的攝像頭并為讀取攝像頭的視頻流初始化VideoCapture對象。這里的“0”表示使用編號為0的攝像頭。如果你的電腦上有多個攝像頭,可以使用1,2,3…代替0。
| 1 | doubledWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH) |
這個函數(shù)獲取攝像頭輸出幀的寬(像素)
| 1 | doubledHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT) |
這個函數(shù)獲取攝像頭輸出幀的高(像素)
其他所有的函數(shù)都跟第一個程序中一樣。
總結(jié)
以上是生活随笔為你收集整理的OpenCV捕获视频和摄像头的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 保存处理后的视频文件
- 下一篇: error C3861: “setw”: