一個簡單的實作代碼:
#include"cv.h"
#include"highgui.h"
//設定全局變量,一個為滾動條的位置。回調函數需要用到的變量cvCapture也是全局變量,是以前面有g_,代表global
CvCapture*g_capture = NULL;//用來儲存圖像捕獲的資訊的結構體
int g_slider_pos = 0;
int frame_count = 0;//記錄播放的幀數
//當滑鼠滑動滑塊的時候 調用該回調函數
void onTrackbarSlider(int pos)//這個參數由cvCreateTrackbar傳入 它反映了目前滑塊被滑到的位置
{
//設定目前視訊檔案的屬性
cvSetCaptureProperty(
g_capture,
CV_CAP_PROP_POS_FRAMES,//機關為幀數的位置(隻對視訊檔案有效)
pos //設定指定視訊擷取的屬性
);
frame_count = pos;
}
int main()
{
cvNamedWindow("show");//建立視窗
g_capture = cvCreateFileCapture("E:\\Linux基礎知識與系統管理\\01 運維基礎\\01_01_面授班開場.avi");//擷取視訊檔案
//擷取視訊的全部幀數frames
int frames = (int)cvGetCaptureProperty(
g_capture,
CV_CAP_PROP_FRAME_COUNT//視訊檔案中幀的總數
);
if (frames > 0)
{
//建立進度條
//當你滑動滑塊的時候 會觸發一個事件執行cvCreateTrackbar 然後cvCreateTrackbar調用onTrackbarSlider 然後傳回while接着以前繼續循環
//cvCreateTrackbar這個函數系統調用 onTrackbarSlider我們自己填寫代碼實作
cvCreateTrackbar(
"Pos", //進度條名稱
"show",//所在視窗
&g_slider_pos,//滑塊的位置
frames,//滑塊位置的最大值。最小值一直是0
onTrackbarSlider//回調函數 這裡面回調函數的聲明參數必須是×××的 傳回值為void
//當你用滑鼠拉動滑塊的時候 就會産生一個消息 來執行這個回調函數
);
}
IplImage*frame;
while (true)
{
frame = cvQueryFrame(g_capture);//從攝像頭或者檔案中抓取并傳回一幀
//cvQueryFrame的參數為CvCapture結構的指針。用來将下一幀視訊檔案載入記憶體,傳回一個對應目前幀的指針
if (!frame)
{
break;
}
cvShowImage("show",frame);
char c = cvWaitKey(33);//控制頻率
if (c == 27)//ESC鍵
{
break;
}
//設定滑塊的位置 實作滑塊随視訊的播放而移動
cvSetTrackbarPos(
"pos",
"show",
frame_count//滑塊的位置
);
frame_count++;//每播放一幀的時候 加一
}
//釋放資源
cvReleaseCapture(&g_capture);
cvDestroyWindow("show");
return 0;
}
函數解釋:
擷取視訊檔案和攝像頭屬性的函數
/* retrieve or set capture properties */
CVAPI(double) cvGetCaptureProperty( CvCapture* capture, int property_id );
capture 要擷取的視訊檔案指針
property_id 要擷取的屬性 傳入相應的宏傳回相應的屬性
CV_CAP_PROP_POS_MSEC - 影片目前位置,為毫秒數或者視訊擷取時間戳
CV_CAP_PROP_POS_FRAMES - 将被下一步解壓/擷取的幀索引,以0為起點
CV_CAP_PROP_POS_AVI_RATIO - 視訊檔案的相對位置(0 - 影片的開始,1 - 影片的結尾)
CV_CAP_PROP_FRAME_WIDTH - 視訊流中的幀寬度
CV_CAP_PROP_FRAME_HEIGHT - 視訊流中的幀高度
CV_CAP_PROP_FPS - 幀率
CV_CAP_PROP_FOURCC - 表示codec的四個字元
CV_CAP_PROP_FRAME_COUNT - 視訊檔案中幀的總數
一個bug:
有時候cvGetCapturePropetry在cvQueryFrame被調用一次後在調用cvGetCapturePropetry才會傳回正确的數值
建立一個滾動條
* create trackbar and display it on top of given window, set callback */
CVAPI(int) cvCreateTrackbar( const char* trackbar_name, //滾動條的名字
const char* window_name, //所在視窗的名字
int* value, //指定建立時的滑塊位置
int count, //滑塊位置的最大值。最小值一直是0
CvTrackbarCallback on_change CV_DEFAULT(NULL));
//每次滑塊位置改變時,調用該回調函數
//typedef void (CV_CDECL *CvTrackbarCallback)(int pos);
//on_change 每次滑塊位置被改變的時候,被調用函數的指針。
//這個函數應該被聲明為void Foo(int); 如果沒有回調函數,這個值可以設為NULL
回調函數:
回調函數就是一個通過函數指針調用的函數
如果你把函數的指針(位址)作為參數傳遞給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數
回調函數不是由該函數的實作方法直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用于對該事件或條件進行響應
編輯
機制:
⑴定義一個回調函數;
⑵提供函數實作的一方在初始化的時候,将回調函數的函數指針注冊給調用者;
⑶當特定的事件或條件發生的時候,調用者使用函數指針調用回調函數對事件進行處理
設定攝像頭屬性的函數
CVAPI(int) cvSetCaptureProperty(
CvCapture* capture, //視訊擷取結構
nt property_id, // 屬性辨別符
double value );
CV_CAP_PROP_POS_MSEC - 從檔案開始的位置,機關為毫秒
CV_CAP_PROP_POS_FRAMES - 機關為幀數的位置(隻對視訊檔案有效)
CV_CAP_PROP_POS_AVI_RATIO - 視訊檔案的相對位置(0 - 影片的開始,1 - 影片的結尾)
CV_CAP_PROP_FRAME_WIDTH - 視訊流的幀寬度(隻對攝像頭有效)
CV_CAP_PROP_FRAME_HEIGHT - 視訊流的幀高度(隻對攝像頭有效)
CV_CAP_PROP_FPS - 幀率(隻對攝像頭有效)
CV_CAP_PROP_FOURCC - 表示codec的四個字元(隻對攝像頭有效)