Opencv——Gmma矯正原理及實現

公式:在這裏插入圖片描述
A是常數,
指數爲Gamma。

Gamma校正:

出現Gamma矯正根本原因是gamma校正存在的本質原因是:是受限於有限存儲空間及渲染帶寬,需要在整個圖像的流轉各級轉換中儘可能保留暗部細節,以滿足人眼對暗部敏感的需求。人最終看到顯示器顯示圖像和最初從自然界捕獲的圖像大體是無差別的,只是暗部細節損失少,亮部細節損失多罷了。
Gamma矯正的目的是爲了讓顯示屏顯示的數據和自然界中一樣。同時儘可能的保存暗部細節。
Gamma校正是一種重要的非線性變換,其是對輸入圖像灰度值進行指數變換,
一般情況下,當用於Gamma矯正的值大於1時,圖像的高光部分被壓縮而暗調部分被擴展,當Gamma矯正的值小於1時,圖像的高光部分被擴展而暗調部分被壓縮,Gamma矯正一般用於平滑的擴展暗調的細節。

在這裏插入圖片描述
中間的虛線代表,

程序

import cv2
import numpy as np
def Gamma_adjust(img,Gamma):
    table = np.zeros(256, dtype=np.float32)
    for i in range(256):
        table[i] = (i/255.0)**(Gamma)*255
    table = np.array(table.astype("uint8"))
    new_img = cv2.LUT(img, table)
    new_img = np.uint8(new_img)
    return new_img


img = cv2.imread("back.jpg",0)
cv2.imshow("initial",img)
img_ga = Gamma_adjust(img,2)
cv2.imshow("Gamma",img_ga)
Key = cv2.waitKey()
if Key == 27:
    cv2.destroyAllWindows()

對Gamma矯正進行本質的認識。

Gamma矯正出現的原因有兩個:

  • 韋伯定律
  • 中灰C

韋伯定律

韋伯定律,即感覺的差別閾跟隨原來刺激量的變化而變化,而且表現爲一定的規律性,用公式表示出來,就是ΔΦ/Φ=C \Delta\Phi/\Phi = C,其中Φ\Phi是原刺激量,ΔΦ\Delta\Phi是此時的差別閾限,C爲常數,又稱韋伯率。
簡單的理解就是,人對自然界的感知,是非線性的,外界以一定比例的加強刺激,對於人來說,這個刺激是均勻增長。
比如,聲音的強度是按照“分貝”來描述,倍數增加的音量聽起來是均勻增加的。

物理反射率檢測

人眼中的中度灰色的色塊,其物理亮度值大於在白色塊的20%左右。
在這裏插入圖片描述
此圖的原點是黑色,(1,1)是白色,你可以這麼理解此圖:當整體環境較暗,微小的亮度增長也會在人的心目中是顯著的明度提升,當物理亮度達到白色的20%左右的時候,人心目中已經感受到了中灰色的概念。而剩下的一半高光區的灰階,需要用白色80%的物理能量才能照亮成白色。

數字攝影和屏幕

爲了把事兒說明白,我們先把8位每通道圖像的數值,換算到0-1區間。8位圖上0是黑,255是白,中灰色是128。換算以後,黑是0,白是1,中灰是0.5。
要注意,8位每通道圖像,灰階預算極其有限,僅有256個,如同一盒256色的灰階蠟筆。
當我們在用數字相機拍照的時候,相當於對自然界採樣,並把數據編碼到圖像文件中。

假設光照適宜的場景中有一箇中灰色的物體,反射率是白紙的0.2,我們採樣到它的時候,應當把0.2的物理能量用0.454的Gamma放大到0.5的灰階地位記錄下來,這樣一來,暗部區域就分配到128個灰階了。我們充分地利用了存儲空間。
如果在拍照的時候不進行Gamma校正,那麼中灰物體會被映射爲0.2記錄下來,那麼此時,暗部僅分配到50個灰階,暗部採樣嚴重不足,高光采樣冗餘。
來到屏幕上,也就是文件解碼端,此時屏幕從計算機中讀到一個0-1的漸變,也就是從黑到白的均勻過渡(人眼感覺),圖片如下:
在這裏插入圖片描述
其中左端的色彩值是0,中間的色彩值是128(0.5),右邊是1.0的純白。解碼後,屏幕要以什麼樣的亮度顯示這些像素呢?最左邊像素關燈不顯示,是黑色,中間以白色21.8%的亮度顯示,右邊像素全開,顯示100%白色。這樣的一個圖片,在我們心目中看起來是均勻的灰度漸變。

此時屏幕的解碼Gamma是2.2,這個Gamma,會把0.5映射成0.218。也就是說計算機中存儲的圖片的物理亮度的均勻遞增的。
從這個角度來看。其實眼睛跟“照相機”真的挺像,我們看見自然界0.2的東西,就把它映射成0.5的地位,記到腦子裏了。

總結

