題目:實現AVI 播放器播放視頻,並通過加入一個滾動條來實現對視頻進行快速拖動
1.通過調用cvCreateTrackbar() 來創建一個滾動條,並且通過設置參數確定滾動條所屬於的窗口,為了獲取所需的功能,只需要提供一個回掉函數。
2.實現滾動條隨著視頻播放自動移動
- #include "opencv3.h"
- #include "cv.h"
- #include "highgui.h"
- int g_slide_position = 0;
- CvCapture* g_capture = NULL;
- void onTrackbarSlide( int pos)
- {
- cvSetCaptureProperty(
- g_capture,
- CV_CAP_PROP_POS_FRAMES,
- pos
- );
- }
- int main()
- {
- cvNamedWindow( "Example3" , CV_WINDOW_AUTOSIZE);
- g_capture = cvCreateFileCapture( "E:\\TigerPI\\test.mp4" );
- int frame = cvGetCaptureProperty(
- g_capture,
- CV_CAP_PROP_FRAME_COUNT
- );
- if (frame != 0)
- {
- cvCreateTrackbar(
- "Position" ,
- "Example3" ,
- &g_slide_position,
- frame,
- onTrackbarSlide
- );
- }
- IplImage* frames;
- int NewPos = g_slide_position;
- while (1)
- {
- frames = cvQueryFrame(g_capture);
- if (!frames)
- break ;
- cvShowImage( "Example3" , frames);
- cvCreateTrackbar( "position" , "Example3" , &NewPos, frame, onTrackbarSlide);
- /*cvSetTrackbarPos(
- "Position",
- "Example3",
- g_slide_position++
- );*/
- char c = cvWaitKey(33);
- if (c == 27)
- break ;
- NewPos++;
- }
- cvReleaseCapture(&g_capture);
- cvDestroyWindow( "Example3" );
- return 0;
- }
- opencv3::opencv3()
- {
- }
- opencv3::~opencv3()
- {
- }
cvCreateTrackbar
該函數為開放計算機視覺(OpenCV)庫庫函數,創建trackbar並將它添加到指定的窗口。
定義:
CV_EXTERN_C_FUNCPTR( void (*CvTrackbarCallback)(int pos) );
int cvCreateTrackbar( const char* trackbar_name, const char* window_name, int* value, int count, CvTrackbarCallback on_change );
參數:
trackbar_name 被創建的trackbar名字。
window_name 窗口名字,這個窗口將為被創建trackbar的父對象。
value 整數指針,它的值將反映滑塊的位置。這個變量指定創建時的滑塊位置。
count 滑塊位置的最大值。最小值一直是0。
on_change 每次滑塊位置被改變的時候,被調用函數的指針。這個函數應該被聲明為void Foo(int); 如果沒有回調函數,這個值可以設為NULL。
函數cvCreateTrackbar用指定的名字和範圍來創建trackbar(滑塊或者範圍控制),指定與trackbar位置同步的變量,並且指定當trackbar位置被改變的時候調用的回調函數。
被創建的trackbar默認顯示在指定窗口的頂端,可以通過函數cvGetTrackbarPos來獲取trackbar顯示的位置信息,以及通過函數cvSetTrackbarPos來重新設置trackbar的顯示位置。
int cvCreateTrackbar(
const char* trackbar_name, //滑動條的名稱
const char* window_name, //窗口的名稱,滑動條不會遮擋圖像
int* value, //當滑動條被拖到時,OpenCV會自動將當前位置所代表的值傳給指針指向的整數
int count, //滑動條所能達到的最大值
CvTrackbarCallback on_change //可選的回調函數,回調函數可參見
其中openCV的highgui庫提供了兩個函數來讀取和設置滾動條的value值
//讀取value值
int cvGetTrackbarPos(
const char* trackbar_name,
cosnt char* window_name
);
//設置value值
void cvSetTrackbarPos(
const char* trackbar_name,
const char* window_name,
int pos
);
OpenCV中關於cvGetCaptureProperty函數
OpenCV中提供了一個函數cvGetCaptureProperty(Capture* cap,int property_index)函數來獲取視頻文件的一些屬性,這是其中的OpenCV中屬性的一些宏定義:
#define CV_CAP_PROP_POS_MSEC 0
#define CV_CAP_PROP_POS_FRAMES 1
#define CV_CAP_PROP_POS_AVI_RATIO 2
#define CV_CAP_PROP_FRAME_WIDTH 3
#define CV_CAP_PROP_FRAME_HEIGHT 4
#define CV_CAP_PROP_FPS 5
#define CV_CAP_PROP_FOURCC 6
#define CV_CAP_PROP_FRAME_COUNT 7
#define CV_CAP_PROP_FORMAT 8
#define CV_CAP_PROP_MODE 9
#define CV_CAP_PROP_BRIGHTNESS 10
#define CV_CAP_PROP_CONTRAST 11
#define CV_CAP_PROP_SATURATION 12
#define CV_CAP_PROP_HUE 13
#define CV_CAP_PROP_GAIN 14
#define CV_CAP_PROP_EXPOSURE 15
#define CV_CAP_PROP_CONVERT_RGB 16
#define CV_CAP_PROP_WHITE_BALANCE 17
#define CV_CAP_PROP_RECTIFICATION 18
通過創建一個Capture對象的指針後,調用cvGetCaptureProperty即可獲取上述任何相關屬性;但是我們不能太依賴這個函數;比如我們想獲取一段視頻的幀數,我們就不能太依賴於CV_CAP_PROP_FRAME_COUNT這個屬性;因為cvGetCaptureProperty對屬性的訪問,其實訪問的是關聯視頻文件的文件頭信息,並不是真正去訪問了視頻的圖像數據,這就帶來一個問題:我們在講其他視頻格式轉換為AVI格式的時候,圖像幀數並沒改變,只是視頻文件頭改變了,這時直接通過get函數讀取的信息就可能不准確;最好的辦法是迭代從視頻中取出一幀,檢查是否有數據,來確定該視頻文件的總共幀數~~~ 不光是幀數,幀率也可能不對~~
比如,自己在實驗中庸狸窩轉換器將一段視頻轉換為avi格式的視頻文件後,用下面的兩段代碼,結果差距很大:
code 1.
CvCapture *cap = cvCaptureFromFile(videoName);//獲取視頻
int numFrames = (int) cvGetCaptureProperty(cap, CV_CAP_PROP_FRAME_COUNT);//得到視頻幀數,筆者獲得的結果為148
CODE 2.
IplImage* pImg=NULL;
int count=0;
while((pImg=cvQueryFrame(cap))!=NULL)
{
count++;
}//得到的幀數只有60幀;
究其原因其實就是cvGetCaptureProperty實現的機制上,它只是讀取視頻文件頭信息,而不是真正讀取了視頻文件;因此在進行不同格式的視頻文件轉換為OpenCV支持的AVI時,可能獲取的屬性並不准確~~~
因此在使用該函數時,要注意。自己的經驗是對於原始的AVI文件,可以直接使用該函數(code1),而經過轉換而得到的視頻文件,最好使用code 2。
cvSetCaptureProperty
設置視頻獲取屬性int cvSetCaptureProperty( CvCapture* capture, int property_id, double value );
capture 視頻獲取結構。
property_id 屬性標識符。可以是下面之一:
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的四個字符(只對攝像頭有效)value 屬性的值。
函數cvSetCaptureProperty設置指定視頻獲取的屬性。目前這個函數對視頻文件只支持:
CV_CAP_PROP_POS_MSEC
CV_CAP_PROP_POS_FRAMES
CV_CAP_PROP_POS_AVI_RATIO
留言列表