Opencv中添加進度條及回調函數

在說明如何給視頻中添加進度條之前,先要解釋下回調函數

打個比方,有一家旅館提供叫醒服務,但是要求旅客自己決定叫醒的方法。可以是打客房電話,也可以是派服務員去敲門,睡得死怕耽誤事的,還可以要求往自己頭上澆盆水。這裏,“叫醒”這個行爲是旅館提供的,相當於庫函數,但是叫醒的方式是由旅客決定並告訴旅館的,也就是回調函數。而旅客告訴旅館怎麼叫醒自己的動作,也就是把回調函數傳入庫函數的動作,稱爲登記回調函數(to register a callback function),如圖所示:


之所以先介紹回調函數,是因爲創建軌跡條的函數createTrackbar常常與一個回調函數配合使用。函數原型如下:
int createTrackbar(conststring& trackbarname, conststring& winname, int* value, int count, TrackbarCallback onChange=0,void* userdata=0);  
第一個參數,const string&類型的trackbarname,表示軌跡條的名字,用來代表我們創建的軌跡條。
第二個參數,const string&類型的winname,填窗口的名字,表示這個軌跡條會依附到哪個窗口上,即對應namedWindow()創建窗口時填的某一個窗口名。
第三個參數,int* 類型的value,一個指向整型的指針,表示滑塊的位置。並且在創建時,滑塊的初始位置就是是由該變量當前的值。
第四個參數,int類型的count,表示滑塊可以達到的最大位置的值。PS:滑塊最小的位置的值始終爲0。
第五個參數,TrackbarCallback類型的onChange,首先注意他有默認值0。這是一個指向回調函數的指針,每次滑塊位置改變時,這個函數都會進行回調。並且這個函數的原型必須爲void XXXX(int,void*);其中第一個參數是軌跡條的位置第二個參數是用戶數據(看下面的第六個參數)。如果回調是NULL指針,表示沒有回調函數的調用,僅第三個參數value有變化。
第六個參數,void*類型的userdata,他也有默認值0。這個參數是用戶傳給回調函數的數據,用來處理軌跡條事件。如果使用的第三個參數value實參是全局變量的話,完全可以不去管這個userdata參數。

這個createTrackbar函數,爲我們創建一個具有特定名稱和範圍的軌跡條(Trackbar,或者說是滑塊範圍控制工具),指定一個和軌跡條位置同步的變量。而且要指定回調函數onChange(第五個參數),在軌跡條位置改變的時候來調用這個回調函數。並且我們知道,創建的軌跡條顯示在指定的winname(第二個參數)所代表的窗口上。


具體程序如下:

#include  "highgui.h"
#include  "iostream"
using namespace std;
using namespace cv;
VideoCapture video1("Seq04.avi");                                        

int position =video1.get(CV_CAP_PROP_POS_FRAMES);  //如果createTrackbar第三個參數是全局變量,會省去很多麻煩

void onTrackbarslide(int pos,void*)         //如果函數的參數可以是任意類型指針,那麼應聲明其參數爲void*

{
double zhenNum=video1.set(CV_CAP_PROP_POS_FRAMES,pos); //第五個參數是一個函數,調到指定的幀使用set函數
}
int  main()
{
if(!video1.isOpened())
cout<<"wrong"<<endl;
double zhenNum=video1.get(CV_CAP_PROP_FRAME_COUNT); //統計幀數作爲進度條的最大值
double zhenLv=video1.get(CV_CAP_PROP_FPS);                         //幀率,用於設置播放延遲

double delay=1/zhenLv;
Mat frame;

while(1)
{
if(!video1.read(frame))   //後面跟的是Mat型
break;
imshow("abc",frame);
waitKey(1000*delay);  //延遲N毫秒,所以要乘以1000
createTrackbar("tiao","abc",&position,zhenNum,onTrackbarslide);//第五個參數實際是一個數字與進度的對應關係;
}

}


在該例子中,進度條不能隨着視頻的播放而改變位置,這也是需要改進的地方,不過能做到拖動進度條就可以讓視頻到相應位置。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章