基於OpenCV 、VS2008 MFC對話框的USB攝像頭的控制和視頻播放、跟蹤(logitech sphere AF網絡攝像頭)

基於OpenCV 、VS2008 MFC對話框的USB攝像頭的控制和視頻播放、跟蹤(logitech sphere AF網絡攝像頭)

 

1.opencv

2.vs2008 mfc

3.logitech sphere AF網絡攝像頭的pan tilt zoom控制

4.SIR粒子濾波

 

我已經做完了,總結完後上傳。

 

 

gui interface

 

草稿

 PTZ Pan, Tilt, Zoom )攝像機跟蹤指圖像工作站通過對攝像頭所獲取的視頻圖像序列處理,對運動目標進行檢測、分割和跟蹤,將得到的目標偏離視場中心的偏差值反饋給雲臺,控制其全方位轉動,實現攝像機對目標的同步跟蹤。

 

1.     界面設計

基於 Visual Studio 2008 MFC 技術, 在對話框GUI 界面,往裏面添加若干Button 和一個Picture 控件,如圖


2.1 GUI 界面

各個控件的ID 號由Visual C++ 自動產生並存放於Resource.h 文件中,比如其中一句定義:

#define IDC_ShowImg                      1002

定義了圖片控件的ID 號,由圖片控件顯示圖片時只需要使用如下命令:

CDC* pDC = GetDlgItem( IDC_ShowImg)->GetDC();// 獲得顯示控件的DC

HDC hDC = pDC->GetSafeHdc();   // 獲取HDC( 設備句柄) 來進行繪圖操作

img.DrawToHDC( hDC, &rect ); // 將圖片繪製到顯示控件的指定區域內

同時,爲了實時顯示各種參數,創建了狀態欄。

HWND hStatusWindow;

HWND hDlg=GetSafeHwnd();

int IDS_STATUS =1;

hStatusWindow=CreateStatusWindow(WS_CHILD|WS_VISIBLE|WS_BORDER,TEXT(" 狀態欄"),hDlg, IDS_STATUS);

int pint[4]={110,250,300,-1};//110,250,300 設定間隔

::SendMessage(hStatusWindow,SB_SETPARTS,4,(LPARAM)pint);

在狀態欄中,將不斷顯示水平、垂直轉動的角度和焦距變化值,這樣可以使用戶在使用系統的過程中得到一些關心的準確數據。

2.     人臉檢測

人臉檢測方法是一種基於積分圖、級聯檢測器和AdaBoost 算法的方法,方法框架可以分爲以下三大部分

第一部分,使用Harr-llke 特徵表示人臉,使用“積分圖’’實現特徵數值的快速計算;

第二部分,使用Adaboost 算法挑選出一些最能代表人臉的矩形特徵( 弱分類器) ,按照加權投票的方式將弱分類器構造爲一個強分類器:

第三部分,將訓練得到的若干強分類器串聯組成一個級聯結構的層疊分類器,級聯結構能有效地提高分類器的檢測速度。

基於AdaBoost 的人臉檢測在OpenCV 中的具體實現步驟如圖2.2

 


2.2 OpenCV2.0 實現人臉檢測的基本步驟

1)      加載分類器。利用以下語句實現分類器的加載。

static CvHaarClassifierCascade* cascade = 0;

const char* cascade_name ="haarcascade_frontalface_alt.xml";

cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );

2)       同時,0penCV 在加載的時候將分類器轉化成了內部格式。加載檢測圖像。在本檢測中,首先將3 通道8 位的彩色圖轉爲灰度圖,然後將灰度圖按縮小1.3 倍。

    cvCvtColor( img, gray, CV_BGR2GRAY );// 將彩色圖轉化爲灰度圖

cvResize( gray, small_img, CV_INTER_LINEAR );// 將灰度圖縮小

3)       檢測人臉。通過以下函數實現人臉檢測

vSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,

        1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,cvSize(30, 30) );

通過以下函數得到臉部座標:

CvRect r = (CvRect*)cvGetSeqElem( faces,0);

 


2.3 人臉檢測效果圖

3.     基於多線程的視頻文件播放

在多線程方法中,同一進程內所有線程共享惟一的進程地址空間資源,線程間共用內存空間、寄存器、進程表項等,不存在通過第三方進行信息交換的問題;而線程內部也能通過線程數據槽等方法實現各自的變量存儲,所以多線程技術是併發程序設計方式中最爲簡單的一種,是首選工具。

在未採用多線程前,單擊Capture 按鈕,視頻播放的過程中整個GUI 界面將失去消息響應,因爲視頻播放是一個死循環的過程。爲了解決這個問題,本系統採用多線程技術,實現了視頻播放與主程序的獨立。

Button 控件Capture 下添加了void CmymfcDlg::OnBnClickedReadimg() 按鈕點擊的消息響應程序,在程序中添加如下代碼:

        CreateThread(NULL,0,CaptureThread,Capture_param,0,NULL);

創建了一個線程,線程函數爲C aptureThread ,傳入參數爲Capture_param 。在 DWORD WINAPI CaptureThread(LPVOID pParam) 函數中,實現了每幀視頻的讀取和粒子濾波的循環。

