OpenCV是一個(gè)基于BSD許可(開源)發(fā)行的跨平臺(tái)計(jì)算機(jī)視覺庫,可以運(yùn)行在Linux、Windows、Android和Mac OS操作系統(tǒng)上。它輕量級(jí)而且高效——由一系列 C 函數(shù)和少量 C++ 類構(gòu)成,同時(shí)提供了Python、Ruby、MATLAB等語言的接口,實(shí)現(xiàn)了圖像處理和計(jì)算機(jī)視覺方面的很多通用算法。OpenCV用C++語言編寫,它的主要接口也是C++語言,但是依然保留了大量的C語言接口。該庫也有大量的Python, Java and MATLAB/OCTAVE (版本2.5)的接口。這些語言的API接口函數(shù)可以通過在線文檔獲得。如今也提供對(duì)于C#,Ch, Ruby的支持。
OpenCV于1999年由Intel建立,如今由Willow Garage提供支持。OpenCV是一個(gè)基于BSD許可[1] (開源)發(fā)行的跨平臺(tái)計(jì)算機(jī)視覺庫,可以運(yùn)行在Linux、Windows和Mac OS操作系統(tǒng)上。它輕量級(jí)而且高效——由一系列 C 函數(shù)和少量 C++ 類構(gòu)成,同時(shí)提供了Python、Ruby、MATLAB等語言的接口,實(shí)現(xiàn)了圖像處理和計(jì)算機(jī)視覺方面的很多通用算法。 最新版本是3.3 ,2017年8月3日發(fā)布。
OpenCV 擁有包括 500 多個(gè)C函數(shù)的跨平臺(tái)的中、高層 API。它不依賴于其它的外部庫——盡管也可以使用某些外部庫。OpenCV 為Intel? Integrated Performance Primitives (IPP) 提供了透明接口。 這意味著如果有為特定處理器優(yōu)化的 IPP 庫, OpenCV 將在運(yùn)行時(shí)自動(dòng)加載這些庫。
VC++是微軟公司開發(fā)的一個(gè)集成開發(fā)環(huán)境,具有多方面強(qiáng)大的功能,可以利用其開發(fā)許多領(lǐng)域的實(shí)用軟件,數(shù)字圖像處理也是其主要功能之但純用VC++處理圖像難度很大,僅圖像的讀入和顯示就需要很大的代碼量,并要求開發(fā)人員必須對(duì)圖像的內(nèi)部結(jié)構(gòu)認(rèn)識(shí)清晰且能熟練使用C+t語言。而對(duì)于初次使用VC++處理圖像的人員來說要做到這些方面確實(shí)有一定的難度。OPENCV提供了許多數(shù)字圖像處理的函數(shù),如果能和VC++結(jié)合使用將會(huì)在很大程度上降低工作難度,減少工作量。本文以灰度圖像的目標(biāo)提取為例說明OPENCV和VC++結(jié)合處理圖像的能力。
環(huán)境配量
在VC++中使用OPENCV函數(shù),首先要將OPENCV函數(shù)庫嵌入到VC++中。目前OPENCV最典型的版本為1.0和2.0,VC++版本有6.0,2005和2008,若要使用OPENCV2.0則必須使用VC++2005或VC++2008,因?yàn)槟壳癘PENCV2.0在VC++6.0中還沒有成功案例。本文以O(shè)PENCV1.0和VC++6.0作為開發(fā)環(huán)境。將OPENCV1.0函數(shù)庫嵌入到VC++6.0的方法很多資料上都有詳細(xì)的闡述,這里就不做介紹了。
目標(biāo)提取
目標(biāo)提取的任務(wù)是從單幅圖像或序列圖像中將感興趣的目標(biāo)與背最分割開來,用于后續(xù)的處理。感興趣目標(biāo)的有效提取對(duì)于目標(biāo)分類、身份識(shí)別和行為理解等中高層次的任務(wù)非常重要,因?yàn)楹罄m(xù)的處理過程通常只考慮圖像中對(duì)應(yīng)于感興趣區(qū)域的像素,并將極大的促進(jìn)視頻編碼、檢索、人機(jī)交互、運(yùn)動(dòng)捕捉等課題的研究目標(biāo)提取技術(shù)最常見的處理過程如圖1所示:
導(dǎo)入圖像
對(duì)一幅圖像進(jìn)行處理之前,首先要讀取圖像的相關(guān)數(shù)據(jù),為了觀察算法的實(shí)現(xiàn)效果,還需清楚地看到處理后的圖像結(jié)果,這就需要讀入和顯示圖像。假若只用VC++,需要開發(fā)人員對(duì)圖像的結(jié)構(gòu)及VC++知識(shí)有個(gè)深刻的理解,代碼量大,運(yùn)算復(fù)雜,這就讓很多初學(xué)者望而卻步,然而在VC++環(huán)境下借助OPENCV函數(shù)庫,可以方便的讀入和顯示圖片。代碼如下:
Ip1Image*img=cvLoadImage(“E: \hua.bmp”,-1) ;
cvNamedWindow(“win1”,0) ;
cvShowImage(“win1”,img) ;
cvWai tKey (0) ;
第一句功能為讀入圖像,需要注意的是表示路徑的反斜杠必須為“\”,因?yàn)樽址小癨”為轉(zhuǎn)義字符,代表一個(gè)“”,參數(shù)“-1”表示以原有顏色通道顯示圖像(還可以選擇別的值,在這里就不加說明了); 第二句功能為建立一個(gè)名字為“win1“ 的窗口,“0”表示窗 口 大小由系統(tǒng)自動(dòng)給定; 第三句功能是將圖像在“win1” 窗口中顯示; 第四句功能為延遲窗口顯示時(shí)間,按回車鍵窗口會(huì)關(guān)閉,假若沒有第四局,圖像會(huì)閃一下消失,用戶觀察不到具體的圖像。
去除背景
讀入圖像后,需要做的第一步就是去除背景。去除背景就是在一幅圖像中,把目標(biāo)從背景中分離出來,以便于進(jìn)一步處理[2]。去除背最是目標(biāo)提取的一個(gè)重要環(huán)節(jié),背最是否去除干凈以及目標(biāo)圖像保留信息的完整性直接決定著下一步任務(wù)能否正常完成。去除背最方法根據(jù)算法的不同可分為闞值法、邊界探測(cè)法和匹配法等[3],其中闊值法的使用最為普遍。眾多資料介紹了多種圖像閾值分割算法。OPENCV提供了固定闞值分割函數(shù)cvThreshold和自適應(yīng)闞值函數(shù)cvAdaptiveThreshold,函數(shù)cvThreshold對(duì)單通道數(shù)組應(yīng)用固定閾值操作,該函數(shù)的典型應(yīng)用是對(duì)灰度圖像進(jìn)行固定閾值操作得到二值圖像,cvAdaptiveThreshold原則上為自適應(yīng)闞值算法提供的函數(shù),然而經(jīng)過測(cè)試,此函數(shù)的確切功能是獲得物體邊緣,而非二值化函數(shù),這應(yīng)該是OPENCV不完善的地方之一。
在眾多的闞值法分割圖像算法中,大津法OSTU (又叫最大類間方差法) 是闞值分割的經(jīng)典算法。大津法利用闞值threld將圖像分為前景和背景,前最點(diǎn)數(shù)占圖像比例為n1,平均灰度為o1,背景點(diǎn)數(shù)占圖像比例為n2,平均灰度為m2,圖像總的平均灰度為=n1*如1+n2*m2,前景和背景像素方差公式為n1*(m1-m)2+n2*(m-m2)2,將m的值帶入上式即得最終方差公式n1*n2*(m1-m2)*(m1-m2),當(dāng)方差值最大時(shí),說明此時(shí)的闞值threld最合適.OSTU算法的核心代碼如下:
for(k=0; k《256; k++)
{
n1+=ihist[k];
if(!nl)
cont inue ;
n2=n-n 1;
if(n2==0)
break ;
csum+=k*ihist[k];
m1=csum/n1;
m2=(sum-csum)/n2;
sb=n1*n2*(m1-m2)*(m1-m2) ;
if (sb》fmax)
{
fmax=sb;
threld=k;
}
}
}
經(jīng)過OSTU算法找出最佳闞值后,將小于闞值的像素設(shè)為0,大于闞值的像素設(shè)為256,這樣圖像被設(shè)置為黑白兩色(白背景黑目標(biāo))。代碼如下:
for(i=0; i《height; i++)
{
for(j=0; j《width; j++)
{
for(k=0; k《channels; k++)
if(data[i*step+j*channels+k]》threld)
data [i *s t ep+j*c hanne 1s +k]=256 ;
else
data[i*step+j*channels+k]=0;
}
}
}
其中,“height“為圖像寬,“width為圖像高,“ channe 1s”為圖像通道,“data[i*step+j*channels+k]” 為像素?cái)?shù)值,threld為OSTU算法得出的閾值。
因?yàn)閳D像可能有不同程度的噪波,因此圖像進(jìn)行這樣的處理后可能不需要靈活采取各種方法處理噪波的會(huì)達(dá)到完全處理掉背景的目的,此時(shí),遺留痕跡,如腐蝕和膨脹,OPENCV分別提供了對(duì)應(yīng)的函數(shù)Erode()和Dilate()。
二值化圖像
通過以上過程得到黑白兩色圖像,對(duì)于深色背景淺色目標(biāo)得到黑背景白目標(biāo),對(duì)于淺色背景深色目標(biāo)得到白背景黑目標(biāo)。由于控制器在處理圖像時(shí)對(duì)于白色檢測(cè)對(duì)象辨別度較好,故應(yīng)將目標(biāo)設(shè)為白色,就是說,假若得到白背景黑目標(biāo),需要對(duì)其進(jìn)行反色處理。利用OPENCV在VC++環(huán)境中對(duì)圖像進(jìn)行反色處理的代碼為:
i++)
for(i=0; i《height;
for(j=0; j《width; j++)
for(k=0; k《channels; k++)
Data[ i*s t ep+j*channe ls + k]=255-data[ i*s t ep+j*c hanne ls + k] ;
以上的黑白圖像為灰度圖像,即像素值為0到255,而二值化圖像像素不是0 (黑色) 就是1(白色),有時(shí)候?yàn)榱擞?jì)算簡單需將黑白灰度圖像轉(zhuǎn)換為二值圖像,OPENCV提供了cvThreshold函數(shù)對(duì)圖像進(jìn)行二值化。同樣,
假若得到的二值圖像是白背景黑目標(biāo),需要將其反色處理。
提取目標(biāo)
通過以上過程已經(jīng)得到了白色目標(biāo)。如果需要顯示目標(biāo)輪廓,OPENCV提供了對(duì)應(yīng)的函數(shù)cvFindContours.以下如圖2和圖3為相關(guān)試驗(yàn)結(jié)果:
由上可知,在VC++環(huán)境下進(jìn)行數(shù)字圖像處理時(shí),若借助于OPENCV函數(shù)以上方法僅適合庫,可以在很大程度上降低工作難度。而通過實(shí)驗(yàn)可知,于簡單背景圖像的目標(biāo)提取,對(duì)于復(fù)雜背景,僅僅使用OSTU法去除背景還不能達(dá)到非常滿意的效果,在這方面,還需要進(jìn)行進(jìn)一步的研究。
評(píng)論
查看更多