程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 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個字節。

or(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三分量各灰度級的累計直方圖分布,並對其進行取整以得出源和目標圖像灰度之間的映射關系:

or(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);
}

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

or(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分量進行灰度映射(均衡化)
}

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