影象增強(一)ACE增強
在影象增強方向上,傳統存在兩種方法一種是:Adaptive Contrast Enhancement,即自適應對比度增強,還有一種是AHE(Adaptive histgram equalization)。
AHE
是透過對區域性區域執行響應的直方圖變換,對於那些畫素值分佈比較均勻的影象來說畫素很好,然後,如果影象中包括明顯比其他區域陰暗或者亮的部分,在這些部分的對比度就得不到有效增強。
AHE的屬性:
領域的大小是該方法的一個引數。領域小,對比度得到增強,領域大,則對比度降低。
當某個領域包含的畫素值非常相似,其直方圖就會尖狀化,此時直方圖的變換會將一個很窄範圍內的畫素對映到整個畫素範圍。這些使得某些平坦區域的少量噪音經AHE處理後會放大。
還有一個
CLAHE
(Contrast Limited Adaptive Histgram equalization)
結果:
上述部分參考:
這裡推薦下他的cnblogs,很強的大佬%%%:
ACE
演算法源自retinex演算法,可以調整影象的對比度,實現人眼色彩的恆常性好和亮度恆常性。透過差分計算目標點與周圍畫素點的相對陰暗關係來矯正最終畫素值,有很好的增強效果,但是計算複雜讀非常高,本文提出一種有效一種非常有效的快速實現方法。
這個方法在開源軟體GIMP已經嵌入了。
假定:x(i,j)是影象中某點的灰度值,區域性區域的定義為:以(i,j)為中心,視窗大小為(2n+1)*(2n+1)的區域,其中n為一整數。區域性的平均值,也就是低頻部分,可以用下式計算:
而區域性方差為:
上述式子中
就是所謂的區域性標準差(LSD)。定義f(i,j)表示x(i,j)對應的增強後的畫素值。則ACE演算法可以表示如下:
其中G(i,j)就是上文所講的CG,一般情況下CG總是大於1的,這樣高頻成分[x(i,j)-m(i,j)]就能得到增強。
還有一種增強方式:
增強影象 = 模糊影象 + Amount *(原始影象 - 模糊影象)。
這裡的模糊影象可以用高斯模糊,也可以採用雙邊濾波器來處理,用雙邊濾波器效果要好。
python程式碼:
import cv2
import numpy as np
import math
def stretchImage(data, s=0。005, bins = 2000): #線性拉伸,去掉最大最小0。5%的畫素值,然後線性拉伸至[0,1]
ht = np。histogram(data, bins);
d = np。cumsum(ht[0])/float(data。size)
lmin = 0; lmax=bins-1
while lmin if d[lmin]>=s: break lmin+=1 while lmax>=0: if d[lmax]<=1-s: break lmax-=1 return np。clip((data-ht[1][lmin])/(ht[1][lmax]-ht[1][lmin]), 0,1) g_para = {} def getPara(radius = 5): #根據半徑計算權重引數矩陣 global g_para m = g_para。get(radius, None) if m is not None: return m size = radius*2+1 m = np。zeros((size, size)) for h in range(-radius, radius+1): for w in range(-radius, radius+1): if h==0 and w==0: continue m[radius+h, radius+w] = 1。0/math。sqrt(h**2+w**2) m /= m。sum() g_para[radius] = m return m def zmIce(I, ratio=4, radius=300): #常規的ACE實現 para = getPara(radius) height,width = I。shape zh,zw = [0]*radius + range(height) + [height-1]*radius, [0]*radius + range(width) + [width -1]*radius Z = I[np。ix_(zh, zw)] res = np。zeros(I。shape) for h in range(radius*2+1): for w in range(radius*2+1): if para[h][w] == 0: continue res += (para[h][w] * np。clip((I-Z[h:h+height, w:w+width])*ratio, -1, 1)) return res def zmIceFast(I, ratio, radius): #單通道ACE快速增強實現 height, width = I。shape[:2] if min(height, width) <=2: return np。zeros(I。shape)+0。5 Rs = cv2。resize(I, ((width+1)/2, (height+1)/2)) Rf = zmIceFast(Rs, ratio, radius) #遞迴呼叫 Rf = cv2。resize(Rf, (width, height)) Rs = cv2。resize(Rs, (width, height)) return Rf+zmIce(I,ratio, radius)-zmIce(Rs,ratio,radius) def zmIceColor(I, ratio=4, radius=3): #rgb三通道分別增強,ratio是對比度增強因子,radius是卷積模板半徑 res = np。zeros(I。shape) for k in range(3): res[:,:,k] = stretchImage(zmIceFast(I[:,:,k], ratio, radius)) return res if __name__ == ‘__main__’: m = zmIceColor(cv2。imread(‘p4。bmp’)/255。0)*255 cv2。imwrite(‘zmIce。jpg’, m) C++版本程式碼: //ace 自適應對比度均衡研究 //by jsxyhelu //感謝 imageshop #include “stdafx。h” #include #include “opencv2/core/core。hpp” #include “opencv2/highgui/highgui。hpp” #include “opencv2/imgproc/imgproc。hpp” using namespace std ; using namespace cv ; //點乘法 elementWiseMultiplication cv :: Mat EWM ( cv :: Mat m1 , cv :: Mat m2 ){ Mat dst = m1 。 mul ( m2 ); return dst ; } //影象區域性對比度增強演算法 cv :: Mat ACE ( cv :: Mat src , int C = 4 , int n = 20 , int MaxCG = 5 ){ Mat meanMask ; Mat varMask ; Mat meanGlobal ; Mat varGlobal ; Mat dst ; Mat tmp ; Mat tmp2 ; blur ( src 。 clone (), meanMask , Size ( 50 , 50 )); //meanMask為區域性均值 tmp = src - meanMask ; varMask = EWM ( tmp , tmp ); blur ( varMask , varMask , Size ( 50 , 50 )); //varMask為區域性方差 //換算成區域性標準差 varMask 。 convertTo ( varMask , CV_32F ); for ( int i = 0 ; i < varMask 。 rows ; i ++ ){ for ( int j = 0 ; j < varMask 。 cols ; j ++ ){ varMask 。 at < float > ( i , j ) = ( float ) sqrt ( varMask 。 at < float > ( i , j )); } } meanStdDev ( src , meanGlobal , varGlobal ); //meanGlobal為全域性均值 varGlobal為全域性標準差 tmp2 = varGlobal / varMask ; for ( int i = 0 ; i < tmp2 。 rows ; i ++ ){ for ( int j = 0 ; j < tmp2 。 cols ; j ++ ){ if ( tmp2 。 at < float > ( i , j ) > MaxCG ){ tmp2 。 at < float > ( i , j ) = MaxCG ; } } } tmp2 。 convertTo ( tmp2 , CV_8U ); tmp2 = EWM ( tmp2 , tmp ); dst = meanMask + tmp2 ; imshow ( “D方法” , dst ); dst = meanMask + C * tmp ; imshow ( “C方法” , dst ); return dst ; } void main () { Mat src = imread ( “plant。bmp” , 0 ); imshow ( “src” , src ); ACE ( src ); waitKey (); } 參考文獻: 由Photoshop高反差保留演算法原理聯想到的一些影象增強演算法。 - Imageshop - 部落格園