兩個問題:
使用DirectShow採集圖像
您也可使用hardy_ai編寫的ARFrameGrabber類
本文檔介紹的CCameraDS類調用採集函數可直接返回IplImage,使用更方便,且集成了DirectShow,勿需安裝龐大的DirectX/Platform SDK。
本類只在Visual C++ 6.0下進行了測試
目錄[隱藏] |
下載
可能存在的缺陷
在vc6.0中測試將此例程移植到mfc下時(特別是顯示到控件上時),性能不如CvCapture;mfc下顯示使用CvvImage對象的DrawToHDC方法。最明顯的差別在cpu使用率上,即使都開到多線程中,DirectShow採集圖像的方法僅僅顯示cpu使用率就高達60%,拖動時能高達80%,且資源釋放緩慢;但是採用CvCapture,即使帶上一些圖像處理步驟,cpu使用率也基本在50%以下。
文檔
CCameraDS中有如下函數:
- CCameraDS()
- 構造函數
- CCameraDS()
- 析構函數
- bool OpenCamera(int nCamID, bool bDisplayProperties=true)
- 打開攝像頭,nCamID指定打開哪個攝像頭,取值可以爲0,1,2,...。bDisplayProperties指示是否自動彈出攝像頭屬性頁。
- bool OpenCamera(int nCamID, bool bDisplayProperties=true, int nWidth=320, int nHeight=240)
- 打開攝像頭,nCamID指定打開哪個攝像頭,取值可以爲0,1,2,...。bDisplayProperties指示是否自動彈出攝像頭屬性頁。nWidth和nHeight設置的攝像頭的寬和高,如果攝像頭不支持所設定的寬度和高度,則返回false
- void CloseCamera()
- 關閉攝像頭,析構函數會自動調用這個函數
- static int CameraCount()
- 返回攝像頭的數目。可以不用創建CCameraDS實例,採用int c=CCameraDS::CameraCount();得到結果。
- static int CameraName(int nCamID, char* sName, int nBufferSize);
- 根據攝像頭的編號返回攝像頭的名字
- nCamID: 攝像頭編號
- sName: 用於存放攝像頭名字的數組
- nBufferSize: sName的大小
- 可以不用創建CCameraDS實例,採用CCameraDS::CameraName();得到結果。
- int GetWidth()
- 返回圖像寬度。
- int GetHeight()
- 返回圖像高度
- IplImage * QueryFrame()
- 抓取一幀,返回的IplImage不可手動釋放!返回圖像數據的爲BGR模式的Top-down(第一個字節爲左上角像素),即IplImage::origin=0(IPL_ORIGIN_TL)
例程
////////////////////////////////////////////////////////////////////// // Video Capture using DirectShow // Author: Shiqi Yu ([email protected]) // Thanks to: // HardyAI@OpenCV China // flymanbox@OpenCV China (for his contribution to function CameraName, and frame width/height setting) // Last modification: April 9, 2009 ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // 使用說明: // 1. 將CameraDS.h CameraDS.cpp以及目錄DirectShow複製到你的項目中 // 2. 菜單 Project->Settings->Settings for:(All configurations)->C/C++->Category(Preprocessor)->Additional include directories // 設置爲 DirectShow/Include // 3. 菜單 Project->Settings->Settings for:(All configurations)->Link->Category(Input)->Additional library directories // 設置爲 DirectShow/Lib // 在vc++2005開發環境下的使用說明: // 1.將CameraDS.h CameraDS.cpp複製到你的項目中 // 2.將DirectShow複製到你的opencv根目錄下,菜單 工具->選項->項目和解決方案->vc++目錄,把..(你的opencv安裝目錄)/DirectShow/Include添加到 // “引用文件”中$(VCInstallDir)PlatformSDK\include和$(FrameworkSDKDir)include下面任意位置 // 3.菜單 工具->選項->項目和解決方案->vc++目錄,把..(你的opencv安裝目錄)/DirectShow/Lib添加到“庫文件”下面。也可參考使用說明3。 ////////////////////////////////////////////////////////////////////// #include "camerads.h" #include <highgui.h> #include <stdio.h> int main() { int cam_count; //僅僅獲取攝像頭數目 cam_count = CCameraDS::CameraCount(); printf("There are %d cameras.\n", cam_count); //獲取所有攝像頭的名稱 for(int i=0; i < cam_count; i++) { char camera_name[1024]; int retval = CCameraDS::CameraName(i, camera_name, sizeof(camera_name) ); if(retval >0) printf("Camera #%d's Name is '%s'.\n", i, camera_name); else printf("Can not get Camera #%d's name.\n", i); } if(cam_count==0) return -1; CCameraDS camera; //打開第一個攝像頭 //if(! camera.OpenCamera(0, true)) //彈出屬性選擇窗口 if(! camera.OpenCamera(0, false, 320,240)) //不彈出屬性選擇窗口,用代碼制定圖像寬和高 { fprintf(stderr, "Can not open camera.\n"); return -1; } cvNamedWindow("camera"); while(1) { //獲取一幀 IplImage *pFrame = camera.QueryFrame(); //顯示 cvShowImage("camera", pFrame); if (cvWaitKey(20) == 'q') break; } camera.CloseCamera(); //可不調用此函數,CCameraDS析構時會自動關閉攝像頭 cvDestroyWindow("camera"); return 0; }