1. 程式人生 > >OpenCV視頻讀取播放,視頻轉換為圖片

OpenCV視頻讀取播放,視頻轉換為圖片

character capture clas 等待 del only _for lis ostream

轉載請註明出處!!!

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視頻讀取播放,視頻轉換為圖片