我們可以利用OpenCV讀取視頻文件或者攝像頭的數據,將其保存為圖像,以用於后期處理。下面的實例代碼展示了簡單的讀取和顯示操作:
1 // This is a demo introduces you to reading a video and camera 2 #include <iostream> 3 #include <string> 4 #include <sstream> 5 using namespace std; 6 7 // OpenCV includes 8 #include <opencv2/core.hpp> 9 #include <opencv2/highgui.hpp> 10 #include <opencv2/videoio.hpp> // for camera 11 using namespace cv; 12 13 // OpenCV command line parser functions 14 // Keys accepted by command line parser 15 const char* keys = 16 { 17 "{help h usage ? | | print this message}" 18 "{@video | | Video file, if not defined try to use webcamera}" 19 }; 20 21 int main(int argc, const char** argv) 22 { 23 CommandLineParser parser(argc, argv, keys); 24 parser.about("Reading a video and camera v1.0.0"); 25 26 // If requires help show 27 if (parser.has("help")) 28 { 29 parser.printMessage(); 30 return 0; 31 } 32 String videoFile = parser.get<String>(0); 33 34 // Check if params are correctly parsed in his variables 35 if (!parser.check()) 36 { 37 parser.printErrors(); 38 return 0; 39 } 40 41 VideoCapture cap; 42 if (videoFile != "") 43 { 44 cap.open(videoFile);// read a video file 45 }else { 46 cap.open(0);// read the default caera 47 } 48 if (!cap.isOpened())// check if we succeeded 49 { 50 return -1; 51 } 52 53 namedWindow("Video", 1); 54 while (1) 55 { 56 Mat frame; 57 cap >> frame; // get a new frame from camera 58 imshow("Video", frame); 59 if (waitKey(30) >= 0) break; 60 } 61 62 // Release the camera or video file 63 cap.release(); 64 return 0; 65 }
在我們解釋如何讀取視頻文件或者攝像頭輸入之前,我們需要首先介紹一個非常有用的新類,它可以用於幫助我們管理輸入的命令行參數,這個類在OpenCV 3.0中被引入,被稱為CommandLineParser類。
// OpenCV command line parser functions // Keys accepted by command line parser const char* keys = { "{help h usage ? | | print this message}" "{@video | | Video file, if not defined try to use webcamera}" };
對於一個命令行解析器(command-line parser)而言,我們首先需要做的事情就是在一個常量字符串向量中定義我們需要或者允許出現的參數列表。其中的每一行都有一個固定的模式:
{ name_param | default_value | description }
其中,name_param(參數名稱)參數之前可以添加“@”符號,用於定義將這個參數作為默認輸入。我們可以使用不止一個參數。
CommandLineParser parser(argc, argv, keys);
構造函數將會讀取主函數的輸入參數和之前定義好的參數作為一個默認輸入。
// If requires help show if (parser.has("help")) { parser.printMessage(); return 0; }
成員方法has()將會檢查指定的參數是否存在。在這個示例程序中,我們將會檢查用戶是否添加了“-h”、"-?"、“--help”或者"--usage"參數,如果有,然后使用printMessage()成員方法輸出所有的參數描述。
String videoFile = parser.get<String>(0);
使用get<typename>(name_param)函數,我們可以訪問和讀取輸入參數的任何內容。上一行程序代碼也可以寫成:
String videoFile = parser.get<String>("@video");
在獲取了所有需要的參數之后,我們可以檢查是否這些參數都已經被正確處理,如果其中有參數未能成功解析,則顯示一條錯誤信息。
// Check if params are correctly parsed in his variables if (!parser.check()) { parser.printErrors(); return 0; }
