讀取影片(VideoCapture)

影片(video)是由連續的影像(image)組成,組成影片的影像稱為影格(frame),影片播放時會不斷呈現新的影格,影格間的時間稱作更新頻率(frame rate)。由於人類眼睛的結構,通常頻率高於每秒約12個影格的時候,就會認為是連貫的,而電影的拍攝及播放影格率通常為每秒24個影格,對一般人而言算可以接受,當然如果有更快的更新頻率,看起來會更流暢。

OpenCV有兩種影片來源,分別是讀取硬碟裡的影像檔,或者是用電腦鏡頭讀取的即時影像,兩者使用方式類似,皆使用OpenCV的VideoCapture物件進行這類型的操作,這邊介紹如何使用VideoCapture物件。


VideoCapture建構式

VideoCapture::VideoCapture()

VideoCapture::VideoCapture(const string& filename)

VideoCapture::VideoCapture(int device)

  • filename:影像檔名。
  • device:裝置(像攝影機)的編號。
  • 透過建構式不同的輸入參數,指定VideoCapture()的來源為影片檔或攝影機。

VideoCapture初始化

bool VideoCapture::open(const string& filename)

bool VideoCapture::open(int device)

  • 可以在建構式就指定來源,也可以先用VideoCapture()這個建構式,接著用open()設定來源。

bool VideoWriter::isOpened()

  • 檢查是否初始化成功,如果成功返回true,否則返回false。

VideoCapture讀取影像

讀取影像:VideoCapture& VideoCapture::operator>>(Mat& image)

讀取影像:bool VideoCapture::read(Mat& image)

  • 透過這個函式不斷讀取來源影格,把資訊寫進image。

VideoCapture影像格式

double VideoCapture::get(int propId)

  • 得到影像設定,propId代表返回哪個設定。

bool VideoCapture::set(int propId, double value)

  • 進行影像設定,propId代表針對哪個設定。

以下程式碼使用電腦的攝影機讀取影像,接著及時秀出影像,用VideoCapture::get()讀取影像的尺寸,waitKey(33)模擬每秒30個frame的效果:

#include <cstdio>
#include <opencv2/opencv.hpp>
using namespace cv;

int main(){
    VideoCapture video(0);
    if (!video.isOpened()){
        return -1;
    }
    Size videoSize = Size((int)video.get(CV_CAP_PROP_FRAME_WIDTH),(int)video.get(CV_CAP_PROP_FRAME_HEIGHT));
    namedWindow("video demo", CV_WINDOW_AUTOSIZE);
    Mat videoFrame;

    while(true){
        video >> videoFrame;
        if(videoFrame.empty()){
            break;
        }
        imshow("video demo", videoFrame);
        waitKey(33);
    }
    return 0;
}

VideoCapture


以下程式碼改為讀取avi檔播放,VideoCapture的建構式改為要讀取的avi檔的檔名:

#include <cstdio>
#include <opencv2/opencv.hpp>
using namespace cv;

int main(){
    VideoCapture video("VideoTest.avi");
    if (!video.isOpened()){
        return -1;
    }
    Size videoSize = Size((int)video.get(CV_CAP_PROP_FRAME_WIDTH),(int)video.get(CV_CAP_PROP_FRAME_HEIGHT));
    namedWindow("video demo", CV_WINDOW_AUTOSIZE);
    Mat videoFrame;

    while(true){
        video >> videoFrame;
        if( videoFrame.empty()){
            break;
        }
        imshow("video demo", videoFrame);
        waitKey(33);
    }
    return 0;
}

回到首頁

回到OpenCV教學


參考資料:

OpenCV 教程