晁 越,李中健,黃士飛(.西北工業(yè)大學(xué) 自動化學(xué)院,陜西 西安 709;.中國人民解放軍978部隊 上海00436)
OpenCV的全稱是:Open Source Computer Vision Library。是Intel公司支持的開源計算機(jī)視覺庫。它輕量級而且高效——由一系列C函數(shù)和少量C++類構(gòu)成,實現(xiàn)了圖像處理和計算機(jī)視覺方面的很多通用算法。由于OpenCV的源代碼是完全開放的,而且源代碼的編寫簡潔而又高效,特別是其中大部分的函數(shù)都已經(jīng)過匯編最優(yōu)化,以使之能高效而充分地利用英特爾系列處理芯片的設(shè)計體系,所以近年來在國外的圖像處理相關(guān)領(lǐng)域中被廣泛地使用,成為一種流行的圖像處理軟件。
OpenCV設(shè)計了一些基礎(chǔ)的數(shù)據(jù)類型和一些幫助數(shù)據(jù)類型,在運(yùn)用OpenCV函數(shù)庫進(jìn)行編程的過程中,常常會需要用到這些結(jié)構(gòu)類型,只有真正了解這些結(jié)構(gòu)才能夠很好地利用OpenCV函數(shù)庫來解決問題。我們在此僅介紹IplImage進(jìn)行介紹。通常情況下,使用DIB格式來處理圖像,而OpenCV庫則是使用 “IplImage”結(jié)構(gòu)體來創(chuàng)造和處理圖像。由于OpenCV主要針對的是計算機(jī)視覺方面的處理,因此在函數(shù)庫中,最重要的結(jié)構(gòu)體就是IplImage結(jié)構(gòu)。IplImage結(jié)構(gòu)來源于inter的另外一個函數(shù)庫IPL,該函數(shù)庫主要是針對圖像處理。使用這種格式的優(yōu)點(diǎn)是可以比DIB格式表示更多的圖像性質(zhì),而且可以很方便地存取圖像中的像素值,IplImage結(jié)構(gòu)的具體定義如下[1]:
width和height這兩個變量很重要,其次是depth和nchannals。depth變量的值取自ipl.h中定義的一組數(shù)據(jù),但與在矩陣中看到的對應(yīng)變量不同。因為在圖像中,我們往往將深度和通道數(shù)分開處理,而在矩陣中,我們往往同時表示它們。可用的深度值如表1所示(通道數(shù)nChannels可取的值是1,2,3或4)。
表1 OpenCV圖像類型Tab.1 Image types of OpenCV
OpenCV1.0版本,包含以下5個部分:
1)CxCore:一些基本函數(shù)(各種數(shù)據(jù)類型的基本類型的基本運(yùn)算等)。
2)CV:圖像處理和計算機(jī)視覺功能(圖像處理、結(jié)構(gòu)分析、運(yùn)動分析、物體跟蹤、模式識別、攝像機(jī)定標(biāo))。
3)CvAux:一些實驗性的函數(shù)。
4)HighGUI:用戶交互部分(GUI,圖像視頻I/O、系統(tǒng)調(diào)用函數(shù))。
5)CvCam:linux版本中已經(jīng)拋棄,windows版本中將directx支持加入HighGUI后,CVCam將徹底去掉。
下面介紹一下OpenCV中常用的3種函數(shù):
1)LoadImage():圖像載入函數(shù)
語 法:IplImage*cvLoadImage(const char*filename,int iscolor=1);
參數(shù)類型說明
Filename const char*待載入圖像的名稱,包括圖像的擴(kuò)展名
Iscolor int輔助參數(shù)項,可選正數(shù)、負(fù)數(shù)、零。正數(shù)表示強(qiáng)制作為三通道(彩色)圖像載入,零表示該圖像作為單通道(灰度)圖像,負(fù)數(shù)表示載入圖像的通道數(shù)由圖像文件自身決定
返回值:IplImage結(jié)構(gòu)指針
2)NamedWindow():窗口定義函數(shù)
語 法:int cvNamedWindow (const char*name,unsigned long flags);
參數(shù)類型說明
Name const char*窗口名
Flags unsigned long窗口屬性指標(biāo)值,可以選擇CV_WINDOW_AUTOSIZE
1和0兩種值。CV_WINDOW_AUTOSIZE表示窗口尺寸與原始尺寸相同,0表示以固定的尺寸顯示圖像
說明:cvNamedWindow創(chuàng)建一個放置圖像和rtackbar的窗口。被創(chuàng)建的窗口可以通過他們的名字被引用。如果已經(jīng)存在這個名字的窗口,這個函數(shù)將不做任何事情。
返回值:無。
3)WaitKey():按鈕等待函數(shù)
語法:int cvWaitKey(int delay=0);
參數(shù)類型說明
Delay int等待按鍵。如果delay<=0,那么無限等待;否則等待delay毫秒這返回
說明:在程序循環(huán)中,有時候由于程序一直處于計算中,導(dǎo)致窗口無法重繪(比如讀出視頻中的所有幀并顯示),可以加入cvWaitKey函數(shù),使程序等待幾毫秒,讓窗口完成重繪在執(zhí)行其他操作。
早期的分水嶺算法的效率較低,Vincent[3]提出的改進(jìn)分水嶺算法使處理效率大大提高,使得分水嶺算法為越來越多的學(xué)者所重視。
Vincent分水嶺算法處理過程:
1)排序過程,按圖像各像素的灰度值進(jìn)行升序排列;
2)浸沒過程,對每一層的閾值進(jìn)行寬度優(yōu)先搜索,通過queue結(jié)構(gòu)(FIFO)完成;
下面對該算法的處理過程進(jìn)行詳細(xì)的描述[4]:
1)排序過程
對指針進(jìn)行操作,確定圖像精確的灰度級頻率分布。使得每個像素都可以被直接定位到排序數(shù)組中的唯一單元。
n,圖像的像素數(shù)目;
hmin,最低的灰度級別;
hmax,最高的灰度級別。
這種排序技術(shù)只需要2n步 “查找和處理”操作,(hmaxhmin-1)步“賦值”操作以得到累積頻率分布。所以,排序所需要的時間和所占用的內(nèi)存幾乎可以忽略不計。從而,能夠直接從排序數(shù)組(元素為指向圖像像素的指針)中讀取給定層高的某層像素,用于下一步的浸沒操作。
2)浸沒過程
一旦,對圖像的像素排序完畢,就開始進(jìn)行浸沒聚水盆的操作。假定,現(xiàn)在已經(jīng)浸沒到高度為h的某層。每個被找到聚水盆(例如,每個聚水盆的相應(yīng)最小值的點(diǎn)的高度都低于或等于h)被賦予一個唯一的標(biāo)識。由于已經(jīng)有了像素的排序數(shù)組,所以我們可以直接讀取h+1層的像素,并給賦給它們具體的值,這一過程稱為“MASK”。作為當(dāng)前像素鄰居、已經(jīng)被標(biāo)識的像素被放進(jìn)queue里。從這些像素開始,queue可以將標(biāo)識好的聚水盆擴(kuò)展,并遞歸浸沒過程,直至所有的像素都被處理。
OpenCV函數(shù)庫中分水嶺源代碼是在Vincent分水嶺算法的基礎(chǔ)上進(jìn)行的改進(jìn)。它首先計算灰度圖像[5]的梯度;這對山谷或沒有紋理的盆地(亮度是低的點(diǎn))的形成有效,也對山頭或圖像中有主導(dǎo)線段的山脈(山脊對應(yīng)的邊緣)的形成有效。然后開始從用戶指定點(diǎn)(或算法得到點(diǎn))開始持續(xù)“灌注”盆地直到這些區(qū)域連在一起?;谶@樣產(chǎn)生的標(biāo)記就可以把區(qū)域合并到一起,合并后的區(qū)域又通過聚集的方式進(jìn)行分割,好像圖像被“填充”起來一樣。通過這種方式,與指示點(diǎn)相連的盆地就為指示點(diǎn)“所擁有”。最終能把圖像分割成相應(yīng)的標(biāo)記區(qū)域。
更確切地說,該分水嶺算法允許用戶(或算法)來標(biāo)記目標(biāo)的某個部分為目標(biāo),或背景的某個部分為背景。用戶或算法可以通過畫一條簡單的線,有效地告知分水嶺算法把這些點(diǎn)像這樣的組合起來。接著分水嶺算法通過允許在梯度圖像中和片段連接的標(biāo)識區(qū)域“擁有”邊沿定義的山谷來分割圖像。
分水嶺算法的函數(shù)定義如下[6]:
void cvWatershed(const CvArr*image,CvArr*markers);
這里image是一個8位 (三通道)的彩色圖像,而markers是單通道整型(IPL_DEPTH_32S),具有相同維數(shù)(x,y)。除非用戶(或算法)用正整數(shù)標(biāo)記屬于同一部分的區(qū)域,markers的值都是0。
如圖2所示,左邊的青椒被標(biāo)記為1,中間的青椒被標(biāo)記為2,上邊的青椒被標(biāo)記為3,右邊的被標(biāo)記為4,背景被標(biāo)記為5。程序通過對每個標(biāo)記給定一個正整數(shù),并把未標(biāo)記的區(qū)域記為-1,從而告知分水嶺用戶標(biāo)記的邊緣,并在此基礎(chǔ)上進(jìn)行分水嶺分割,然后用隨機(jī)生成的顏色填充分割后的區(qū)域,得到最終的結(jié)果如圖3。
圖2 分割前標(biāo)記圖Fig.2 Marked original image
圖3 分割結(jié)果圖Fig.3 Watershed segmentation image
由于時間的限制,本文僅在了解OpenCV初級使用的基礎(chǔ)上,對數(shù)字圖像進(jìn)行了分割處理,并未達(dá)到自適應(yīng)的效果。希望在研究生階段能深入了解OpenCV的特性,更好的掌握OpenCV的使用,通過該軟件提高對數(shù)字圖像的處理技術(shù);并嘗試通過移植OpenCV在DSP平臺上實現(xiàn)圖像處理功能。
圖1 原圖像Fig.1 Original image
[1]陳勝勇,劉盛.基于OpenCV的計算機(jī)視覺技術(shù)實現(xiàn)[M].北京:科學(xué)出版社,2008.
[2]Gary Bradski and Adrian Kaebler.Learning OpenCV(影印版)[M].南京:東南大學(xué)出版社,2009.
[3]陳天華.數(shù)字圖像處理[M].北京:清華大學(xué)出版社,2007.
[4]景曉軍.圖像處理技術(shù)及應(yīng)用[M].北京:國防工業(yè)出版社,2005.
[5]劉瑞禎,于仕琪.OpenCV教程基礎(chǔ)篇[M].北京:北京航空航天大學(xué)出版社,2007.
[6]章毓晉.圖像分割[M].北京:科學(xué)出版社,2001.