class CV_EXPORTS_W VideoCapture { public: /**1. @brief Default constructor @note In @ref videoio_c "C API", when you finished working with video, release CvCapture structure with cvReleaseCapture(), or use Ptr<CvCapture> that calls cvReleaseCapture() automatically in the destructor.
当结束采集时候,调用cvReleaseCapture函数释放资源 */ CV_WRAP VideoCapture(); /** 2.@overload @brief Opens a video file or a capturing device or an IP video stream for video capturing with API Preference @param filename it can be: - name of video file (eg. `video.avi`) - or image sequence (eg. `img_%02d.jpg`, which will read samples like `img_00.jpg, img_01.jpg, img_02.jpg, ...`) - or URL of video stream (eg. `protocol://host:port/script_name?script_params|auth`). Note that each video stream or IP camera feed has its own URL scheme. Please refer to the documentation of source stream to know the right URL.
打开.avi或者jpg图片的名 @param apiPreference preferred Capture API backends to use. Can be used to enforce a specific reader implementation if multiple are available: e.g. cv::CAP_FFMPEG or cv::CAP_IMAGES or cv::CAP_DSHOW. @sa The list of supported API backends cv::VideoCaptureAPIs
指定使用的读取的方式 */ CV_WRAP VideoCapture(const String& filename, int apiPreference = CAP_ANY); /** 3. @overload @brief Opens a camera for video capturing @param index id of the video capturing device to open. To open default camera using default backend just pass 0. (to backward compatibility usage of camera_id + domain_offset (CAP_*) is valid when apiPreference is CAP_ANY)
如果只有一个摄像头,则默认打开0
@param apiPreference preferred Capture API backends to use. Can be used to enforce a specific reader implementation if multiple are available: e.g. cv::CAP_DSHOW or cv::CAP_MSMF or cv::CAP_V4L. 读取的参数 @sa The list of supported API backends cv::VideoCaptureAPIs */ CV_WRAP VideoCapture(int index, int apiPreference = CAP_ANY); /** 4.@brief Default destructor The method first calls VideoCapture::release to close the already opened file or camera.
虚函数,用来调用 VideoCapture::release 来关闭文件或者摄像机 */ virtual ~VideoCapture(); /**5. @brief Opens a video file or a capturing device or an IP video stream for video capturing. @overload Parameters are same as the constructor VideoCapture(const String& filename, int apiPreference = CAP_ANY)
参数与VideoCapture相同 @return `true` if the file has been successfully opened The method first calls VideoCapture::release to close the already opened file or camera. */ CV_WRAP virtual bool open(const String& filename, int apiPreference = CAP_ANY); /** @brief Opens a camera for video capturing @6.overload 参数与 VideoCapture相同 Parameters are same as the constructor VideoCapture(int index, int apiPreference = CAP_ANY) @return `true` if the camera has been successfully opened. The method first calls VideoCapture::release to close the already opened file or camera. */ CV_WRAP virtual bool open(int index, int apiPreference = CAP_ANY); /** 7.@brief Returns true if video capturing has been initialized already. 判断VideoCapture是否初始化成功 If the previous call to VideoCapture constructor or VideoCapture::open() succeeded, the method returns true. */ CV_WRAP virtual bool isOpened() const; /** 8.@brief Closes video file or capturing device. The method is automatically called by subsequent VideoCapture::open and by VideoCapture destructor. 该方法在调用VideoCapture::open需要被调用,也被VideoCapture的析构函数调用 The C function also deallocates memory and clears *capture pointer. */ CV_WRAP virtual void release(); /** 9.@brief Grabs the next frame from video file or capturing device.
获取视频的下一帧以及采集设备中的一帧图像 @return `true` (non-zero) in the case of success. The method/function grabs the next frame from video file or camera and returns true (non-zero) in the case of success. The primary use of the function is in multi-camera environments, especially when the cameras do not have hardware synchronization. That is, you call VideoCapture::grab() for each camera and after that call the slower method VideoCapture::retrieve() to decode and get frame from each camera. This way the overhead on demosaicing or motion jpeg decompression etc. is eliminated and the retrieved frames from different cameras will be closer in time. Also, when a connected camera is multi-head (for example, a stereo camera or a Kinect device), the correct way of retrieving data from it is to call VideoCapture::grab() first and then call VideoCapture::retrieve() one or more times with different values of the channel parameter. @ref tutorial_kinect_openni */ CV_WRAP virtual bool grab(); /** 10.@brief Decodes and returns the grabbed video frame.
解码和返回抓取到的视频帧 @param [out] image the video frame is returned here. If no frames has been grabbed the image will be empty. @param flag it could be a frame index or a driver specific flag @return `false` if no frames has been grabbed The method decodes and returns the just grabbed frame. If no frames has been grabbed (camera has been disconnected, or there are no more frames in video file), the method returns false and the function returns an empty image (with %cv::Mat, test it with Mat::empty()). @sa read() @note In @ref videoio_c "C API", functions cvRetrieveFrame() and cv.RetrieveFrame() return image stored inside the video capturing structure. It is not allowed to modify or release the image! You can copy the frame using cvCloneImage and then do whatever you want with the copy. */ CV_WRAP virtual bool retrieve(OutputArray image, int flag = 0); /**11. @brief Stream operator to read the next video frame.
运算符用于获取视频中的某一个帧 @sa read() */ virtual VideoCapture& operator >> (CV_OUT Mat& image); /** @overload @sa read() */ virtual VideoCapture& operator >> (CV_OUT UMat& image); /** 13.@brief Grabs, decodes and returns the next video frame.
返回视频中的帧 @param [out] image the video frame is returned here. If no frames has been grabbed the image will be empty. @return `false` if no frames has been grabbed The method/function combines VideoCapture::grab() and VideoCapture::retrieve() in one call. This is the most convenient method for reading video files or capturing data from decode and returns the just grabbed frame. If no frames has been grabbed (camera has been disconnected, or there are no more frames in video file), the method returns false and the function returns empty image (with %cv::Mat, test it with Mat::empty()). @note In @ref videoio_c "C API", functions cvRetrieveFrame() and cv.RetrieveFrame() return image stored inside the video capturing structure. It is not allowed to modify or release the image! You can copy the frame using cvCloneImage and then do whatever you want with the copy. */ CV_WRAP virtual bool read(OutputArray image); /**14. @brief Sets a property in the VideoCapture.
设置VideoCapture的属性 @param propId Property identifier from cv::VideoCaptureProperties (eg. cv::CAP_PROP_POS_MSEC, cv::CAP_PROP_POS_FRAMES, ...) or one from @ref videoio_flags_others @param value Value of the property. @return `true` if the property is supported by backend used by the VideoCapture instance. @note Even if it returns `true` this doesn't ensure that the property value has been accepted by the capture device. See note in VideoCapture::get() */ CV_WRAP virtual bool set(int propId, double value); /** 15@brief Returns the specified VideoCapture property 设置VideoCapture的属性 @param propId Property identifier from cv::VideoCaptureProperties (eg. cv::CAP_PROP_POS_MSEC, cv::CAP_PROP_POS_FRAMES, ...) or one from @ref videoio_flags_others @return Value for the specified property. Value 0 is returned when querying a property that is not supported by the backend used by the VideoCapture instance. @note Reading / writing properties involves many layers. Some unexpected result might happens along this chain. @code {.txt} `VideoCapture -> API Backend -> Operating System -> Device Driver -> Device Hardware` @endcode The returned value might be different from what really used by the device or it could be encoded using device dependent rules (eg. steps or percentage). Effective behaviour depends from device driver and API Backend */ CV_WRAP virtual double get(int propId) const; /** @brief Returns used backend API name @note Stream should be opened. */ CV_WRAP String getBackendName() const; protected: Ptr<CvCapture> cap; Ptr<IVideoCapture> icap; };
以上为VideoCapture类的解析
#include <iostream> #include <string> #include <sstream> using namespace std; // OpenCV includes #include "opencv2/core.hpp" #include "opencv2/highgui.hpp" using namespace cv; // OpenCV command line parser functions // Keys accecpted by command line parser const char* keys = { "{help h usage ? | | print this message}" "{@video | | Video file, if not defined try to use webcamera}" }; int main( int argc, const char** argv ) { CommandLineParser parser(argc, argv, keys); parser.about("Chapter 2. v1.0.0"); //If requires help show if (parser.has("help")) { parser.printMessage(); return 0; } String videoFile= parser.get<String>(0); // Check if params are correctly parsed in his variables if (!parser.check()) { parser.printErrors(); return 0; } VideoCapture cap; //声明VideoCapture对象 if(videoFile != "") cap.open(videoFile); else cap.open("Recording3.webm"); if(!cap.isOpened()) // 判断VideoCapture是否打开成功 return -1; namedWindow("Video",1); for(;;) ///死循环”有两种写法:for(;;)和while(true), { Mat frame; ///声明Mat用于存储单帧的图像 cap >> frame; // 通过运算符>>获取单帧图像 if(frame.empty()) return 0; imshow("Video", frame); ///显示图像 if(waitKey(30) >= 0) break;///两帧显示的等待时间 } // Release the camera or video cap cap.release(); return 0; }
注意:摄像头访问下一帧所需的时间是根据摄像头的采集速度以及算法时间决定,例如FPS为20,即采集一帧需要50ms,算法处理时间小于10ms,则只需要等到40ms就ok