1. 程式人生 > >opencv從入門到精通(1)-建立自己的視訊播放器

opencv從入門到精通(1)-建立自己的視訊播放器

本文預設你已經成功配置opencv並具有一定的c++基礎,後續將由淺入深地介紹如何運用opencv進行影象處理與機器學習的具體實踐,在熟悉opencv的同時也能對相關理論有更深刻的理解。opencv的具體配製方法參見:http://www.cnblogs.com/woshitianma/p/3853447.html

第一個程式——展示一個影象

 c++中通過檔案流可以將影象從磁碟中讀入,處理後再輸出到磁碟,但無法在螢幕上顯示,運用opencv中的HighGUI工具箱則可以達到螢幕上及時顯示的效果。
 首先在visual studio中建立一個空的win32專案,新建一個cpp檔案,輸入下面的程式碼,並將影象檔案放到專案的檔案目錄中。在解決方案資源管理器中可以開啟專案所在資料夾。

dfg
程式碼如下:

   #include<iostream>  
    #include <opencv2/core/core.hpp>  
    #include <opencv2/highgui/highgui.hpp>  

    using namespace cv;  

    int main()  
    {
        IplImage* img = cvLoadImage("a1.ppm");
            //IplImage是opencv中處理影象的資料結構,支援所有影象格式。
            //cvLoadImage函式讀入影象"a1.ppm",返回一個指標變數。
cvNamedWindow("Example1",CV_WINDOW_AUTOSIZE); //cvNamedWindow函式建立一個名為"Example1"的視窗,第二個參 //數CV_WINDOW_AUTOSIZE表示視窗大小自動調整與影象大小相同 cvShowImage("Example1",img); //cvShowImage將影象img在視窗Example中顯示出來。 cvWaitKey(0); //cvWaitKey函式功能是等待雙擊事件,雙擊後退出。 cvReleaseImage(&img);//釋放影象記憶體
cvDestroyWindow("Example1");//釋放視窗記憶體 }

第二個程式-展示AVI視訊

具體情形與影象差不多,但要設定一個迴圈來讀取每一幅畫面,同時能在視訊結束或者你不想看時退出迴圈。
程式碼:
   #include<iostream>  
    #include <opencv2/core/core.hpp>  
    #include <opencv2/highgui/highgui.hpp>  

    using namespace cv;  

    int main()  
    { 

        cvNamedWindow("Example2",CV_WINDOW_AUTOSIZE);//建立視窗
        CvCapture* capture=cvCreateFileCapture("a2.mp4");
    //cvCreateFileCapture函式作用是載入視訊"a2.mp4"並返回指標到
        //視訊資料結構CvCapture建立的變數capture中,這時capture便包含視訊    //中的所有資訊。
        IplImage* frame;//建立變數frame
        while(1){
            frame=cvQueryFrame(capture);/*cvQueryFrame的引數為CvCapture結構的指標。用來將下一幀視訊檔案載入記憶體,返回一個對應當前幀的指標。與cvLoadImage不同的是cvLoadImage為影象分配記憶體空間,而cvQueryFrame使用已經在cvCapture結構中分配好的記憶體。*/
            if(!frame) break;//frame為空時退出迴圈
            cvShowImage("Example2",frame);//顯示當前畫面
            char c=cvWaitKey(33);//等待33毫秒,如有按鍵,將值賦給c
            if(c==27) break;/*如果按鍵是“Esc”鍵(ASCLL 27),結束迴圈*/
        }
        cvReleaseCapture(&capture);
        cvDestroyWindow("Example2");
    } 

簡單的視訊播放器

接下來介紹cvSetCaptureProperty等函式在視訊播放中加入進度條,這樣就可以取得調戲自己家的進度條成就了。程式碼及註釋如下:
#include <stdio.h>
#include <fstream>
#include<iostream>  
    #include <opencv2/core/core.hpp>  
    #include <opencv2/highgui/highgui.hpp>  

    using namespace cv;
    using namespace std;



int        g_slider_position = 0;
CvCapture* g_capture         = NULL;
//定義onTrackbarSlide回撥函式來輸入滾動條的位置pos
void onTrackbarSlide(int pos) {
    cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);
    /*cvSetCaptureProperty函式用於設定capture結構的各種屬性,CV_CAP_PROP_POS_FRAMES表示以幀數來設定讀入位置。*/
}


int main(  ) {
    cvNamedWindow( "Example3", CV_WINDOW_AUTOSIZE );
    g_capture = cvCreateFileCapture( "a2.mp4" );
    IplImage *foo = cvQueryFrame( g_capture);

    //獲取視訊的幀數、畫面的長和寬
    int frames = (int) cvGetCaptureProperty(g_capture, CV_CAP_PROP_FRAME_COUNT );    
    int tmpw = (int) cvGetCaptureProperty(g_capture,CV_CAP_PROP_FRAME_WIDTH);
    int tmph = (int) cvGetCaptureProperty( g_capture, CV_CAP_PROP_FRAME_HEIGHT );
    printf("opencv frames %d w %d h %d\n",frames,tmpw,tmph);


    cvCreateTrackbar( "Position", "Example3", &g_slider_position, frames, onTrackbarSlide );/*
cvCreateTrackbar函式用於建立進度條,引數含義:Position-進度條名字;Example3-需要加入進度條的視窗名字
&g_slider_position整數指標,它的值將反映滑塊的位置。這個變數指定建立時的滑塊位置;frames-滑塊位置的最大值。
onTrackbarSlide-回撥函式的指標*/

    IplImage* frame;
    frames = 0;
    while(1) {
        frame = cvQueryFrame( g_capture );
        if( !frame ) break;
        int frames = cvGetCaptureProperty( g_capture, CV_CAP_PROP_POS_FRAMES);//返回當前進度條位置對應的幀數
        frames++; 
        cvSetTrackbarPos("Position","Example3",frames);//自動控制滾條位置
        cvShowImage( "Example3", frame );
        char c = (char)cvWaitKey(10);
        if( c == 27 ) break;
    }
    cvReleaseCapture( &g_capture );
    cvDestroyWindow( "Example3" );
    return 0;
}

效果如圖,可能有的視訊檔案格式會出現問題,我用的是手機錄製的視訊