4.     基於OpenCV 2.0 的視頻文件讀取

OpenCV 是一種用於數字圖像處理和計算機視覺的函數庫。它由英特爾公司開發,是一套可免費獲得的由一些C 函數和C++ 類所組成的庫。OpenCVWindows 系統及Linux 系統下都可以使用,它提供了很多標準的圖像處理算法,主要用於對圖像進行一些高級處理。這些函數可以直接在具體的視頻開發項目中調用,通過簡單編程即可完成十分複雜龐大的開發任務,具有很好的效率。

CvCapture* pCapture;

pCapture = cvCaptureFromCAM(0) ;

IplImage* ipl=NULL;

ipl = cvQueryFrame( Capture_param->plistener->pCapture );

通過以上代碼實現了從攝像頭讀取每幀圖片。由於圖片控件的大小是276 ×276 ,需要對攝像頭採集的圖像進行縮放。攝像頭採集的圖像大小是320 ×240 ,上下添加黑邊至320 ×320, 然後進行256/320 的縮放。

cvSetImageROI( TheImage, cvRect( tlx, tly, nw, nh) );

cvResize( img, TheImage );

cvResetImageROI( TheImage );

通過OpenCV 設置感興趣區域ROI 進行縮放, 可以很方便地實現圖片以合適尺寸顯示。

5.     PTZ 攝像頭的控制

PTZ.CPP 文件中,主要通過如下函數實現攝像頭的控制。

HRESULT set_mechanical_pan_relative(IAMCameraControl *pCameraControl, long value);

HRESULT set_mechanical_tilt_relative(IAMCameraControl *pCameraControl, long value);

以上兩個函數,實現了攝像頭的水平和垂直轉動,輸入參數分別爲攝像頭的ID 號和轉動角度。

HRESULT set_digital_zoom_absolute(IAMCameraControl *pCameraControl, long value);

這個函數實現了攝像頭的放大縮小倍數。

Logitech 此款攝像頭中,焦距的變化範圍從50mm200mm 。函數傳入的value 即設置的焦距值 。這樣可以看到,此攝像頭最大的放大倍數是4 倍。

6.     粒子濾波程序的實現

Button 控件track 下添加了void CmymfcDlg:: OnBnClickedTrace () 按鈕點擊的消息響應程序,在程序中添加如下代碼:

if(initPFTracking((PixelsInfor *)ImageSource->imageData,

                                      &TrackLocation,

                                      &goalFeatuerStuctAdr,

                                      &G_MAIN_ParticlesAdr,

                                      G_MAIN_PARNUMBER)!=0)

                   {

                           AfxMessageBox("SIR initialization error!");

                   }

啓動粒子濾波程序。

其中TrackLocation 爲目標位置,本系統由兩種方式輸入。

a)      由鼠標響應事件產生

GUI 界面中,添加如下消息響應事件

void CmymfcDlg::OnLButtonDown(UINT nFlags, CPoint point)

void CmymfcDlg::OnLButtonUp(UINT nFlags, CPoint point)

由鼠標畫框事件,記錄下目標的座標,再傳給粒子濾波初始化程序。

b)    AdaBoost 人臉檢測程序的返回值確定。

人臉檢測程序可以返回檢測結果,通過一定的換算後可以得到目標位置,然後傳遞給粒子濾波程序,實現了人臉的自動檢測和跟蹤。

當初始化完成後,將粒子濾波的初始化完成標誌位注爲真,然後每幀圖像顯示前調用如下函數進行持續跟蹤並返回位置座標,畫框程序根據位置座標不斷進行標註。

if(oncePFTracking((PixelsInfor *)(ImageSource->imageData),

                               Capture_param->plistener->G_MAIN_ParticlesAdr,                                G_MAIN_PARNUMBER,

                                      Capture_param->plistener->goalFeatuerStuctAdr,

                                      &Capture_param->plistener->TrackLocation)!=0)

        {

                       AfxMessageBox("tracking code error!");}

總結

本系統在VS2008 下開發環境下,開發出了基於MFC 對話框的人機交互界面,使用OpenCV 2.0 函數庫和多線程技術,在流暢播放視頻的同時,能進行基於用戶操作的Logitech USB 攝像頭的PTZ 控制,能自動運行基於Adaboost 的人臉檢測並具有非常高的準確性,能提供兩種目標輸入模式的粒子濾波程序的人臉跟蹤,並能根據跟蹤結果對攝像頭進行水平、垂直控制,使跟蹤實現了水平360 , 垂直90 的跟蹤效果。

本系統只是完成了水平和垂直的轉動跟蹤,沒有使雲臺根據轉動參數實現目標跟蹤過程中的自動鏡頭縮放,這個是下一步需要繼續深入下去的工作。

 

五 部分代碼

回答一個朋友的問題

1.怎麼交換數據?

在窗體初始化的時候,創建守護線程,在守護線程中不斷獲取圖像,並通過MFC顯示。通過函數調用傳遞參數,不會產生延時。

以下代碼是Capture_param的定義

以下是顯示代碼



 

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