程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> VC下通過直方圖變換對圖像進行有效增強

VC下通過直方圖變換對圖像進行有效增強

編輯:vc教程

前言

  圖像增強處理技術一直是圖像處理領域一類非常重要的基本圖像處理技術。通過采取適當的增強處理可以使原本模糊不清甚至根本無法分辨的原始圖片處理成清楚、明晰的富含大量有用信息的可使用目標圖像,因此此類圖像處理技術在醫學、遙感、微生物、刑偵以及軍事等諸多科研和應用領域對原始圖像的模式識別、目標檢測等起著重要作用。本文將從空間域的角度對圖像的灰度直方圖增強處理方法做詳細的介紹。

  圖像的灰度直方圖處理技術

  在空域對圖像進行增強處理的方式有許多種,如增強對比度和動態范圍壓縮等等,但這些處理方式都是針對原始圖像的每一個像素直接對其灰度進行處理的,其處理過程主要是通過增強函數對像素的灰度級進行運算並將運算結果作為該像素的新灰度值來實現的。通過改變選用增強函數的解析表達式就可以得到不同的處理效果,這類處理方法比較靈活方便,處理效果也比較不錯,但對於某些灰度分布很密集或對比度很弱的圖像雖然也能起到一定的增強效果但並不明顯。對於這種情況就需要用本文提出的灰度直方圖變換方法將原始圖像密集的灰度分布變的比較疏散,從而拉大了圖像的對比度並在視覺上達到明顯增強的效果,使一些原本不易觀察到的細節能變的清晰可辯。

  圖像的灰度變換處理是通過改變原始圖像各像素在各灰度級上的概率分布來實現的。通過對圖像的灰度值進行統計可以得到一個一維離散的圖像灰度統計直方圖函數p(sk)=nk/n (k=0,1,2,……,L-1)。該式表達了在第k個灰度級上的像素的個數nk占全部像素總數n的比例,p(sk)則給出了對sk出現概率的1個估計。因此該直方圖函數實際是圖像的各灰度級的分布情況的反映,換句話說也就是給出了該幅圖像所有灰度值的整體描述。通過該函數可以清楚地了解到圖像對應的動態范圍情況,可以了解到圖像灰度的主要集中范圍。因此可以通過圖像增強程序的干預來改變直方圖的灰度分布狀況,使灰度均勻的或是按預期目標分布與整個灰度范圍空間,從而達到增強圖像對比度的效果。這種方法是基於數理統計和概率論的,比直接在空域對原始圖像采取對比度增強效果要好的多。在實際應用中直方圖的變換主要有均衡變換和規定變換兩種,而後者又根據灰度級映射規則的不同分單映射規則和組映射規則兩種。

  直方圖均衡化處理

  直方圖均衡化處理的中心思想是把原始圖像的灰度直方圖從比較集中的某個灰度區間變成在全部灰度范圍內的均勻分布。對圖像空域點的增強過程是通過增強函數t=EH(s)來完成的,t、s分別為目標圖像和原始圖像上的像素點(x,y),在進行均衡化處理時對增強函數EH需要滿足兩個條件:增強函數EH(s)在0≤s≤L-1的范圍內是一個單調遞增函數,這個條件保證了在增強處理時沒有打亂原始圖像的灰度排列次序。另一個需要滿足的條件是對於0≤s≤L-1應當有0≤EH(s)≤L-1,它保證了變換過程灰度值的動態范圍的一致。同樣的,對於反變換過程s=EH-1(t),在0≤t≤1時也必須滿足上述兩個條件。累計分布函數(cumulative distribution function,CDF)就是滿足上述條件的一種,通過該函數可以完成s到t 的均勻分布轉換。此時的增強轉換方程為:

tk = EH(sk) = ∑(ni/n) = ∑ps(si) ,(k=0,1,2,……,L-1)

  上述求和區間為0到k,根據該方程可以由源圖像的各像素灰度值直接得到直方圖均衡化後各像素的灰度值。在實際處理變換時,一般先對原始圖像的灰度情況進行統計分析,並計算出原始直方圖分布,然後根據計算出的累計直方圖分布tk按式tk=[(N-1)* tk+0.5]對其取整並得出源灰度sk到tk的灰度映射關系,其中N為灰度的級數。在重復上述步驟得到所有的源圖像各灰度級到目標圖像各灰度級的映射關系後按照新的映射關系對源圖像各點像素進行灰度轉換即可完成對源圖的直方圖均衡化。下面是按照上述算法實現的部分主要程序代碼:

  首先對原始圖像的各像素點的灰度情況進行統計計算。對於24位BMP圖像,圖像陣列是從第54字節起始的,每像素按R、G、B的順序占3個字節。

