摘 要: 圖像的閾值化在圖像分割中有著至關(guān)重要的作用。在OpenCV 算法環(huán)境下,運(yùn)用固定閾值化和自適應(yīng)閾值化算法,分別對同一幅圖調(diào)用OpenCV 中相應(yīng)的函數(shù)進(jìn)行處理;同時(shí)針對圖像中的噪聲,結(jié)合高斯模糊算法對圖像噪聲的濾除作用,將高斯模糊和閾值化算法結(jié)合起來,分析研究圖像分割算法。結(jié)果表明自適應(yīng)閾值化算法可以更有效地進(jìn)行圖像分割。
關(guān)鍵字: OpenCV; 自適應(yīng)閾值; 圖像分割; 固定閾值
中圖分類號: TN919?34; TP32 文獻(xiàn)標(biāo)識(shí)碼: A 文章編號: 1004?373X(2013)24?0073?04
Research and implementation of image threshold segmentation based on OpenCV
LEI Jian?feng, WANG Wei
(Capital Medical University, Beijing 100069, China)
Abstract:The image threshold plays a very important role in image segmentation. In the OpenCV algorithm environment, the fixed threshold algorithm and adaptive threshold algorithm are emploied respectively to process the same image by calling the corresponding function in OpenCV. The noise in the image is eliminated in combination with the filtering function of Gauss fuzzy algorithm. The image segmentation algorithm was analyzed by means of Gauss fuzzy and thresholding algorithm. The results show that the adaptive threshold algorithm can perform image segmentation more efficiently.
Keyword: OpenCV; adaptive threshold; image segmentation; fixed threshold
1 OpenCV簡介
OpenCV是一種開源的軟件,采用基于C/C++語言編寫,OpenCV可以在多種操作系統(tǒng)上運(yùn)行同時(shí)為其他軟件提供了多種接口。在數(shù)據(jù)類型上OpenCV提供了多種基本數(shù)據(jù)類型。雖然這些數(shù)據(jù)類型在C語言中不是基本類型,但結(jié)構(gòu)都很簡單,可將它們作為原子類型。OpenCV 主體分為5個(gè)模塊,其中4個(gè)模塊如圖1所示。
圖1 OpenCV基本結(jié)構(gòu)圖
OpenCV的目標(biāo)是為計(jì)算機(jī)視覺提供基本工具,在處理計(jì)算機(jī)視覺中一些很復(fù)雜的問題時(shí),可以利用OpenCV提供的高層函數(shù)有效地解決這些問題。OpenCV有一個(gè)強(qiáng)大的函數(shù)庫,它可以提供基本函數(shù)為大多數(shù)計(jì)算機(jī)視覺問題創(chuàng)建一個(gè)完整解決方案。
2 圖像分割
圖像分割[1]是圖像分析中很重要的基礎(chǔ)環(huán)節(jié),只有準(zhǔn)確地將對象從圖像中提取出來,才能進(jìn)一步對該對象做定量的描繪。圖像分割又是比較困難的環(huán)節(jié),因?yàn)樵谠S多情況下,對象與背景之間很難區(qū)分。所以圖像分割算法已經(jīng)成為圖像處理[2]和分析領(lǐng)域中研究的熱點(diǎn),并且到目前為止沒有一種通用的分割算法對各種圖像均能得到滿意的分割結(jié)果。圖像分割的準(zhǔn)則實(shí)質(zhì)是將一幅圖像分成幾幅子圖像,并且滿足3個(gè)條件:
(1)圖像中的每一個(gè)像素必須被歸入某一子圖像,并只能屬于一個(gè)子圖像;
(2)屬于同一子圖像的像素在某種性質(zhì)上是相近的;
(3)屬于不同子圖像的像素在該性質(zhì)上相差很大。所謂性質(zhì)指的是如灰度、灰度梯度、紋理以及空間位置等。因此,圖像分割的過程也就是按性質(zhì)對像素進(jìn)行分類和識(shí)別。
圖像分割[3]方法一般有2類:
(1)基于邊界分割方法,這種方法通過子圖像之間一般都有明顯的邊界。假設(shè)圖像中只有2個(gè)子圖像,子圖像不存在多個(gè)互不連通的區(qū)域;
(2)基于閾值方法,這種方法首先根據(jù)像素的某個(gè)特征確定分割閾值,然后將像素的這個(gè)特征值與此分割閾值相比較,并以此決定將該像素歸入哪一類子圖像。通常將像素的灰度作為特征來選擇閾值。
2.1 VC6.0下OpenCV的安裝及環(huán)境搭配
(1)下載OpenCV安裝程序(1.0版本)。假如要將OpenCV安裝到C:\Program Files\OpenCV。在安裝時(shí)選擇“將\OpenCV\bin加入系統(tǒng)變量”。或安裝完成后手動(dòng)添加環(huán)境變量“C:\Program Files\OpenCV\bin”。
(2)啟動(dòng)VC++ 6.0,菜單Tools?>Options?>Directories:先設(shè)置lib路徑,選擇Library files,在下方填入路徑: C:\Program Files\OpenCV\lib然后選擇include files,在下方填入路徑:
C:\Program Files\OpenCV\cxcore\include
C:\Program Files\OpenCV\cv\include
C:\Program Files\OpenCV\cvaux\include
C:\Program Files\OpenCV\ml\include
C:\Program Files\OpenCV\otherlibs\highgui
C:\Program Files\OpenCV\otherlibs\cvcam\include
(3)每創(chuàng)建一個(gè)將要使用OpenCV的VC Project,都需要給它指定需要的lib。菜單:Project?>Settings,然后將Setting for選為All Configurations,然后選擇右邊的link標(biāo)簽,在Object/library modules附加上:cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.lib如果不需要這么多l(xiāng)ib,你可以只添加你需要的lib。
2.2 利用OpenCV進(jìn)行圖像閾值分割
閾值分割是傳統(tǒng)的圖像分割方法,因其實(shí)現(xiàn)簡單,性能較穩(wěn)定而成為圖像分割中最基本和應(yīng)用最廣泛的分割技術(shù)[4]。它適用于目標(biāo)和背景有不同灰度級范圍的圖像,而且總可以得到封閉且連通區(qū)域的邊界。
2.2.1 閾值分割的概念
閾值分割法是一種基于區(qū)域的圖像分割技術(shù),其基本原理是:通過設(shè)定不同的特征閾值,把圖像象素點(diǎn)分為若干類[5]。通常將像素的灰度作為特征來選擇閾值。首先設(shè)原始圖像為f(x,y),然后按照一定的準(zhǔn)則f(x,y)中找到特征值T,將圖像分割為2個(gè)部分,分割后的圖像為: 若取b0=0(黑),b1=1(白),即為圖像二值化。該方法的特點(diǎn)是可以減少數(shù)據(jù)量,而且簡化了分析和處理步驟,因此該方法是進(jìn)行圖像分析、特征提取與模式識(shí)別之前的必要的圖像預(yù)處理過程。圖像閾值化的目的是要按照灰度級,對像素集合進(jìn)行一個(gè)劃分,使每個(gè)子集形成一個(gè)與現(xiàn)實(shí)景物相對應(yīng)的區(qū)域,各個(gè)區(qū)域內(nèi)部具有一致的屬性,而相鄰區(qū)域具有不同的屬性。這樣的劃分可以通過從灰度級出發(fā)選取一個(gè)或多個(gè)閾值來實(shí)現(xiàn)。
2.2.2 OpenCV實(shí)現(xiàn)閾值分割方法
OpenCV實(shí)現(xiàn)閾值分割方法[6]:
(1)固定閾值分割,在OpenCV中實(shí)現(xiàn)固定閾值分割的函數(shù)是cvThreshold(),函數(shù) cvThreshold()對單通道數(shù)組應(yīng)用固定閾值操作。其基本的思想是,給定一個(gè)數(shù)組和一個(gè)閾值,然后根據(jù)數(shù)組中的每個(gè)元素的是低于還是高于閾值而進(jìn)行一些處理。
(2)自適應(yīng)閾值分割,在OpenCV中實(shí)現(xiàn)自適應(yīng)閾值分割的函數(shù)AdaptiveThreshold(),此函數(shù)有2種不同的自適應(yīng)閾值方法。
2.2.3 基于MFC的OpenCV閾值分割的實(shí)現(xiàn)
OpenCV 庫是使用“IplImage”結(jié)構(gòu)體來創(chuàng)建和處理圖像,在其庫函數(shù)中,最重要的結(jié)構(gòu)體就是IplImage 結(jié)構(gòu),使用這種格式的特點(diǎn)是:可以比DIB 格式表示更多的圖像性質(zhì),而且可以更方便地存取圖像中的像素值[7]。定義該結(jié)構(gòu)體變量時(shí),需要用到函數(shù)cvCreateImage,定義方法如下:
IplImage *src=cvCreateImage(cvSize(800,600),IPL_DEPTH_16U,3);
在VC6.0 中新建MFC AppWizard(exe),添加支持OpenCV 的庫文件,如cxcore.lib cv.libml.lib cvaux.lib highgui.lib cvcam.lib 等,使得VC能夠調(diào)用OpenCV 的庫函數(shù)。
(1)固定閾值算法
OpenCV 中使用固定閾值對圖像進(jìn)行二值化的函數(shù)是cvThreshold(),函數(shù)具體定義為:
Double cvThreshold(
CvArr* src,
CvArr* dst,
double threshold,
double max_value,
int threshold_type);
該函數(shù)的特點(diǎn)是只能處理8位或浮點(diǎn)灰度圖像。目標(biāo)圖像必須與源圖像的類型一致。每個(gè)閾值類型threshold_type對應(yīng)于一個(gè)特定的比較操作如表1所示,該比較操作在源圖像第i個(gè)像素(srci)和閾值(T)之間進(jìn)行。根據(jù)源圖像的像素和閾值之間的關(guān)系,目標(biāo)圖像的像素dsti 會(huì)被設(shè)置為0, srci 或者max_value。當(dāng)threshold_type 被設(shè)置為CV_THRESH_BINARY 時(shí),如果源圖像第i 個(gè)像素(srci)大于閾值T,則目標(biāo)像素dsti 被設(shè)置為最大值max_value。否則目標(biāo)像素dsti 被設(shè)置為0[8]。
表1 cvThreshold()中閾值類型選項(xiàng)和對應(yīng)的操作
以下是本文測試基于MFC的OpenCV高斯模糊算法部分核心代碼:
//定義IplImage 結(jié)構(gòu)體存放高斯模糊后的目標(biāo)圖片
IplImage* pImg8uSmooth= NULL;
IplImage* pImg8u= NULL;
//建立3 通道圖像,圖像大小與輸入圖像的大小相同的IplImage 結(jié)構(gòu)體
pImg8uSmooth = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U, 3);
//使用高斯模糊方法對輸入圖像進(jìn)行濾波
cvSmooth( img, pImg8uSmooth,CV_GAUSSIAN,3,0,0);
//創(chuàng)建窗口,顯示高斯模糊后的圖像
cvvNamedWindow( \"Smooth Image\", 1 );
cvvShowImage( \"Smooth Image\", pImg8uSmooth);
以下是基于MFC 的OpenCV 固定閾值化算法部分核心代碼:
//建立IplImage 結(jié)構(gòu)體存放圖片
IplImage* Thresholdimg=NULL;
//設(shè)定固定閾值為15(該值為參考值,實(shí)際測試程序時(shí),可以根據(jù)具體程序設(shè)置為其他測試值)
double threshold = 15;
//設(shè)定閾值類型為CV_THRESH_BINARY
int threshold_type = CV_THRESH_BINARY;
//對上一步中進(jìn)行過高斯模糊的圖像進(jìn)行固定閾值化處理
cvCvtColor(pImg8uSmooth, Thresholdimg, CV_BGR2GRAY);
//固定閾值化處理
cvThreshold(Thresholdimg,It,threshold,255,threshold_type);
(2)自適應(yīng)閾值算法
針對有很強(qiáng)照明和反射梯度的圖像,圖像中像素分布很不均勻,要想對圖像處理得到效果較好的二值化效果,很難通過某一個(gè)或者某幾個(gè)固定的閾值來實(shí)現(xiàn)。在這種情況下,需要根據(jù)梯度進(jìn)行閾值化,于是便有了自適應(yīng)閾值算法[9]。
自適應(yīng)閾值算法是OpenCV 中的一種改進(jìn)了的閾值化處理技術(shù),使用的閾值本身就是一個(gè)變量,這種方法由函數(shù)cvAdaptiveThreshold()實(shí)現(xiàn),其具體函數(shù)為:
Void cvAdaptiveThreshold(
CvArr* src,
CvArr* dst,
double max_val,
Int adaptive_method=CV_ADAPTIVE_THRESH_MEAN_C,
Int threshold_type=CV_THRESH_BINARY,
Int block_size=3,
Double param1=5);
cvAdaptiveThreshold()有兩種不同的自適應(yīng)閾值方法,可以用參數(shù)adaptive_method進(jìn)行設(shè)置。在這兩種方法下,自適應(yīng)閾值T(x,y)在每個(gè)像素點(diǎn)都不同。通過計(jì)算像素點(diǎn)周圍b×b區(qū)域加權(quán)平均,然后減去常數(shù)得到自適應(yīng)閾值,b由參數(shù)block_size 指定,常參數(shù)由param1 指定。當(dāng)adaptive_method = CV_ADAPTIVE_THRESH_MEAN_C 時(shí),對區(qū)域所有像素平均加權(quán);當(dāng)adaptive_method=CV_ADAPTIVE_THRESH_GAUSSIAN_C時(shí),區(qū)域中的(x,y)周圍像素根據(jù)高斯函數(shù)按照它們離中心的距離進(jìn)行加權(quán)計(jì)算。最后參數(shù)threshold_type和表1中的一樣。
本方法對于有很強(qiáng)照明或反射梯度的圖像,需要根據(jù)梯度進(jìn)行閾值化時(shí),自適應(yīng)閾值技術(shù)與其他技術(shù)相比就有很好的效果。本文是在adaptive_method=CV_ADAPTIVE_THRESH_GAUSSIAN_C時(shí)使用高斯模糊算法對輸入圖像進(jìn)行去噪濾波,之后用cvAdaptiveThreshold ()函數(shù)對高斯濾波之后的圖像進(jìn)行自適應(yīng)閾值化處理。具體核心代碼如下:
//定義IplImage 結(jié)構(gòu)體存放自適應(yīng)閾值化后的目標(biāo)圖片
IplImage* AdpThresholdimg=NULL;
//設(shè)定閾值類型為CV_THRESH_BINARY
int threshold_type = CV_THRESH_BINARY;
//設(shè)定自適應(yīng)閾值方法為CV_ADAPTIVE_THRESH_MEAN_C 方法
int adaptive_method = CV_ADAPTIVE_THRESH_MEAN_C;
int block_size = 71;
//設(shè)置減去的常數(shù)值,以得到自適應(yīng)閾值
double offset = 15;
//建立Iat 指針存放自適應(yīng)閾值化處理后的圖像結(jié)構(gòu)體,作為輸出圖像
Iat = cvCreateImage(cvSize(Igray?>width,Igray?>height),IPL_DEPTH_8U, 1);
// AdpThresholdimg 存放經(jīng)過高斯模糊處理的圖像結(jié)構(gòu)體,作為輸入圖像
AdpThresholdimg=cvCreateImage(cvGetSize(img),IPL_
DEPTH_8U, 1);
//進(jìn)行自適應(yīng)閾值化處理,
cvAdaptiveThreshold(AdpThresholdimg, Iat, 255, adaptive_method,
threshold_type, block_size, offset);
//創(chuàng)建窗口,顯示自適應(yīng)閾值處理后的圖像
cvNamedWindow(\"Adaptive Threshold\",1);
cvShowImage(\"Adaptive Threshold\",Iat);
經(jīng)過上述兩種算法處理的圖像如圖2~圖4所示。
圖2 原始圖
圖3 固定閾值分割
圖4 自適應(yīng)閾值分割
3 結(jié) 語
本文介紹了基于OpenCV 的圖像處理并給出了實(shí)例,利用OpenCV 中的函數(shù)使圖像處理[10]問題變得很簡單,具有很強(qiáng)的實(shí)用價(jià)值,通過圖2和圖3的圖像處理后的效果,發(fā)現(xiàn)自適應(yīng)閾值相較于固定閾值有著較好的特征提取效果。當(dāng)使用固定閾值時(shí),無法分割出圖像中需要的信息,而使用自適應(yīng)閾值,可以有效地分割出圖像中的有用信息。
注:本文通訊作者為汪偉。
參考文獻(xiàn)
[1] 韓思奇,王蕾.圖像分割的閾值法綜述[J].系統(tǒng)工程與電子技術(shù),24(6):91?94.
[2] 陳勝勇,劉盛.基于OpenCV 的計(jì)算機(jī)視覺技術(shù)實(shí)現(xiàn)[M].北京:科學(xué)出版社,2008.
[3] 黃春艷.圖像分割若干算法研究[D].開封:河南大學(xué),2011.
[4] 趙春燕,閏長青,時(shí)秀芳.圖像分割綜述[J].中國科技信息,2009(7):41?43.
[5] 劉爽.圖象分割中閾值選取方法的研究及其算法實(shí)現(xiàn)[J].電腦知識(shí)與技術(shù),2010(11):68?70.
[6] 周強(qiáng).圖像分割算法研究[J].福建電腦,2009(3):27?35.
[7] 高秀娟.圖像分割的理論、方法及應(yīng)用[D].長春:吉林大學(xué),2012.
[8] 劉瑞禎,于仕琪.OpenCV 教程基礎(chǔ)篇[M].北京:北京航空航天大學(xué)出版社,2009.
[9] 蘇彥華.Visual C++數(shù)字圖像識(shí)別技術(shù)典型案例[M].北京:人民郵電出版社,2004.
[10] 楊金龍.圖像分割算法研究與實(shí)現(xiàn)[D].蘭州:西北師范大學(xué),2011.