OpenCV控制攝像頭實現 拍照功能
注意註釋部分,其中使用的比較生疏的 API 包括cvPyrDown ,cvCreateCameraCapture
以及cvCopy和cvSaveImage
下面就來一一解釋這幾個 API 的具體使用:
voidcvPyrDown( const CvArr* src, CvArr* dst, int filter=CV_GAUSSIAN_5x5 );
其中 src 為 CvArr * 型別,這裡順便解釋一下 OpenCV 基本上是用 C 實現的,當然其中包括一定的 C++ 成分,
但是 OpenCV 中仍然也使用了面向物件的思想,即有以下的繼承關係:
所以在實際使用當中,完全可以使用 ”子類” 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?- #include "stdafx.h"
- #include"cv.h"
- #include"highgui.h"
- #include"stdio.h"
- // 實現將拍下來的圖片縮放一倍
- IplImage* DoPyrDown(IplImage* image, int filter = IPL_GAUSSIAN_5x5)
- {
- // 設定大小縮小一倍
- CvSize size = cvSize(image->width / 2,image->height / 2);
- //初始化圖片
- IplImage* outImage = cvCreateImage(size,image->depth,image->nChannels);
- //實現縮放
- cvPyrDown(image,outImage);
- cvReleaseImage(&image);
- return outImage;
- }
- int main(int argc, char** argv)
- {
- cvNamedWindow("vedio");
- CvCapture* capture;
- // 首先是要通過攝像裝置來得到一個CvCapture物件
- if(1 == argc)
- {
- capture = cvCreateCameraCapture(0);
- }
- else
- {
- capture = cvCreateCameraCapture(atoi(argv[1]));
- }
- assert(NULL != capture);
- IplImage* frame;
- char keyCode;
- // 每隔30ms捕捉一次視訊影象
- // 可以設為while(1) 使得實時捕捉視訊畫面
- while((keyCode = cvWaitKey(30)))
- {
- //表示按下了ESC鍵,退出
- if(keyCode == 27)
- {
- break;
- }
- //表示按下了回車鍵,此時應當儲存照片
- if(keyCode == 13)
- {
- //初始化一張圖片
- IplImage* outImage = cvCreateImage(cvGetSize(frame),frame->depth,frame->nChannels);
- // 將原圖拷貝過來
- cvCopy(frame,outImage,NULL);
- //實現縮放操作
- outImage = DoPyrDown(outImage);
- //設定儲存的圖片名稱和格式
- char* outImageName = "test.jpg";
- //儲存圖片
- cvSaveImage(outImageName,outImage);
- cvReleaseImage(&outImage);
- printf(" 恭喜你,儲存圖片成功!\n");
- }
- // 得到攝像裝置的下一幀影象
- frame = cvQueryFrame(capture);
- if(!frame)
- {
- break;
- }
- cvShowImage("vedio",frame);
- }
- cvReleaseImage(&frame);
- cvDestroyAllWindows();
- return 0;
- }
F5執行結果: