close

題目:實現AVI 播放器播放視頻,並通過加入一個滾動條來實現對視頻進行快速拖動

 

1.通過調用cvCreateTrackbar() 來創建一個滾動條,並且通過設置參數確定滾動條所屬於的窗口,為了獲取所需的功能,只需要提供一個回掉函數。

2.實現滾動條隨著視頻播放自動移動

 

 

[cpp] view plaincopy在CODE上查看代碼片派生到我的代碼片
 
  1. #include "opencv3.h"  
  2. #include "cv.h"  
  3. #include "highgui.h"  
  4.   
  5. int  g_slide_position = 0;  
  6. CvCapture* g_capture = NULL;  
  7.   
  8. void  onTrackbarSlide( int  pos)  
  9. {  
  10.     cvSetCaptureProperty(  
  11.         g_capture,  
  12.         CV_CAP_PROP_POS_FRAMES,  
  13.         pos  
  14.         );  
  15. }  
  16. int  main()  
  17. {  
  18.     cvNamedWindow( "Example3" , CV_WINDOW_AUTOSIZE);  
  19.     g_capture = cvCreateFileCapture( "E:\\TigerPI\\test.mp4" );  
  20.     int  frame = cvGetCaptureProperty(  
  21.         g_capture,  
  22.         CV_CAP_PROP_FRAME_COUNT  
  23.         );  
  24.     if  (frame != 0)  
  25.     {  
  26.         cvCreateTrackbar(  
  27.             "Position" ,  
  28.             "Example3" ,  
  29.             &g_slide_position,  
  30.             frame,  
  31.             onTrackbarSlide  
  32.             );  
  33.     }  
  34.   
  35.     IplImage* frames;  
  36.     int  NewPos = g_slide_position;  
  37.     while  (1)  
  38.     {  
  39.         frames = cvQueryFrame(g_capture);  
  40.         if  (!frames)  
  41.             break ;  
  42.         cvShowImage( "Example3" , frames);  
  43.         cvCreateTrackbar( "position" ,  "Example3" , &NewPos, frame, onTrackbarSlide);  
  44.           
  45.         /*cvSetTrackbarPos( 
  46.             "Position", 
  47.             "Example3", 
  48.             g_slide_position++ 
  49.             );*/  
  50.         char  c = cvWaitKey(33);  
  51.         if  (c == 27)  
  52.             break ;  
  53.         NewPos++;  
  54.   
  55.     }  
  56.   
  57.     cvReleaseCapture(&g_capture);  
  58.     cvDestroyWindow( "Example3" );  
  59.   
  60.     return  0;  
  61. }  
  62.   
  63. opencv3::opencv3()  
  64. {  
  65. }  
  66.   
  67.   
  68. opencv3::~opencv3()  
  69. {  
  70. }  



 

 

 

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

arrow
arrow
    全站熱搜

    大玩家闖天涯 發表在 痞客邦 留言(0) 人氣()