OpenCV視頻讀取播放,視頻轉換為圖片
轉載請註明出處!!!
http://blog.csdn.net/zhonghuan1992
OpenCV視頻讀取播放,視頻轉換為圖片
介紹幾個有關視頻讀取的函數:
VideoCapture::VideoCapture
VideoCapture能夠從文件裏或者攝像頭中讀取視頻,這是提供給C++的接口的。C的接口是CvCapture結構。
<span style="white-space:pre"> </span>C++: VideoCapture::VideoCapture(conststring& filename) C++: VideoCapture::VideoCapture(int device)
上面是初始化VideoCapture對象的。第一個是從文件裏讀取。第二個是從設備中讀取,默認設備在這裏是0;
樣例:
<span style="white-space:pre"> </span>VideoCapturecapture(“sample.avi”); //讀取sample.avi文件 VideoCapturecapture(0);//假設僅僅有一個攝像頭。capture會得到攝像頭的視頻。
VideoCapture::Open
打開視頻文件或者視頻設備(比如攝像頭)。
C++:bool VideoCapture::open(const string& filename) C++:bool VideoCapture::open(int device)
樣例:
VideoCapturecapture; capture.open(“sample.avi”);//這裏的兩句等效於上面的VideoCapturecapture(“sample.avi”),capture.open(0);是一樣的
註意:
上面的視頻文件打開,用完後,最好調用capture.release();來關閉剛剛打開的文件
VideoCapture::release
C++: void VideoCapture::release()
調用該方法關閉剛剛打開的文件。
VideoCapture::isOpened
推斷視頻是否被打開。
C++:bool VideoCapture::open(const string& filename) C++:bool VideoCapture::open(int device)
成功打開,返回ture;否則false;
VideoCapture::grab
從視頻文件裏或者設備中獲取下一幀。
C++:bool VideoCapture::grab()
該方法成功調用返回ture。主要用於多攝像頭情況下,特別當那些攝像頭沒有實現硬件同步。
grab之後,須要調用retrive對獲取的幀進行解碼。
VideoCapture::retrieve
<span style="white-space:pre"> </span>C++:bool VideoCapture::retrieve(Mat& image, int channel=0)
對grab()得到的幀進行解碼。
VideoCapture::read
獲取,解碼。這種方法結合了grab和retrieve。這種方法比較方便,
C++:VideoCapture& VideoCapture::operator>>(Mat& image) C++: bool VideoCapture::read(Mat& image)
樣例1:
if(!capture.read(frame)) { cout<< "讀取視頻失敗" << endl; return-1; }
樣例2:
capture >>frame;
這兩個方法都可以。只是第一個可以推斷,建議使用第一個,程序更健壯。
VideoCapture::get
返回VideoCapture的一些屬性
C++: double VideoCapture::get(int propId)
probId能夠是以下的:
· CV_CAP_PROP_POS_MSEC Currentposition of the video file in milliseconds or video capture timestamp.
· CV_CAP_PROP_POS_FRAMES 0-basedindex of the frame to be decoded/captured next.
· CV_CAP_PROP_POS_AVI_RATIO Relativeposition of the video file: 0 - start of the film, 1 - end of the film.
· CV_CAP_PROP_FRAME_WIDTH Width of theframes in the video stream.
· CV_CAP_PROP_FRAME_HEIGHT Height ofthe frames in the video stream.
· CV_CAP_PROP_FPS Frame rate.
· CV_CAP_PROP_FOURCC 4-charactercode of codec.
· CV_CAP_PROP_FRAME_COUNT Number offrames in the video file.
· CV_CAP_PROP_FORMAT Format ofthe Mat objects returned by retrieve() .
· CV_CAP_PROP_MODE Backend-specificvalue indicating the current capture mode.
· CV_CAP_PROP_BRIGHTNESS Brightnessof the image (only for cameras).
· CV_CAP_PROP_CONTRAST Contrast ofthe image (only for cameras).
· CV_CAP_PROP_SATURATION Saturationof the image (only for cameras).
· CV_CAP_PROP_HUE Hue of theimage (only for cameras).
· CV_CAP_PROP_GAIN Gain of theimage (only for cameras).
· CV_CAP_PROP_EXPOSURE Exposure(only for cameras).
· CV_CAP_PROP_CONVERT_RGB Booleanflags indicating whether images should be converted to RGB.
· CV_CAP_PROP_WHITE_BALANCE Currentlynot supported
· CV_CAP_PROP_RECTIFICATION Rectificationflag for stereo cameras (note: only supported by DC1394 v 2.x backendcurrently)
VideoCapture::set
設置VideoCapture的屬性:
C++: bool VideoCapture::set(int propId, double value)
設置的probId和上面的get一樣。
以下的是視頻讀取和將視頻內的畫面轉化為圖片的代碼,裏面的凝視應該足夠解釋了。
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace std; using namespace cv; int main() { //打開視頻文件:事實上就是建立一個VideoCapture結構 VideoCapture capture("G:\\視頻分析入門練習\\視頻分析入門練習 - 附件\\sample.avi"); //檢測是否正常打開:成功打開時,isOpened返回ture if (!capture.isOpened()) cout << "fail toopen!"<< endl; //獲取整個幀數 long totalFrameNumber = capture.get(CV_CAP_PROP_FRAME_COUNT); cout << "整個視頻共" << totalFrameNumber << "幀" << endl; //設置開始幀() long frameToStart = 1; capture.set(CV_CAP_PROP_POS_FRAMES, frameToStart); cout << "從第" <<frameToStart << "幀開始讀" << endl; //設置結束幀 int frameToStop = 30; if (frameToStop < frameToStart) { cout << "結束幀小於開始幀,程序錯誤,即將退出!" << endl; return -1; } else { cout << "結束幀為:第" << frameToStop << "幀" << endl; } //獲取幀率 double rate = capture.get(CV_CAP_PROP_FPS); cout << "幀率為:" << rate<< endl; //定義一個用來控制讀取視頻循環結束的變量 bool stop = false; //承載每一幀的圖像 Mat frame; //顯示每一幀的窗體 namedWindow("Extractedframe"); //兩幀間的間隔時間: //int delay = 1000/rate; double delay = 1000 / rate; //利用while循環讀取幀 //currentFrame是在循環體中控制讀取到指定的幀後循環結束的變量 long currentFrame = frameToStart; //濾波器的核 int kernel_size = 3; Mat kernel = Mat::ones(kernel_size, kernel_size, CV_32F) / (float)(kernel_size*kernel_size); while (!stop) { //讀取下一幀 if(!capture.read(frame)) { cout << "讀取視頻失敗" << endl; return -1; } cout << "正在讀取第" << currentFrame << "幀" << endl; imshow("Extractedframe",frame); cout << "正在寫第" << currentFrame << "幀" << endl; stringstream str; str<<"sample" <<currentFrame << ".png"; cout << str.str() << endl; imwrite(str.str() , frame); //waitKey(intdelay=0)當delay≤ 0時會永遠等待。當delay>0時會等待delay毫秒 //當時間結束前沒有按鍵按下時,返回值為-1;否則返回按鍵 int c = waitKey(delay); //按下ESC或者到達指定的結束幀後退出讀取視頻 if ((char)c == 27 ||currentFrame > frameToStop) { stop = true; } //按下按鍵後會停留在當前幀,等待下一次按鍵 if (c >= 0) { waitKey(0); } currentFrame++; } //關閉視頻文件 capture.release(); waitKey(0); return 0; }
結果:
讀取後的圖片,由於圖片非常多。上面代碼在設置的時候,僅僅讀取了30幀
OpenCV視頻讀取播放,視頻轉換為圖片