在這裏插入圖片描述
總結段要說三個問題:
Gamma值2.2怎麼來的
爲什麼一直強調低動態圖像
如果灰階預算不緊張,會怎麼樣

Gamma=2.2怎麼來的?是實踐中目測調整出來並最終確定的,其實說良心話,只要是0.5中灰對應白色的20%左右,畫面看起來都是靠譜的,所以當年的Gamma特別多種多樣,在2.2上下浮動(1.8-2.5),1996年微軟和惠普在特定的光照條件下測試人觀看顯示器的感受,他們認爲,把8位圖像中128號灰(0.5灰)這個抽象的、代表心目中中灰色的數值,對應以白像素21.8%的亮度顯示出來,由黑到白的漸變過渡看起來會比較均勻。最終對應的Gamma就是2.2。那麼他們定了這個標準,後世的硬件也就都往上面靠了,包括拍照的時候,編碼Gamma也就取了1/2.2=0.454。這樣能保證整個編碼解碼系統總Gamma是1,高保真,自然界中的色值能在屏幕上相對完好的再現。

凡是說Gamma 2.2來自於老式CRT顯示器物理特性的解釋,都是誤解。這個誤解一般會這麼講解Gamma的來龍去脈:當年老式的CRT顯示器內置Gamma 2.35左右,解碼的時候會把輸入信號壓暗,所以我們呢,爲了保證總Gamma接近1,就要預先在編碼的時候把輸入文件的信號提亮,而且這樣一來呢,剛好順應了人眼對暗部感興趣的特點,把暗部的信息多多記錄了下來,充分利用了文件的空間,真是美妙的巧合啊。但是人類就被一個老式硬件的物理特性決定了後世的工業標準?這邏輯不對。

爲啥錯,比如當年要是沒有先發明CRT顯示器呢?假設我們先發明瞭一個物理Gamma爲1的顯示器。當輸入8位圖像0.5的數值的時候,它還是要乖乖的把這個0.5映射成白像素的20%輸出出來。否則看起來就不是中灰,8位每通道的顯示器Gamma必須在2.2左右,跟顯示器發展史沒關係,完全是視覺效果決定的。一切都因爲韋伯定律。

爲什麼一直強調低動態圖像?這個其實涉及到“自然景象再現成畫面”這樣一個複雜的事情,自然界是高動態的,亮度可以非常亮,也可以有一些明亮的光源,所以我在描述中灰的物理量的時候,我不可能描述成場景中最亮的物體亮度的20%,這個最亮的概念會非常不好確定。同一個明亮的場景中,中灰紙張應該是白紙反射率的20%而不是燈泡能量的20%。我如果把高亮物體牽涉僅來,事情就亂了。但是我可以用繪畫舉例子,畫布的動態範圍是有限的,最亮不過是畫布上的留白,屏幕的動態範圍也是有限的,最亮不過是白像素。所以在低動態範圍的語境下,我可以安全的定義,中灰蠟筆的反射率是白色蠟筆的20%左右,中灰像素的亮度是白像素亮度的20%左右,而不是現實場景中最亮物體的20%。這一點是很關鍵的。

另外,一切的前提必須是:灰階預算很緊張,只有灰階有限,我們才需要考慮中灰映射給誰的問題,如果灰階足足的夠用,硬盤不要錢了,網線足夠粗,我們主流不再使用8位每通道圖片記錄亮度信息的話,Gamma是沒必要的,我們直接把自然界的0.2記錄在文件上,顯示器讀取到0.2,也直接顯示就好了——32位每通道的hdr格式就是這樣的。32位格式中,中灰就被記作0.218,所以在32位環境中拉一個0-1的漸變是這樣的,很明顯暗部被壓縮了,高光區很多:
這張圖怎麼理解?它還是0-1的均勻漸變,中間那個顏色還是0.5,只不過32位圖中的數值就是自然界的物理量,所以這個色帶對應的其實是現實中的反射率。左邊五分之一20%處是中灰色,中間的像素表現的是反射率爲白色50%的物體看起來的灰度,這個灰度是0.5^0.454=73%灰。也就是8位下的186灰。具象的說,如果我有一支蠟筆反射率是50%,看起來就是中間這個灰度。

總之一句話:灰階有限的前提下,因爲人眼對自然的非線性感知特性,我們才需要Gamma校正。

具體到生活中的現象就是:因爲我們硬盤太貴,網線太細,所以地球人目前主流使用8位每通道的sRGB色彩描述體系,它灰階有限,中灰的地位必須在所有灰階的中間,記錄值爲128,而不能是其物理值0.218,把物理量0.218換算成0.5灰階編號的過程,就是編碼端的Gamma校正,Gamma值爲1/2.2=0.454。屏幕讀取到128顯示成21.8%的亮度的過程,就是解碼端的Gamma校正,Gamma值爲2.2。整個系統Gamma爲1。若是有朝一日,32位每通道文件成爲主流格式,Gamma校正就會消失。自然數據不經校正直接記錄爲文件數據,再不經校正直接顯示。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章