Giới thiệu
Thông thường khi làm việc với OpenCV, đầu vào là hình ảnh hoặc các tập hình ảnh. Vậy làm sao lấy được các frame trong video thông qua camera hay đọc frame từ file video?
Khá hay là thư viện OpenCV có cung cấp 1 class là VideoCapture
có chức năng capturing video từ camera, đọc video từ file video hay từ 1 tập các hình ảnh.
Lấy video frame từ camera với VideoCapture
// // main.cpp // OpenCVTest // // Created by NguyenNghia on 11/11/16. // Copyright © 2016 nguyennghia. All rights reserved. // #include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; int main(int argc, const char * argv[]) { // class represent for capturing video from camera and reading video file or image sequences VideoCapture videoCapture; Mat videoFrame; // open camera videoCapture.open(0); namedWindow("VideoCapture", WINDOW_AUTOSIZE); // check open camera open sucessed or failed if(!videoCapture.isOpened()) { cout << "Can't open camera" << endl; } else { while (true) { //read video frame from camera and show in windows videoCapture.read(videoFrame); imshow("VideoCapture", videoFrame); if(waitKey(30) >= 0) break; } } return 0; }
Các bước làm việc với VideoCapture trong OpenCV
Bước 1: Khởi tạo đối tượng VideoCapture
và mở camera với tham số truyền vào là flags với các giá trị dưới đây, được định nghĩa trong OpenCV. Nếu máy tính có 1 camera thì hãy truyền vào 0 để OpenCV tự nhận dạng và mở đúng camera đó.
// Camera API enum { CAP_ANY = 0, // autodetect CAP_VFW = 200, // platform native CAP_V4L = 200, CAP_V4L2 = CAP_V4L, CAP_FIREWARE = 300, // IEEE 1394 drivers CAP_FIREWIRE = CAP_FIREWARE, CAP_IEEE1394 = CAP_FIREWARE, CAP_DC1394 = CAP_FIREWARE, CAP_CMU1394 = CAP_FIREWARE, CAP_QT = 500, // QuickTime CAP_UNICAP = 600, // Unicap drivers CAP_DSHOW = 700, // DirectShow (via videoInput) CAP_PVAPI = 800, // PvAPI, Prosilica GigE SDK CAP_OPENNI = 900, // OpenNI (for Kinect) CAP_OPENNI_ASUS = 910, // OpenNI (for Asus Xtion) CAP_ANDROID = 1000, // Android - not used CAP_XIAPI = 1100, // XIMEA Camera API CAP_AVFOUNDATION = 1200, // AVFoundation framework for iOS (OS X Lion will have the same API) CAP_GIGANETIX = 1300, // Smartek Giganetix GigEVisionSDK CAP_MSMF = 1400, // Microsoft Media Foundation (via videoInput) CAP_WINRT = 1410, // Microsoft Windows Runtime using Media Foundation CAP_INTELPERC = 1500, // Intel Perceptual Computing SDK CAP_OPENNI2 = 1600, // OpenNI2 (for Kinect) CAP_OPENNI2_ASUS = 1610, // OpenNI2 (for Asus Xtion and Occipital Structure sensors) CAP_GPHOTO2 = 1700, // gPhoto2 connection CAP_GSTREAMER = 1800, // GStreamer CAP_FFMPEG = 1900, // FFMPEG CAP_IMAGES = 2000 // OpenCV Image Sequence (e.g. img_%02d.jpg) };
Bước 2: Kiểm tra đã mở camera thành công hay chưa thông qua phương thức isOpen
.
Bước 3: Nếu mở video thành công thì dùng vòng lặp vô tận để lấy video frame từ camera thông qua phương thức read()
để nhận video frame thông qua thể hiện của class Mat
(cấu trúc dữ liệu lưu trữ dữ liệu hình ảnh trong OpenCV). Từ video frame này có thể áp dụng các thuật toán để xử lý theo ý muốn.
Bước 4. Kết thúc chương trình.
Đọc video từ file với VideoCapture
// // main.cpp // OpenCVTest // // Created by NguyenNghia on 11/11/16. // Copyright © 2016 nguyennghia. All rights reserved. // #include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; #define INPUT "input_video.mp4" int main(int argc, const char * argv[]) { VideoCapture videoCapture; Mat videoFrame; videoCapture.open(INPUT); namedWindow("VideoCapture", WINDOW_AUTOSIZE); if(!videoCapture.isOpened()) { cout << "Can't open camera" << endl; } else { while (true) { videoCapture.read(videoFrame); imshow("VideoCapture", videoFrame); if(waitKey(30) >= 0) break; } } return 0; }
Cũng giống với việc lấy video frame từ camera nhưng với cách đọc video frame, truyền đối số vào phương thức open
là tên của file video.
Các phương thức lấy ra các thuộc tính của video frame
Phương thứ get
của VideoCapture
cho phép lấy ra các thuộc tính của video frame.
double VideoCapture::get(int propId)
Với propID
là các giá trị dưới đây (được giữ nguyên thủy phần chút thích bằng tiếng Anh).
CV_CAP_PROP_POS_MSEC
Current position of the video file in milliseconds or video capture timestamp.CV_CAP_PROP_POS_FRAMES
0-based index of the frame to be decoded/captured next.CV_CAP_PROP_POS_AVI_RATIO
Relative position of the video file: 0 – start of the film, 1 – end of the film.CV_CAP_PROP_FRAME_WIDTH
Width of the frames in the video stream.CV_CAP_PROP_FRAME_HEIGHT
Height of the frames in the video stream.CV_CAP_PROP_FPS
Frame rate.CV_CAP_PROP_FOURCC
4-character code of codec.CV_CAP_PROP_FRAME_COUNT
Number of frames in the video file.CV_CAP_PROP_FORMAT
Format of the Mat objects returned by retrieve() .CV_CAP_PROP_MODE
Backend-specific value indicating the current capture mode.CV_CAP_PROP_BRIGHTNESS
Brightness of the image (only for cameras).CV_CAP_PROP_CONTRAST
Contrast of the image (only for cameras).CV_CAP_PROP_SATURATION
Saturation of the image (only for cameras).CV_CAP_PROP_HUE
Hue of the image (only for cameras).CV_CAP_PROP_GAIN
Gain of the image (only for cameras).CV_CAP_PROP_EXPOSURE
Exposure (only for cameras).CV_CAP_PROP_CONVERT_RGB
Boolean flags indicating whether images should be converted to RGB.CV_CAP_PROP_WHITE_BALANCE_U
The U value of the whitebalance setting (note: only supported by DC1394 v 2.x backend currently).CV_CAP_PROP_WHITE_BALANCE_V
The V value of the whitebalance setting (note: only supported by DC1394 v 2.x backend currently).CV_CAP_PROP_RECTIFICATION
Rectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend currently).CV_CAP_PROP_ISO_SPEED
The ISO speed of the camera (note: only supported by DC1394 v 2.x backend currently).CV_CAP_PROP_BUFFERSIZE
Amount of frames stored in internal buffer memory (note: only supported by DC1394 v 2.x backend currently).
Viết lại chương trình trên như sau:
// // main.cpp // OpenCVTest // // Created by NguyenNghia on 11/11/16. // Copyright © 2016 nguyennghia. All rights reserved. // #include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; #define INPUT "input_video.mp4" int main(int argc, const char * argv[]) { VideoCapture videoCapture; Mat videoFrame; videoCapture.open(INPUT); namedWindow("VideoCapture", WINDOW_AUTOSIZE); if(!videoCapture.isOpened()) { cout << "Can't open camera" << endl; } else { while (true) { videoCapture.read(videoFrame); imshow("VideoCapture", videoFrame); cout << "FPS: " << videoCapture.get(CV_CAP_PROP_FPS) << endl; cout << "FRAME_COUNT: " << videoCapture.get(CV_CAP_PROP_FRAME_COUNT) << endl; cout << "FRAME_WIDTH: " << videoCapture.get(CV_CAP_PROP_FRAME_WIDTH) << endl; cout << "FRAME_HEIGHT: " <<videoCapture.get(CV_CAP_PROP_FRAME_HEIGHT) << endl; cout << "CODEC: " << videoCapture.get(CV_CAP_PROP_FOURCC) << endl; cout << "AVI_RATION: " <<videoCapture.get(CV_CAP_PROP_POS_AVI_RATIO) << endl; if(waitKey(30) >= 0) break; } } return 0; }
Và 1 đoạn log xuất ra như dưới đây:
FPS: 29.97 FRAME_COUNT: 10444.1 FRAME_WIDTH: 1152 FRAME_HEIGHT: 720 CODEC: 0 AVI_RATION: 0.00612786 FPS: 29.97 FRAME_COUNT: 10444.1 FRAME_WIDTH: 1152 FRAME_HEIGHT: 720 CODEC: 0 AVI_RATION: 0.0062236 FPS: 29.97 FRAME_COUNT: 10444.1 FRAME_WIDTH: 1152 FRAME_HEIGHT: 720 CODEC: 0 AVI_RATION: 0.00631935 FPS: 29.97 FRAME_COUNT: 10444.1 FRAME_WIDTH: 1152 FRAME_HEIGHT: 720 CODEC: 0 AVI_RATION: 0.0064151 FPS: 29.97 FRAME_COUNT: 10444.1 FRAME_WIDTH: 1152 FRAME_HEIGHT: 720 CODEC: 0 AVI_RATION: 0.00651085 FPS: 29.97 FRAME_COUNT: 10444.1 FRAME_WIDTH: 1152 FRAME_HEIGHT: 720 CODEC: 0 AVI_RATION: 0.0066066
* Ngoài ra 1 thư viện xử lý video rất phổ biến khác, được sử dụng rất nhiều là FFmpeg, có thể tìm hiểu thông qua trang chủ: https://ffmpeg.org/