一、OpenCV概述與功能介紹
OpenCV是Intel®開源電腦視覺庫。它由一系列 C 函數和少量 C++ 類構成,實現了影像處理和電腦視覺方面的很多通用演算法。OpenCV 擁有包括 300 多個C函數的跨平台的中、高層 API。它不依賴於其它的外部庫——儘管也可以使用某些外部庫。
OpenCV 對非商業應用和商業應用都是免費(FREE)的。(細節參考 license)。代碼下載地址:http://www.sourceforge.net/projects/opencvlibrary
OpenCV 為Intel® Integrated Performance Primitives (IPP) 提供了透明介面。 這意味著如果有為特定處理器最佳化的的 IPP 庫, OpenCV 將在運行時自動載入這些庫。 更多關於 IPP 的資訊請參考: http://www.intel.com/software/products/ipp/index.htm
它有以下特點:
1) 開放的C/C++源碼
2) 基於Intel處理器指令集開發的最佳化代碼
3) 統一的結構和功能定義
4) 強大的映像和矩陣運算能力
5) 方便靈活的使用者介面
6)同時支援MS-WINDOWS、LINUX平台
作為一個基本的電腦視覺、影像處理和模式識別的開源項目,OPENCV可以直接應用於很多領域,作為第二次開發的理想工具。
OpenCV功能介紹:
OpenCV包含如下幾個部分:
Cxcore:一些基本函數(各種資料類型的基本運算等)。
Cv:影像處理和電腦視覺功能(影像處理,結構分析,運動分析,物體跟蹤,模式識別,攝像機定標)
Ml:機器學習模組,目前內容主要為分類器。
Cvaux:一些實驗性的函數(ViewMorphing,三維跟蹤,PCA,HMM)
Highgui:使用者互動部分,(GUI,圖象視頻I/O,系統調用函數)
二、OpenCV安裝
OpenCV2.0剛剛發布,VC 2008 Express下安裝OpenCV2.0請參考:
http://www.opencv.org.cn/index.php/VC_2008_Express%E4%B8%8B%E5%AE%89%E8%A3%85OpenCV2.0
三、基礎知識:
1、opencv 資料類型轉換操作小結
(1)映像中或矩陣數組中資料格式轉換:
cvConvert( image, image_temp );
cvConvertScale( const CvArr* src, CvArr* dst, double scale CV_DEFAULT(1), double shift CV_DEFAULT(0) );
cvScale(src, dst);
// Converts CvArr (IplImage or CvMat,...) to CvMat.
cvGetMat( const CvArr* arr, CvMat* header, int* coi CV_DEFAULT(NULL), int allowND CV_DEFAULT(0));
cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask ); //可以實現對不規製圖形的提取
(2)多通道映像轉成數組中資料
cvGetMat( const CvArr* array, CvMat* mat, int* pCOI, int allowND )
cvCopy(img,mat);
// Converts CvArr (IplImage or CvMat,...) to CvMat.
cvGetMat( const CvArr* arr, CvMat* header, int* coi CV_DEFAULT(NULL), int allowND CV_DEFAULT(0));
(3) 數組中資料轉成多通道映像
cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL );
cvGetMat( const CvArr* arr, CvMat* header, int* coi CV_DEFAULT(NULL), int allowND CV_DEFAULT(0));
2、二值化函數cvAdaptiveThreshold和cvThreshold的一些發現
自適應二值化計算像素的鄰域的平均灰階,來決定二值化的值。如果整個地區幾乎是一樣灰階的,則無法給出合適的結果了。之所以看起來像邊緣檢測,是因為窗尺寸設定的小,可以改大一點試一試。
cvAdaptiveThreshold( src, dst, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 21); //窗設定為21
沒有萬能的二值化方法,具體問題具體分析,自適應二值化對於光照不均的文字,條碼等,效果很好。視窗大小選擇,考慮被檢測物體尺寸。自適應閾值化中的閾值完全是由你所選擇的鄰域所確定的,如果你所選擇的鄰域非常小(比如3×3),那麼很顯然閾值的“自適應程度”就非常高,這在結果映像中就表現為邊緣檢測的效果。如果鄰域選擇的比較大(比如31×31),那麼閾值的“自適應程度”就比較低,這在結果映像中就表現為二值化的效果。
3、用 gabor 和 AdaBoost (MultiBoost )做目標檢測Image Recognition
http://www.opencv.org.cn/forum/viewtopic.php?f=10&t=7790
4、視頻跟蹤方法
跟蹤的方法我知道的有KLMAN濾波.粒子濾波.camshift.meanshift。 基於Mean Shift的閾值分割:http://www.codesoso.com/code/mean_shift.aspx http://arslan-ai.spaces.live.com/blog/cns!CAE7EF891A2218BA!123.entry
5、怎麼訪問映像像素
(座標是從0開始的,並且是相對映像原點的位置。映像原點或者是左上方 (img->origin=IPL_ORIGIN_TL) 或者是左下角 (img->origin=IPL_ORIGIN_BL) )
假設有 8-bit 1-通道的映像 I (IplImage* img):
---------------------------------------------------------------------
I(x,y) ~ ((uchar*)(img->imageData + img->widthStep*y))[x]
---------------------------------------------------------------------
假設有 8-bit 3-通道的映像 I (IplImage* img):
---------------------------------------------------------------------
I(x,y)blue ~ ((uchar*)(img->imageData + img->widthStep*y))[x*3]
I(x,y)green ~ ((uchar*)(img->imageData + img->widthStep*y))[x*3+1]
I(x,y)red ~ ((uchar*)(img->imageData + img->widthStep*y))[x*3+2]
------------------------------------------------------------------------------
例如,給點 (100,100) 的亮度增加 30 ,那麼可以這樣做:
------------------------------------------------------------------------------
CvPoint pt = {100,100};
((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3] += 30;
((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3+1] += 30;
((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3+2] += 30;
-----------------------------------------------------------------------------
或者更高效地:
-----------------------------------------------------------------------------
CvPoint pt = {100,100};
uchar* temp_ptr = &((uchar*)(img->imageData + img->widthStep*pt.y))[pt.x*3];
temp_ptr[0] += 30;
temp_ptr[1] += 30;
temp_ptr[2] += 30;
-----------------------------------------------------------------------------
假設有 32-bit 浮點數, 1-通道 映像 I (IplImage* img):
-----------------------------------------------------------------------------
I(x,y) ~ ((float*)(img->imageData + img->widthStep*y))[x]
-----------------------------------------------------------------------------
現在,一般的情況下,假設有 N-通道,類型為 T 的映像:
-----------------------------------------------------------------------------
I(x,y)c ~ ((T*)(img->imageData + img->widthStep*y))[x*N + c]
-----------------------------------------------------------------------------
你可以使用宏 CV_IMAGE_ELEM( image_header, elemtype, y, x_Nc )
-----------------------------------------------------------------------------
I(x,y)c ~ CV_IMAGE_ELEM( img, T, y, x*N + c )
-----------------------------------------------------------------------------