for(DWord i=54;i<m_dwFileLen;i++)
{
 ns_r[m_cpBuffer[i]]++; //ns_r[k]為k灰度級像素數,m_cpBuffer[i]為當前的灰度值
 i++;
 ns_g[m_cpBuffer[i]]++;//ns_g為G分量的統計記數
 i++;
 ns_b[m_cpBuffer[i]]++;//ns_b為B分量的統計記數
}
for(i=0;i<256;i++) //計算R、G、B三分量的直方圖分布
{
 ps_r[i]=ns_r[i]/((m_dwFileLen-54)/3.0f); //ps_r[i]為R分量中i灰度級出現的概率
 ps_g[i]=ns_g[i]/((m_dwFileLen-54)/3.0f); //ps_b[i]為G分量中i灰度級出現的概率
 ps_b[i]=ns_b[i]/((m_dwFileLen-54)/3.0f); //ps_b[i]為B分量中i灰度級出現的概率
}

  然後計算R、G、B三分量各灰度級的累計直方圖分布,並對其進行取整以得出源和目標圖像灰度之間的映射關系:

for(i=0;i<256;i++)
{
 //計算累計直方圖分布
 temp_r[i]=temp_r[i-1]+ps_r[i];
 temp_g[i]=temp_g[i-1]+ps_g[i];
 temp_b[i]=temp_b[i-1]+ps_b[i];
 //累計分布取整,ns_r[]、ns_g[]、ns_b[]保存有計算出來的灰度映射關系
 ns_r[i]=(int)(255.0f*temp_r[i]+0.5f);
 ns_g[i]=(int)(255.0f*temp_g[i]+0.5f);
 ns_b[i]=(int)(255.0f*temp_b[i]+0.5f);
}

  最後按照計算出來的映射關系把原圖的原始灰度值映射到經過均衡化的新灰度級上,完成最後的處理,下圖就是原圖像和用本程序得出的經過直方圖均衡化處理的目標圖像,從實驗結果可以看出原始圖像太暗根本看不清細節,而處理過的圖像則非常清晰:

for(i=54;i<m_dwFileLen;i++)
{
 m_cpBuffer[i]=ns_r[m_cpBuffer[i]]; //對R分量進行灰度映射(均衡化)
 i++;
 m_cpBuffer[i]=ns_g[m_cpBuffer[i]]; //對G分量進行灰度映射(均衡化)
 i++;
 m_cpBuffer[i]=ns_b[m_cpBuffer[i]]; //對B分量進行灰度映射(均衡化)

 采取單映射規則的直方圖規定化處理

  前面介紹的直方圖均衡化處理方法從實驗效果看還是很不錯的,從實現算法上也可以看出其優點主要在於能自動增強整幅圖像的對比度,但具體的增強效果也因此不易控制,只能得到全局均衡化處理的直方圖。而在科研和工程應用中往往根據不同的需要而希望得到特定形狀的直方圖分布以有選擇的對某灰度范圍進行局部的對比度增強。象這種情況可以采取對直方圖的規定化處理,通過選擇合適的規定化函數可以取得期望的效果。對於灰度級數分別為M和N(滿足M≥N)的原始圖和規定圖,一般仍先按均衡化對原始圖進行處理:

tk = EHs(si) = ∑ps(si) ,(k=0,1,2,……,M-1)

  然後規定需要的直方圖,並計算出能使規定的直方圖均衡化的變換:

vl = EHu(uj) = ∑pu(ui) ,(l=0,1,2,……,N-1)

  最後將第一步得到的變換反轉過去,即把原始直方圖對應映射到規定的直方圖,也就是把所有的ps(si)映射到pu(uj)中去。由於映射是在離散空間進行的,而且在取整時不可避免會引入誤差,因此采取何種對應規則是一個很重要的問題。比較常用的一種方法是Gonzalez在1987年提出的單映射規則(single mapping law,SML):首先尋找能滿足 |∑ps(si) - ∑pu(uj)| 最小的k和l(ps()和pu()的求和上限),然後把ps(si)映射到pu(uj)中去。

  本文針對原始圖像比較暗的特點,采取如下的規定直方圖,以使高亮度像素能得到充分的加強:

float a=1.0f/(32.0f*63.0f); //64個灰度級,a為步長
for(int i=0;i<64;i++)
{
 nu[i]=i*4;
 pu[i]=a*i;
}

  接下來的對原始圖和規定直方圖計算累計直方圖同前面

[1] [2] 下一頁

  1. 上一頁:
  2. 下一頁:
欄目導航
Copyright © 程式師世界 All Rights Reserved