1. 程式人生 > >OpenCV控制攝像頭實現 拍照功能

OpenCV控制攝像頭實現 拍照功能

注意註釋部分,其中使用的比較生疏的 API 包括cvPyrDown  ,cvCreateCameraCapture

以及cvCopycvSaveImage

下面就來一一解釋這幾個 API 的具體使用:

voidcvPyrDown( const CvArr* src, CvArr* dst, int filter=CV_GAUSSIAN_5x5 );

其中 src 為 CvArr * 型別,這裡順便解釋一下 OpenCV 基本上是用 C 實現的,當然其中包括一定的 C++ 成分,

但是 OpenCV 中仍然也使用了面向物件的思想,即有以下的繼承關係:

image

所以在實際使用當中,完全可以使用 ”子類” CvMat 或者是 IplImage 來代替 CvArr ,

也就是說在引數中完全可以傳入一個 IplImage 型別,

src 代表的就是源影象,即傳入函式的影象,而 dst 則是輸出影象,即縮放一倍後的影象,

但是需要注意的是,在這裡傳入的 dst 影象必須是在初始化以後才能傳入,

對於這一點,在下面的 Demo 中可以看到。而至於卷積濾波器的型別則一般採用預設型別即可。

CvCapture*cvCreateCameraCapture( int index );

大夥應該還記得cvCreateFileCapture這個函式嗎?

其實對於cvCreateFileCapture來說,其是根據一個指定的視訊檔案來初始化,

而對於cvCreateCameraCapture

則不同,其是通過初始化一個視訊裝置 (也可以看做就是一個攝像頭),

初始化以後,便可以從這個攝像裝置中獲取視訊了。

至於引數 index 的話,如果您的電腦上連線了多個攝像裝置,則需要通過這個  index  來指定到底要使用哪一個攝像頭。

voidcvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL );

這個函式的作用是拷貝一個數組到另一個數組,而根據前面的繼承關係,IplImage  繼承自  CvMat,

而 CvMat 又是繼承於  CvArr ,所以在此處可以直接傳入一個  IplImage  來實現拷貝,

很明顯,src 是傳入的陣列,而 dst 則是複製完成後返回的結果陣列,

而至於 mask 這個陣列呢,比較變態,

它指定了陣列 src 中哪些元素需要拷貝到 dst 陣列中,哪些元素不能夠拷貝到 dst 陣列中,

mask 陣列中標記為非 0 的則可以拷貝到 dst 中,標記為 0 的則不會拷貝到 dst 陣列當中去。

這裡需要注意的是,dst 陣列和 src 陣列必須是相同的型別,並且具有相同的維數和大小,否則整個程式會崩潰。

intcvSaveImage( const char* filename, const CvArr* image );

這個函式的作用很明顯,即儲存圖片到檔案,而至於儲存的圖片的檔案則看  filename  這個引數指定的字尾名是什麼了。

[cpp] view plaincopyprint?
  1. #include "stdafx.h" 
  2. #include"cv.h" 
  3. #include"highgui.h" 
  4. #include"stdio.h" 
  5. // 實現將拍下來的圖片縮放一倍 
  6. IplImage* DoPyrDown(IplImage* image, int filter = IPL_GAUSSIAN_5x5)  
  7. {  
  8. // 設定大小縮小一倍 
  9.     CvSize size = cvSize(image->width / 2,image->height / 2);  
  10. //初始化圖片 
  11.     IplImage* outImage = cvCreateImage(size,image->depth,image->nChannels);  
  12. //實現縮放 
  13.     cvPyrDown(image,outImage);  
  14.     cvReleaseImage(&image);  
  15. return outImage;  
  16. }  
  17. int main(int argc, char** argv)  
  18. {  
  19.     cvNamedWindow("vedio");  
  20.     CvCapture* capture;  
  21. // 首先是要通過攝像裝置來得到一個CvCapture物件 
  22. if(1 == argc)  
  23.     {  
  24.         capture = cvCreateCameraCapture(0);  
  25.     }  
  26. else
  27.     {  
  28.         capture = cvCreateCameraCapture(atoi(argv[1]));  
  29.     }  
  30.     assert(NULL != capture);  
  31.     IplImage* frame;  
  32. char keyCode;  
  33. // 每隔30ms捕捉一次視訊影象 
  34. // 可以設為while(1)  使得實時捕捉視訊畫面 
  35. while((keyCode = cvWaitKey(30)))  
  36.     {  
  37. //表示按下了ESC鍵,退出 
  38. if(keyCode == 27)  
  39.         {  
  40. break;  
  41.         }  
  42. //表示按下了回車鍵,此時應當儲存照片 
  43. if(keyCode == 13)  
  44.         {  
  45. //初始化一張圖片 
  46.             IplImage* outImage = cvCreateImage(cvGetSize(frame),frame->depth,frame->nChannels);  
  47. // 將原圖拷貝過來 
  48.             cvCopy(frame,outImage,NULL);  
  49. //實現縮放操作 
  50.             outImage = DoPyrDown(outImage);  
  51. //設定儲存的圖片名稱和格式 
  52. char* outImageName = "test.jpg";  
  53. //儲存圖片 
  54.             cvSaveImage(outImageName,outImage);  
  55.             cvReleaseImage(&outImage);  
  56.             printf(" 恭喜你,儲存圖片成功!\n");  
  57.         }  
  58. // 得到攝像裝置的下一幀影象 
  59.         frame = cvQueryFrame(capture);  
  60. if(!frame)  
  61.         {  
  62. break;  
  63.         }  
  64.         cvShowImage("vedio",frame);  
  65.     }  
  66.     cvReleaseImage(&frame);  
  67.     cvDestroyAllWindows();  
  68. return 0;  
  69. }  

F5執行結果: