一、灰度世界算法
① 算法原理
灰度世界算法以灰度世界假設為基礎,該假設認為:對於一幅有着大量色彩變化的圖像,R,G,B三個分量的平均值趨於同一灰度值Gray。從物理意義上講,灰色世界法假設自然界景物對於光線的平均反射的均值在總體上是個定值,這個定值近似地為“灰色”。顏色平衡算法將這一假設強制應用於待處理圖像,可以從圖像中消除環境光的影響,獲得原始場景圖像。
一般有兩種方法確定Gray值
1) 使用固定值,對於8位的圖像(0~255)通常取128作為灰度值
2) 計算增益系數,分別計算三通道的平均值avgR,avgG,avgB,則:
Avg=(avgR+avgG+avgB)/3
kr=Avg/avgR , kg=Avg/avgG , kb=Avg/avgB
利用計算出的增益系數,重新計算每個像素值,構成新的圖片
② 算法優缺點
這種算法簡單快速,但是當圖像場景顏色並不豐富時,尤其出現大塊單色物體時,該算法常會失效。
③ 算法展示
1 def grey_world(nimg): 2 nimg = nimg.transpose(2, 0, 1).astype(np.uint32) 3 avgB = np.average(nimg[0]) 4 avgG = np.average(nimg[1]) 5 avgR = np.average(nimg[2]) 6 7 avg = (avgB + avgG + avgR) / 3 8 9 nimg[0] = np.minimum(nimg[0] * (avg / avgB), 255) 10 nimg[1] = np.minimum(nimg[1] * (avg / avgG), 255) 11 nimg[2] = np.minimum(nimg[2] * (avg / avgR), 255) 12 return nimg.transpose(1, 2, 0).astype(np.uint8)
① 效果圖對比
第一組圖片場景顏色豐富,利用灰度世界假設法校正效果明顯;第二組圖片中顏色相對單一,校正效果也不是很理想;這也就導致了‘灰度世界假設算法’無法通用.
二、直方圖均衡化
① 算法原理
直方圖均衡化的基本思想是把原始圖的直方圖變換為均勻分布的形式,這樣就增加了象素灰度值的動態范圍從而可達到增強圖像整體對比度的效果
假設,一張圖像的直方圖如下圖(左)所示,均衡化后,圖像直方圖如下圖(右)顯示
② 算法優缺點
直方圖均衡化,一般可用於灰度圖像的對比增強(如:人臉陰影部位增強);
如果直接對彩色圖像R,G,B三通道分別均衡化后再合並,極容易出現顏色不均、失真等問題,所以,一般會將RGB圖像轉換到YCrCb空間,對Y通道進行均衡化(Y通道代表亮度成分)
③ 算法展示
在python中opencv3提供了能將灰度圖直接均衡化的方法:equalizeHist(img),借助這個方法,可以實現彩色圖像的均衡化
1 def hisEqulColor(img): 2 ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB) 3 channels = cv2.split(ycrcb) 4 cv2.equalizeHist(channels[0], channels[0]) #equalizeHist(in,out) 5 cv2.merge(channels, ycrcb) 6 img_eq=cv2.cvtColor(ycrcb, cv2.COLOR_YCR_CB2BGR) 7 return img_eq
④ 效果圖對比
第一組、第二組彩色圖像中均衡化后圖片對比原圖更清晰,細節突出;第三組灰度圖,均衡化在光照不均調節明暗的功能上,效果更明顯
三、視網膜-大腦皮層(Retinex)增強算法
① 算法原理
視網膜-大腦皮層(Retinex)理論認為世界是無色的,人眼看到的世界是光與物質相互作用的結果,也就是說,映射到人眼中的圖像和光的長波(R)、中波(G)、短波(B)以及物體的反射性質有關
其中I是人眼中看到的圖像,R是物體的反射分量,L是環境光照射分量,(x, y)是二維圖像對應的位置
它通過估算L來計算R,具體來說,L可以通過高斯模糊和I做卷積運算求得,用公式表示為:
其中F是高斯模糊的濾波器,“ * ”表示卷積運算
其中σ稱為高斯周圍空間常數(Gaussian Surround Space Constant),也就是算法中所謂的尺度,對圖像處理有比較大的影響,對於二維圖像,等於對應位置即:
即:一般認為光照分量是原圖像經過高斯濾波后的結果
② 算法優缺點
Retinex算法,從SSR(單尺度Retinex)到MSR(多尺度Retinex)以及到最常用的MSRCR(帶顏色恢復的多尺度Retinex);其中色彩恢復主要目的是來調節由於圖像局部區域對比度增強而導致顏色失真的缺陷.
先看一組公式:
RMSRCR(x,y)'=G⋅RMSRCR(x,y)+b
RMSRCR (x,y)=C(x,y)RMSR(x,y)
C(x,y)=f[I'(x,y)]=f[I(x,y)/∑I(x,y)]Ci(x,y)=f[Ii′(x,y)]=f[Ii(x,y)∑j=1NIj(x,y)]
f[I'(x,y)]=βlog[αI'(x,y)]=β{log[αI'(x,y)]−log[∑I(x,y)]}
如果是灰度圖像,只需要計算一次即可,如果是彩色圖像,如RGB三通道,則每個通道均需要如上進行計算
G表示增益Gain(一般取值:5)
b表示偏差Offset(一般取值:25)
I (x, y)表示某個通道的圖像
C表示某個通道的彩色回復因子,用來調節3個通道顏色的比例;
f(·)表示顏色空間的映射函數;
β是增益常數(一般取值:46);
α是受控制的非線性強度(一般取值:125)
MSRCR算法利用彩色恢復因子C,調節原始圖像中3個顏色通道之間的比例關系,從而把相對較暗區域的信息凸顯出來,達到了消除圖像色彩失真的缺陷。 處理后的圖像局部對比度提高,亮度與真實場景相似,在人們視覺感知下,圖像顯得更加逼真;但是MSRCR算法處理圖像后,像素值一般會出現負值。所以從對數域r(x, y)轉換為實數域R(x, y)后,需要通過改變增益Gain,偏差Offset對圖像進行修正
關於Retinex算法更多的細節,可以查看https://www.cnblogs.com/wangyong/p/8665434.html
③ 算法展示
④ 效果圖對比
(原圖) (SSR)
(MSR) (MSRCR)
(原圖) (SSR)
(MSR) (MSRCR)
上面的兩組圖片,可以看到第一組的效果明顯,第二組的效果很差;同時可和‘灰度世界算法’的結果進行比較;一般認為,Retinex算法比較適合航空圖片的處理,‘去霧’效果顯著。
四、自動白平衡(AWB)
① 算法原理
用一個簡單的概念來解釋什么是白平衡:假設,圖像中R、G、B最高灰度值對應於圖像中的白點,最低灰度值的對應於圖像中最暗的點;其余像素點利用(ax+b)映射函數把彩色圖像中R、G、B三個通道內的像素灰度值映射到[0.255]的范圍內.
白平衡的本質是讓白色的物體在任何顏色的光源下都顯示為白色,這一點對人眼來說很容易辦到,因為人眼有自適應的能力,只要光源的色彩不超出一定的限度,就可以自動還原白色。但相機就不同了,無論是圖像傳感器還是膠卷都會記錄光源的顏色,白色的物體就會帶上光源的顏色,白平衡所要做的就是把這個偏色去掉。
② 算法優缺點
自動白平衡是一個很復雜的問題,目前還沒有一個萬能的方法可以解決所有場景的白平衡問題
截止2017年,出現不少利用神經網絡實現自動白平衡的算法,也會有專門的文檔對這部分進行詳細的介紹。
③ 算法展示
利用Lab顏色空間,對圖片進行自動白平衡操作.
③ 效果圖對比
可以看出,這兩組效果圖和‘灰度世界假設’算法得出的效果圖很類似,主要是因為上述的白平衡算法也是基於‘灰度世界’這個假設下的
五、自動色彩均衡(ACE)
① 算法原理
ACE算法源自retinex算法,可以調整圖像的對比度,實現人眼色彩恆常性和亮度恆常性,該算法考慮了圖像中顏色和亮度的空間位置關系,進行局部特性的自適應濾波,實現具有局部和非線性特征的圖像亮度與色彩調整和對比度調整,同時滿足灰色世界理論假設和白色斑點假設。
第一步:對圖像進行色彩/空域調整,完成圖像的色差校正,得到空域重構圖像;
式中,Rc 是中間結果,Ic(p)-Ic(j)為兩個不同點的亮度差,d(p,j)表示距離度量函數,r(*)為亮度表現函數,需是奇函數;這一步可以適應局部圖像對比度,r(*)能夠放大較小的差異,並豐富大的差異,根據局部內容擴展或者壓縮動態范圍。一般得,r(*)為:
第二步:對校正后的圖像進行動態擴展。ACE算法是對單一色道進行的,對於彩色圖片需要對每一個色道分別處理
其中存在一種簡單的線性擴展:
R(x)=round[127.5+w*Rc(p)],其中,w表示線段[(0,mc),(255,Mc)]的斜率,且有:
Mc=min[Rc(p)],Mc=max[Rc(p)]
第三步:利用下面的公式將R(x)展到[0,1]之間,得到增強后的通道
②算法優缺點
ACE的增強效果普遍比retinex好。需要注意的是,ACE中當前像素是與整個圖像的其他像素做差分比較,計算復雜度非常非常高,這也是限制它應用的最主要原因。
所以,一般算法中,會通過指定采樣數來代替與整副圖像的像素點信息進行差分計算,減少運算量,提高效率。
③ 算法展示
1 #飽和函數 2 def calc_saturation(diff,slope,limit): 3 ret = diff * slope 4 if ret > limit: 5 ret = limit 6 elif (ret < (-limit)): 7 ret = -limit 8 return ret 9 10 def automatic_color_equalization(nimg, slope=10, limit=1000, samples=500): 11 12 nimg = nimg.transpose(2, 0, 1) 13 14 #Convert input to an ndarray with column-major memory order(僅僅是地址連續,內容和結構不變) 15 nimg = np.ascontiguousarray(nimg, dtype=np.uint8) 16 17 width=nimg.shape[2] 18 height=nimg.shape[1] 19 20 cary=[] 21 22 #隨機產生索引 23 for i in range(0,samples): 24 _x=random.randint(0,width)%width 25 _y=random.randint(0,height)%height 26 27 dict={"x":_x,"y":_y} 28 cary.append(dict) 29 30 31 mat=np.zeros((3,height,width),float) 32 33 r_max = sys.float_info.min 34 r_min = sys.float_info.max 35 36 g_max = sys.float_info.min 37 g_min = sys.float_info.max 38 39 b_max = sys.float_info.min 40 b_min = sys.float_info.max 41 42 for i in range(height): 43 for j in range(width): 44 r=nimg[0,i,j] 45 g=nimg[1,i,j] 46 b=nimg[2,i,j] 47 48 r_rscore_sum = 0.0 49 g_rscore_sum = 0.0 50 b_rscore_sum = 0.0 51 denominator = 0.0 52 53 for _dict in cary: 54 _x=_dict["x"] #width 55 _y=_dict["y"] #height 56 57 #計算歐氏距離 58 dist=np.sqrt(np.square(_x-j)+np.square(_y-i)) 59 if (dist < height / 5): 60 continue; 61 62 _sr=nimg[0,_y,_x] 63 _sg=nimg[1,_y,_x] 64 _sb=nimg[2,_y,_x] 65 66 r_rscore_sum +=calc_saturation(int(r) - int(_sr),slope,limit) / dist 67 g_rscore_sum +=calc_saturation(int(g) - int(_sg),slope,limit) / dist 68 b_rscore_sum +=calc_saturation(int(b) - int(_sb),slope,limit) / dist 69 70 denominator += limit / dist 71 72 r_rscore_sum = r_rscore_sum / denominator 73 g_rscore_sum = g_rscore_sum / denominator 74 b_rscore_sum = b_rscore_sum / denominator 75 76 mat[0,i,j]=r_rscore_sum 77 mat[1,i,j]=g_rscore_sum 78 mat[2,i,j]=b_rscore_sum 79 80 if r_max<r_rscore_sum: 81 r_max=r_rscore_sum 82 if r_min>r_rscore_sum: 83 r_min=r_rscore_sum 84 85 if g_max<g_rscore_sum: 86 g_max=g_rscore_sum 87 if g_min>g_rscore_sum: 88 g_min=g_rscore_sum 89 90 if b_max<b_rscore_sum: 91 b_max=b_rscore_sum 92 if b_min>b_rscore_sum: 93 b_min=b_rscore_sum 94 95 for i in range(height): 96 for j in range(width): 97 nimg[0, i, j] = (mat[0, i, j] - r_min) * 255 / (r_max - r_min) 98 nimg[1, i, j] = (mat[1, i, j] - g_min) * 255 / (g_max - g_min) 99 nimg[2, i, j] = (mat[2, i, j] - b_min) * 255 / (b_max - b_min) 100 101 return nimg.transpose(1, 2, 0).astype(np.uint8)
④ 效果圖對比
總結:查看各種傳統算法的效果圖,ACE自動色彩均衡算法具有比較好的普遍性和效果,當然,對於一些圖片ACE也不能得到很好地效果,所以,這就需要我們不斷的去深入研究和學習,接下來會學習神經網絡在色彩恆常性方面的應用並進行效果對比。
作為一枚技術小白,寫這篇筆記的時候參考了很多博客論文,在這里表示感謝,同時,轉載請注明出處......