Building Computer Vision Projects with OpenCV 4 and C++
上QQ阅读APP看书,第一时间看更新

Reading videos and cameras

This section introduces you to video and camera reading using this simple example. Before explaining how to read videos or camera input, we want to introduce a new, very useful class that helps us to manage the input command-line parameters. This new class was introduced in OpenCV version 3.0, and is the CommandLineParser class:

// 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}" 
}; 

The first thing that we have to do for CommandLineParser is define what parameters we need or allow in a constant char vector; each line has the following pattern:

"{name_param | default_value | description}"

name_param can be preceded with @, which defines this parameter as a default input. We can use more than one name_param:

CommandLineParser parser(argc, argv, keys);

The constructor will get the inputs of the main function and the key constants defined previously:

//If requires help show 
if (parser.has("help")) 
{ 
       parser.printMessage(); 
       return 0; 
} 

The .has class method checks the existence of the parameter. In the sample, we check whether the user adds the parameter help or ?, and then use the class function printMessage to show all the description parameters:

   String videoFile= parser.get<String>(0);

With the .get<typename>(parameterName) function, we can access and read any of input parameters:

   // Check if params are correctly parsed in his variables 
   if (!parser.check()) 
   { 
       parser.printErrors(); 
       return 0; 
   } 

After obtaining all the requisite parameters, we can check whether these parameters are parsed correctly and show an error message if one of the parameters was not parsed, for example, add a string instead of a number:

VideoCapture cap; // open the default camera 
if(videoFile != "") 
   cap.open(videoFile); 
else 
   cap.open(0); 
if(!cap.isOpened())  // check if we succeeded 
   return -1;  

The class for video reading and camera reading is the same: the VideoCapture class that belongs to the videoio submodule instead of the highgui submodule, as in the previous version of OpenCV. After creating the object, we check whether the input command-line parameter videoFile has a path filename. If it's empty, then we try to open a web camera; if it has a filename, then open the video file. To do this, we use the open function, giving as a parameter the video filename or the index camera that we want to open. If we have a single camera, we can use 0 as a parameter.

To check whether we can read the video filename or the camera, we use the isOpened function:

namedWindow("Video",1); 
for(;;) 
{ 
    Mat frame; 
    cap >> frame; // get a new frame from camera 
    if(frame) 
       imshow("Video", frame); 
    if(waitKey(30) >= 0) break; 
} 
// Release the camera or video cap 
cap.release(); 

Finally, we create a window to show the frames with the namedWindow function and, with an infinite loop, we grab each frame using the >> operation and show the frame with the imshow function if we retrieve the frame correctly. In this case, we don't want to stop the application, but will wait 30 milliseconds to check whether any users want to stop the application execution with any key using waitKey(30).

The time required to wait for the next frame using camera access is calculated from the camera speed and our spent algorithm time. For example, if a camera works at 20 fps, and our algorithm spent 10 milliseconds, a great waiting value is 30 = ( 1000/ 20) - 10 milliseconds. This value is calculated considering a wait of a sufficient amount of time to ensure that the next frame is in the buffer. If our camera takes 40 milliseconds to take each image, and we use 10 milliseconds in our algorithm, then we only need to stop with waitKey 30 milliseconds, because 30 milliseconds of wait time, plus 10 milliseconds of our algorithm, is the same amount of time for which each frame of the camera is accessible.

When the user wants to finish the application, all they have to do is press any key and then we have to release all video resources using the release function.

It is very important to release all resources that we use in a computer vision application. If we do not, we can consume all RAM memory. We can release the matrices using the release function.

The result of the previous code is a new window showing a video or web camera in BGR format.