The ACE algorithm is derived from the Retinex algorithm, which can adjust the contrast of the image, realize the color constancy and luminance constancy of the human eye, and use the difference to calculate the relative shading between the target point and the surrounding pixels to correct the final pixel value, which has a good enhancement effect. But the computational complexity is very high, this paper proposes an effective fast implementation method.
For the convenience of narration, this assumes that the following images are normalized to a floating-point image between [0,1].
The ACE algorithm is calculated as:
Y =∑ (g (I (x0)-I (x)) W (x0,x))/∑ (W (x0,x)) x belongs to I (1)
where w is the weight parameter, the farther from the center pixel the lower the W value, the Euclidean distance can be directly evaluated. G () is a relative contrast adjustment parameter, non-linear, simply take the following calculation method:
G (x) = max (min (Ax, 1.0),-1.0) (2)
Here A is the control parameter, the higher the value, the more obvious the detail enhancement. Once the calculation is finished, the final enhanced image can be obtained once the y is normalized.
Ace's enhancement effect is generally good with Retinex. It is important to note that the current pixel in the ACE is compared with the other pixels of the entire image, the computational complexity is very high, which is the most important reason to limit its application, this article is based on two assumptions: (1) A pair of image ace enhanced to obtain the output y, if Y and then an ace enhancement, The output is still y itself, and (2) the Ace enhancement results for a pair of images are scaled by the size of Y, the Aces are enhanced for Y, and the output is still y itself. These two assumptions I can not confirm, hehe, even if the imaginary bar.
If the above hypothesis is established, we can zoom the image to get I1, the I1 of the Ace enhancement results scaling (as I size) to get Y1, then Y and Y1 is very close, we only need to further processing on the basis of Y1. Here's another two details question: 1) How to quickly find I1 Ace enhancement results? In fact, it is very simple, it is again scaled to get I2, to seek I2 enhancement results, and so on, is the pyramid structure thought. 2) How to further process the Y1 based on y? Because it is a differential comparison operation in the whole image domain, and the comparison of the nearest neighborhood pixels constitutes the details of Y, and the comparison of the distance pixels constitutes the global background information of Y, then we reasonably assume that the global background information of Y and Y1 is the same, only update the details, that is, We need to add the difference result of the adjacent pixels in I to the Y1 base and subtract the difference result of the neighboring pixels in the Y1 as the final output Y.
It's a little bit around, take a slow look.
Here is the Python code
Import Cv2import numpy as Npimport mathdef stretchimage (data, s=0.005, bins =): #线性拉伸, remove the maximum minimum 0.5% pixel value and then stretch linearly to [0,1] HT = Np.histogram (data, bins); D = np.cumsum (Ht[0])/float (data.size) lmin = 0; Lmax=bins-1 while Lmin<bins: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_pa RA = {}def Getpara (radius = 5): #根据半径计算权重参数矩阵 global G_para m = g_para.get (radius, None) I F 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, Radi US+W] = 1.0/math.sqrt (h**2+w**2) m/= m.sum () G_para[radius] = m return mdef 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]*radi US 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 resdef 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 is the contrast enhancement factor, radius is the convolution template radius res = Np.zeros (i.shape) for K in range (3): Res[:,:,k] = StretchImage (zmicefast(I[:,:,k], ratio, radius)) return resif __name__ = = ' __main__ ': M = Zmicecolor (Cv2.imread (' p4.bmp ')/255.0) *255 cv2.imwrite (' zmice.jpg ', m)
Here is the result of the experiment, above is the original, and below is the enhancement result.
Automatic color equalization (ACE) fast algorithm