1、OpenCV模塊划分
OpenCV其實就是一堆用C和C++語言來實現計算機視覺算法的源代碼文件;例如C接口函數cvCany()實現了Canny邊緣提取算法,我們可以直接將這些源代碼添加到自己的軟件項目中,而不需要自己去寫代碼實現Canny算法。同時由於源文件居多,所以根據算法的功能將源文件分到多個模塊中(如下),將每個模塊中的源文件編譯成一個庫文件(如opencv_core.lib、opencv_highgui.lib),用戶調用時僅將所需的庫文件添加到自己的項目中,與自己的源文件一起連接成可執行程序即可。
OpenCV2.0主體分為五個模塊:
1、CV圖像處理和視覺算法
2、MLL統計分類器
3、HighGUI圖像和視頻輸入/輸出
4、CXCORE(基本結構和算法,XML支持,繪圖函數)
5、CvAux(存放即將被淘汰的算法和函數,新出現的實驗性算法和函數)
(CVCAM攝像機接口屬於OpenCV1.0版內容,在以后的版本中被棄用)
2、命令行參數 argc/argv
c/c++語言中的main函數,經常帶有參數argc,argv,如下:
int main(int argc,char** argv)或者int main(int argc,char* argv[])
*1、argc:命令行輸入參數個數,以空白符分隔
*2、argv:中存儲了命令行參數
*3、如下圖在dos命令下進入到openpictures.exe文件所在目錄下運行命令:openpictures.exe lena.jpg lena2.jpg
那么有:argc=3,argv[0] = openpictures.exe,argv[1] = lena.jpg,argv[2] = lena2.jpg。
3、麻雀雖小五臟俱全之典例精析
實現功能:
輸入openpictures.exe lena.jpg命令符后,執行:顯示lena.jpg圖片的功能
輸入openpictures.exe lena.jpg lena2.jpg命令符后,執行:顯示lena.jpg圖像、並將其寫入lena2.jpg文件
(你會發現在lena.jpg所在文件目錄下多出來一個lena2.jpg文件並且跟lena.jpg圖片信息一樣)
函數精析:
-
cvLoadImage(fileName,flag)
- 將圖像文件fileName以flag代表的格式加載至內存
- fileName包含文件的擴展名,確定被加載文件的格式;例如lena.jpg
- flag<0:默認讀取圖像的原通道數;flag=0:強制以單通道灰度形式讀取;flag>0:強制以三通道形式讀取
- 高層調用接口,通過fileName確定被加載文件的格式,並且該函數將自動分配圖像數據結構所需的內存。函數執行完后將返回一個指針,此指針指向一塊為描述該圖像文件的數據結構而分配的內存塊。
-
cvNamedWindow(“win1”,CV_WINDOW_AUTOSIZE)
- 用於在屏幕上創建一個窗口,將被顯示的圖片包含於該窗口中
- win1:指定了窗口的標題,其他函數與該窗口進行交互使用時,通過該參數值引用這個窗口
- 第二個參數定義了窗口的屬性,通常設為CV_WINDOW_AUTOSIZE/1,兩者等價:表示窗口大小會自動調整以適應被顯示的圖像,並且不能夠手動調節大小。設為>=0的其他數值時:圖像只能在窗口中根據窗口大小進行拉伸或縮放。
-
cvShowImage(“win1”,img)
- 將在制定的窗口win1中顯示圖像img
- 參數1:顯示圖像的窗口標識符;參數2:要被顯示的圖像
- 該函數調用時窗口將被重新繪制,同時圖像也會顯示在窗口中
- 只要有一個與某個圖像文件相對應的IplImage*類型指針,我們就可以在一個已創建好的窗口中使用該函數顯示該圖像
-
cvWaitKey(int delay)
- delay<=0時:永久等待;delay>0時:等待至少delay毫秒時間,因為考慮到操作系統切換時間
- 在沒有按鍵按下時,函數等待delay 毫秒時間長后返回-1;如果按鍵按下則返回按鍵的ASCII碼,然后繼續執行程序
- fileName包含文件的擴展名,確定被加載文件的格式;例如lena.jpg
- flag<0:默認讀取圖像的原通道數;flag=0:強制以單通道灰度形式讀取;flag>0:強制以三通道形式讀取
-
cvReleaseImage(&img)
- 一旦用完加載到內存的圖像文件,我們就可以釋放該圖像文件所分配的內存。調用完畢后img指針將被設置為NULL。
-
cvDestoryWindow(“win1”)
- 銷毀顯示圖像文件的窗口;關閉窗口並釋放該窗口所分配的所有內存(包括窗口內部的圖像內存緩區:保存了與img指針相關的圖像文件像素的一個副本)。
- 當應用程序的窗口被關閉時,該應用程序窗口所占用的一切資源都會由操作系統自動釋放,所以對一些簡單的程序,不必調用cvDestroy()或cvReleaseImage()函數顯式釋放資源。但是,養成習慣每次都調用這些函數顯式釋放資源總是好的
-
cvMoveWindow(“win1”,int x,int y)
- 移動win1窗口到指定的坐標(x,y)位置
- 默認顯示屏左上角為原點;x,y:為偏移位置
-
cvResizeWindow(“win1”,int width,int height)
- 設定窗口尺寸為指定寬度和高度
- 設定的窗口尺寸是指顯示圖像的窗口尺寸,不包含拖動條
- 只有創建的窗口flag屬性不為CV_WINDOW_AUTOSIZE時才能夠調用此函數
-
cvGetSize(const CvArr* arr)
- 函數返回輸入矩陣或者圖像arr的行數和列數;當為圖像時返回感興趣區域的尺
- cvCreateImage(CvSize size,int depth,int channels)
- 創建圖像頭並且分配圖像數據;返回IplImage結構
- size:圖像的寬度和高度;depth:圖像像素的位深度;channels:圖像的通道數
- 位深度:可以使有的選擇如下:
IPL_DEPTH_8U:無符號8bit整型
IPL_DEPTH_8S:無符號8bit整型
IPL_DEPTH_16U:無符號16bit整型
IPL_DEPTH_16S:有符號16bit整型
IPL_DEPTH_32S:有符號32bit整型
IPL_DEPTH_32F:單精度浮點數
IPL_DEPTH_64F:雙精度浮點數
-
cvCopy(const CvArr* src,const CvArr* dst,const CvArr* mask)
- 函數復制一個數組數據到另一個數組中
- src:源輸入數組;dst:輸出數組;mask:操作掩碼,必須為8位單通道數組,指定輸出數組的被改變元素
- dst(i) = src(i) if mask(i) != 0
- 輸入輸出數組必須為同類型,維數大小相同;如果是IplImage類型,則ROI和COI將被使用
-
cvSaveImage(const char* filename,const CvArr* Image)
- 保存圖像Image到指定文件filename
附源代碼:
#include "stdafx.h" #include "highgui.h" int main(int argc, char** argv) { IplImage* pImg; //聲明IplImage指針 if(argc == 2 && (pImg = cvLoadImage(argv[1],1)) != 0) //當(“輸入兩個字符串”並且“成功讀入圖片”)時 { cvNamedWindow("Image",1); //創建標題為Image的窗口,並且隨實際圖片大小改變窗口尺寸 cvShowImage("Image",pImg); //在Image窗口內顯示pImg指針所指圖像 cvWaitKey(); //等待按鍵 cvDestroyWindow("Image"); //銷毀窗口 cvReleaseImage(&pImg); //釋放圖像 return 0; } else if(argc == 3 && (pImg = cvLoadImage(argv[1],1)) != 0) //當(“輸入三個字符串”並且“成功讀入圖片”)時 { IplImage* pImg2 = cvCreateImage(cvGetSize(pImg),pImg->depth,pImg->nChannels); //以圖像pImg的格式創建圖像pImg2 cvCopy(pImg,pImg2,NULL); //復制pImg圖像數據到pImg2 cvSaveImage(argv[2],pImg2); //把圖像pImg2寫入以輸入第三個字符串為名字的文件中 cvNamedWindow("Image",1); //創建窗口 cvShowImage("Image",pImg); //顯示圖像 cvWaitKey(0); //等待按鍵 cvDestroyWindow("Image"); //銷毀窗口 cvReleaseImage(&pImg); //釋放圖像 return 0 ; } return -1; }