Search…

Đọc Camera và Video với VideoCapture trong OpenCV

08/11/20206 min read
Hướng dẫn đọc và xử lý video từ Camera và Video bằng VideoCapture trong OpenCV.

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/

IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024