一、圖像增強算法原理
圖像增強算法常見於對圖像的亮度、對比度、飽和度、色調等進行調節,增加其清晰度,減少噪點等。圖像增強往往經過多個算法的組合,完成上述功能,比如圖像去燥等同於低通濾波器,增加清晰度則為高通濾波器,當然增強一副圖像是為最后獲取圖像有用信息服務為主。一般的算法流程可為:圖像去燥、增加清晰度(對比度)、灰度化或者獲取圖像邊緣特征或者對圖像進行卷積、二值化等,上述四個步驟往往可以通過不同的步驟進行實現,后續將針對此方面內容進行專題實驗,列舉其應用場景和處理特點。
本文章是一篇綜合性文章,算是一篇拋磚引玉的文章,有均衡化、提高對比度、降低對比度的算法。
1.1 基於直方圖均衡化的圖像增強
圖像對比度增強的方法可以分為兩種:直接對比度增強方法,間接對比度增強方法。直方圖拉伸和直方圖均衡化是常見的間接對比度增強方法。直方圖拉伸是利用對比度拉伸對直方圖進行調整,擴大前景和背景灰度的差別,這種方法可以通過線性和非線性的方法來實現,其中ps中就是利用此方法提高對比度;直方圖均衡化則是利用累積函數對灰度值進行調整,實現對比度的增強。
直方圖均衡化處理原理:將原始圖像的灰度圖從比較集中的某個灰度區間均勻分布在整個灰度空間中,實現對圖像的非線性拉伸,重新分配圖像像素值。
算法應用場景:
1、算法的本質是重新分布圖像的像素值,增加了許多局部的對比度,整體的對比度沒有進行太大改變,所以應用圖像為圖像有用數據的對比度相近是,例如:X光圖像,可以將曝光過度或曝光不足照片進行更好的顯示,或者是背景及前景太亮或太暗的圖像非常有用。
2、算法當然也有缺點,具體表現為:變換后的圖像灰度級減少,某些細節減少;某些圖像有高峰值,則處理后對比度不自然的過分增強。
算法實現特點:
1、均衡化過程:直方圖均衡化保證在圖像像素映射過程中原來的大小關系保持不變,即較亮的區域依舊較亮,較暗的依舊較暗,只是對比度增加,不能明暗顛倒;保證像素映射函數的值域在0和255之間。累積分布函數是單增長函數,並且值域是0到1。
2、累積分布函數實現過程:
比較概率分布函數和累積分布函數,前者的二維圖像是參差不齊的,后者是單調遞增的。直方圖均衡化過程中,映射方法是
其中,n是圖像中像素的總和,是當前灰度級的像素個數,L是圖像中可能的灰度級總數。
來看看通過上述公式怎樣實現的拉伸。假設有如下圖像:
得圖像的統計信息如下圖所示,並根據統計信息完成灰度值映射:
映射后的圖像如下所示:
算法偽代碼:
1、計算原始灰度圖像的像素概率分布
2、根據像素概率分布獲取圖像累積分布函數
3、根據映射函數獲取變換后的圖像
算法matlab代碼:
%直方圖均衡化 I = imread('rice.png'); [height,width] = size(I); figure subplot(221) imshow(I)%顯示原始圖像 subplot(222) imhist(I)%顯示原始圖像直方圖 %進行像素灰度統計; NumPixel = zeros(1,256);%統計各灰度數目,共256個灰度級 for i = 1:height for j = 1: width NumPixel(I(i,j) + 1) = NumPixel(I(i,j) + 1) + 1;%對應灰度值像素點數量增加一 end end %計算灰度分布密度 ProbPixel = zeros(1,256); for i = 1:256 ProbPixel(i) = NumPixel(i) / (height * width * 1.0); end %計算累計直方圖分布 CumuPixel = zeros(1,256); for i = 1:256 if i == 1 CumuPixel(i) = ProbPixel(i); else CumuPixel(i) = CumuPixel(i - 1) + ProbPixel(i); end end %累計分布取整 CumuPixel = uint8(255 .* CumuPixel + 0.5); %對灰度值進行映射(均衡化) for i = 1:height for j = 1: width I(i,j) = CumuPixel(I(i,j)); end end subplot(223) imshow(I)%顯示原始圖像 subplot(224) imhist(I)%顯示原始圖像直方圖
1.2 基於拉普拉斯算子的圖像增強
利用拉普拉斯算子進行圖像增強本質是利用圖像的二次微分對圖像進行蛻化,在圖像領域中微分是銳化,積分是模糊,利用二次微分對圖像進行蛻化即利用鄰域像素提高對比度。在opencv中也有拉普拉斯函數,但那時生成了灰度圖像,更多的求取邊緣,具體源碼還沒研究,其中原理可以參考我前一篇文章,針對拉普拉斯有個詳細的介紹。
本次實驗應用的卷積核為:
1.3 基於對象Log變換的圖像增強
對數變換可以將圖像的低灰度值部分擴展,顯示出低灰度部分更多的細節,將其高灰度值部分壓縮,減少高灰度值部分的細節,從而達到強調圖像低灰度部分的目的。變換方法:
對數變換對圖像低灰度部分細節增強的功能過可以從對數圖上直觀理解:
x軸的0.4大約對應了y軸的0.8,即原圖上0~0.4的低灰度部分經過對數運算后擴展到0~0.8的部分,而整個0.4~1的高灰度部分被投影到只有0.8~1的區間,這樣就達到了擴展和增強低灰度部分,壓縮高灰度部分的值的功能。
從上圖還可以看到,對於不同的底數,底數越大,對低灰度部分的擴展就越強,對高灰度部分的壓縮也就越強。
1.4 基於伽馬變換的圖像增強
伽馬變換主要用於圖像的校正,將灰度過高或者灰度過低的圖片進行修正,增強對比度。變換公式就是對原圖像上每一個像素值做乘積運算:
伽馬變換對圖像的修正作用其實就是通過增強低灰度或高灰度的細節實現的,從伽馬曲線可以直觀理解:
γ值以1為分界,值越小,對圖像低灰度部分的擴展作用就越強,值越大,對圖像高灰度部分的擴展作用就越強,通過不同的γ值,就可以達到增強低灰度或高灰度部分細節的作用。
伽馬變換對於圖像對比度偏低,並且整體亮度值偏高(對於於相機過曝)情況下的圖像增強效果明顯。
二、測試代碼
根據上述講解,本文利用python進行編程實驗,代碼如下:
def preprocess(filename, i): image = cv2.imread(filename) image_gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY) # 直方圖均衡增強 image_equal = cv2.equalizeHist(image_gray) r,g,b = cv2.split(image) r1 = cv2.equalizeHist(r) g1 = cv2.equalizeHist(g) b1 = cv2.equalizeHist(b) image_equal_clo = cv2.merge([r1, g1, b1]) # 拉普拉斯算法增強 kernel = np.array([ [0, -1, 0], [-1, 5, -1], [0, -1, 0] ]) image_lap = cv2.filter2D(image,cv2.CV_8UC3 , kernel) # 對象算法增強 image_log = np.uint8(np.log(np.array(image) +1)) cv2.normalize(image_log, image_log,0,255,cv2.NORM_MINMAX) # 轉換成8bit圖像顯示 cv2.convertScaleAbs(image_log,image_log) # 伽馬變換 fgamma = 2 image_gamma = np.uint8(np.power((np.array(image)/255.0),fgamma)*255.0) cv2.normalize(image_gamma, image_gamma, 0, 255, cv2.NORM_MINMAX) cv2.convertScaleAbs(image_gamma, image_gamma)
三、實驗結果及分析
(laplus) (gamma)
(src) (log)
(laplus) (gamma)
(equal)
實驗結果分析為:
1、log函數變化對圖像增強來講,更多是對圖像的對比度有所減弱,畢竟函數表現形式為像素值小的變大點,像素值大的變小點,所以對比度減小,亮度增加,正如圖像所顯示。所以目前看來log函數還是慎用,如果提高函數可以利用分段函數啊。
2、gamma函數圖像增強,這個函數原理可以看出,當r大於1時,可以當做指數函數,小於則為log函數。在試驗中我們常用r>1,實現圖像對比度增強。從圖像中可以看出,黑色更黑,白色更白。
3、laplus函數圖像增強,本質是微分,所以為圖像銳化,在圖像銳化是明顯凸顯圖像的細節,進而直觀上提高圖像對比度。
4、equal函數本質是重新分布圖像的像素值,直觀我們發現圖像顏色發生變化,但對比度是有所提高,當然對於這組的圖像的作用,沒有體現。
總結:圖像增強方法不同,應用領域不同,更好的應用需要掌握靈活多變的方法。
四、參考文章
1、OpenCV圖像增強算法實現(直方圖均衡化、拉普拉斯、Log、Gamma):本文基本在此基礎上進行編程實現,原理可以參考這,同時自己對里面的概念問題進行詳解。
2、直方圖均衡化原理:本文詳細介紹了直方圖均衡化的原理,並通過opencv進行函數實現。
3、直方圖均衡化詳解及編程實現:文中對直方圖均衡化的應用特點和缺點進行分析,並根據算法原理通過matlab實現了算法。