播放一個視頻並用滾動條控制進度-OpenCV應用學習筆記二

     logo_thumb9

 

今天咱們來作個有趣的程序實現:利用OpenCV讀取本地文件夾的視頻文件,而且在窗口中建立拖動控制條來顯示而且控制視頻文件的讀取進度。ios

此程序調試花費了筆者近一天時間,其實大致程序都已經很快寫出,結果執行時卻出現拖動條不能控制視頻讀取進度現象,結果發現是」一個大小寫字母引起的血案「——在建立拖動條時命名爲:Position,可是在設置拖動條的視頻位置時卻疏忽寫爲:position。爲此筆者反覆了N遍,因而可知程序的嚴格性,以及「搬磚碼垛」時專一的重要性。ide

一樣在附上程序以前咱們有必要對程序中出現的關鍵函數給出深度解析,這個也會成爲筆者對於學習筆記的博客書寫風格:開篇小敘——程序實現功能——關鍵函數精析——附上完整測試程序;若是有更好的書寫方案但願與你們不吝賜教,惟一的目的就是爲了讓技術道路上的咱們能更快的從彼此哪裏獲取實用信息,這個也是衡量一個大牛是否技術精通的重要指標:所謂的助攻能力!!!共勉之函數

實現功能:

    輸入avi2.exe play2.avi命令符後,執行:Example2窗口播放play2.avi視頻文件,而且在Position拖動條上顯示進度,手動拖動能調節對應視頻播放進度。學習

J5243MCM7T)X19FA1P[DNWM

函數精析:

  • cvCreateFileCapture(const char* filename)/cvCaptureFromAVI(const char* filename)

  • 從指定文件filename中獲取視頻流,分配和初始化CvCaputure*結構指針
  • 兩個函數等價,實現從文件夾中讀取視頻流;同時支持多種視頻格式AVI、MP四、wmv等
  • 只分配一幀的圖像空間,每次調用時覆蓋前面一次的數據(每次調用返回的指針是同樣的)
  • 假若咱們想分配本身的圖像存儲空間用:cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,3)-《筆記一》
  • cvCaptureFromCAM(int index)

  • 從攝像頭中獲取視頻,多個攝像頭的編號index;本地index=0;外部index=1
  • cvSetCaptureProperty(CvCapture* capture, int propId, double value)

  • 設置視頻的屬性 (視頻對象,屬性標識符,屬性)
  • CV_CAP_PROP_POS_MSEC:視頻當前位置,毫秒或者視頻獲取時間戳
  • CV_CAP_PROP_POS_MSEC:將被下一步解壓獲取的幀索引,以0爲起點
  • CV_CAP_PROP_POS_AVI_RATIO:視頻文件相對位置(0開頭1結尾)
  • propId可取值以下:

RNW)J1I2J7%6LJ}KLX1S_16

  • cvGetCaptureProperty(CvCapture* capture, int propId)

  • 獲取視頻屬性;propId一樣適用上圖
  • cvCreateTrackbar(barName, win1, int* value, int count, CvTrackbarCallback onChange)

  • 建立拖動條(拖動條標識符,窗口標識符,拖動條位置數字指針,最大位置,調用函數更新拖動後的位置)
  • 在win1窗口建立拖動條barName,count爲其最大值,value爲其當前值,onChange跟新拖動後的位置
  • cvSetTrackbarPos(barName,win1, int pos)

  • 設置win1窗口下barName拖動條的最新位置pos
  • cvQueryFrame(g_capture)

  • 從讀取的視頻流g_capture中讀取一幀,而且解壓返回這一幀,返回的圖像能夠被釋放和修改
  • cvRetrieveFrame(g_capture)

  • 返回抓取圖像的指針,可是返回的圖像不能被釋放和修改
  • 利用cvCloneImage()後能夠對抓取的圖像進行任何操做
  • cvGrabFrame(g_capture)

  • 捕捉視頻或者相機的下一幀圖像,尤爲是應用在多相機的狀況下
  • 附源代碼:

#include "stdafx.h"
#include "highgui.h"
#include "cv.h"
#include <iostream>  
using namespace std;

 /*            聲明三個全局變量並初始化             */
int g_slider_position                        //定義拖動條當前位置變量
int frame_count =0;                          //定義一個全局變量,控制滾動條的位置
CvCapture *g_capture = NULL;

/*    定義拖動條函數:設置視頻獲取信息(對指定視頻g_capture
       設置屬性標識符CV_CAP_PROP_POS_FRAMES的值pos)       */

void onTrackbarSlide(int pos)
{
    cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);
    frame_count = pos;                     //將設置的視頻信息中的屬性值保存到frame_count中
    return; 
}

int  main(int argc,char** argv)
{
    if(argc == 2)
    {

        cvNamedWindow("Example2",0);
        g_capture = cvCaptureFromAVI(argv[1]);
                                       // cvCreateFileCapture(argv[1]); 讀入AVI文件等價
        int frames = (int) cvGetCaptureProperty(g_capture,CV_CAP_PROP_FRAME_COUNT);  
                                       //獲取視頻文件屬性的總幀數
        if(frames != 0)
        {
            /*   "position"表示滾動條的名詞,"Example3"表示滾動條所屬窗口, 
                  g_slider_position表示滾動條當前位置。 frames表示滾動條的最大值,
                     onTrackbarSlide表示滾動條的回調函數(被拖動時調用)            */

            cvCreateTrackbar("Position","Example2",&g_slider_position,frames,onTrackbarSlide);
        }    
 
        IplImage* frame = NULL ; 
        while(1)                            //實時捕捉視頻幀顯示,而且更新進度條
        {
              frame = cvQueryFrame(g_capture);//得到一幀圖像
             if(!frame)  break;  
               cvShowImage("Example2",frame);

            cvSetTrackbarPos( "Position", "Example2",  frame_count++  );
             /*    進度條根據視頻進度跟新位置
                    拖動條設置的時候跟以前的建立名稱不一樣致使拖動條不能根據
                    視頻進度更新調試了一天終於發現這裏「position」應該爲「Position」
                    cout << g_slider_position << endl ;//能夠看到爲止更新數據     */


             char c = cvWaitKey(33);          //按下esc後退出
             if( c == 27)break;
              
        }
    }
    cvReleaseCapture(&g_capture);
    cvDestroyWindow("Example2");
    return 0;
}
相關文章
相關標籤/搜索