影片(video)是由連續的影像(image)組成,組成影片的影像稱為影格(frame),影片播放時會不斷呈現新的影格,影格間的時間稱作更新頻率(frame rate)。由於人類眼睛的結構,通常頻率高於每秒約12個影格的時候,就會認為是連貫的,而電影的拍攝及播放影格率通常為每秒24個影格,對一般人而言算可以接受,當然如果有更快的更新頻率,看起來會更流暢。
OpenCV有兩種影片來源,分別是讀取硬碟裡的影像檔,或者是用電腦鏡頭讀取的即時影像,兩者使用方式類似,皆使用OpenCV的VideoCapture物件進行這類型的操作,這邊介紹如何使用VideoCapture物件。
VideoCapture::VideoCapture()
VideoCapture::VideoCapture(const string& filename)
VideoCapture::VideoCapture(int device)
filename:影像檔名。device:裝置(像攝影機)的編號。透過建構式不同的輸入參數,指定VideoCapture()的來源為影片檔或攝影機。bool VideoCapture::open(const string& filename)
bool VideoCapture::open(int device)
可以在建構式就指定來源,也可以先用VideoCapture()這個建構式,接著用open()設定來源。bool VideoWriter::isOpened()
檢查是否初始化成功,如果成功返回true,否則返回false。讀取影像:VideoCapture& VideoCapture::operator>>(Mat& image)
讀取影像:bool VideoCapture::read(Mat& image)
透過這個函式不斷讀取來源影格,把資訊寫進image。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; }以下程式碼改為讀取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; }
转自:http://monkeycoding.com/?p=649