[數字影像學筆記] 4.直方圖變換2
文章目錄
分段函式(Piecewise Functions)
在前一章《[數字影像學筆記] 4.直方圖變換1》中所提到幾種針對直方圖的變化方法,基本上都是針對 [ 0 , 255 ] [0, 255] [0,255] 全部灰度值的變化,然後我們在實際的使用中也許並不需要對全部的灰度值進行變化,比如我們只想調整其中一部分的強度,或者只顯示其中的一部分。
那麼這種方法就是分段線性變化,有的地方也稱為分段濾波函式,或者直接稱呼它的數學定義分段函式。依據我們小學知道的數學定義,分段函式可以有多個不同的函式組成。
所以寫成公式的話,就表示成如下的樣子:
f ( X ) = { F 1 ( x 0 ) 0 ≤ x 0 < I 0 F 2 ( x 1 ) I 0 ≤ x 1 < I 1 ⋯ ⋯ F n ( x n ) I n ≤ x n ≤ 255 f(X) = \left\{\begin{matrix} F_1 \left ( x_0 \right ) & 0 \leq x_0 < I_0 \\ F_2 \left ( x_1 \right ) & I_0 \leq x_1 < I_1 \\ \cdots & \cdots \\ F_n \left ( x_n \right ) & I_n \leq x_n \leq 255 \end{matrix}\right. f(X)=⎩⎪⎪⎨⎪⎪⎧F1(x0)F2(x1)⋯Fn(xn)0≤x0<I0I0≤x1<I1⋯In≤xn≤255
分段線性變化函式(Piecewise Transformation Function)
區域性對比度拉伸(Contrast Stretching)
在岡薩雷斯的教材裡,提到了第一個簡單的Sample,好像是把花粉還是種子的圖片進行對比度拉伸。原圖是一張對比度非常低的圖片,很多圖片中的細節看不清楚,因此我們使用一個簡單的分段函式,對原圖進行對比度拉伸。
f ( X ) = { 0.25 ∗ x 0 ≤ x < 90 1.25 ∗ x 90 ≤ x < 160 0.25 ∗ x 160 ≤ x n ≤ 255 f(X) = \left\{\begin{matrix} 0.25 * x & 0 \leq x < 90 \\ 1.25 * x & 90 \leq x < 160 \\ 0.25 * x & 160 \leq x_n \leq 255 \end{matrix}\right. f(X)=⎩⎨⎧0.25∗x1.25∗x0.25∗x0≤x<9090≤x<160160≤xn≤255
def piecewise_transformation(image):
row, col, shape = image.shape
out_img = np.zeros((row, col))
# image conversion
for r in range(row):
for l in range(col):
val = image[r, l, 0]
if val < 90:
out_img[r, l] = val * 0.25
elif 90 <= val < 160:
out_img[r, l] = val * 1.25
else:
out_img[r, l] = val * 0.25
return out_img
通過拉伸以後,我們還可以發現很多細節,但是如果想進一步拉伸對比度,由於原圖中細節已經缺失很多,所以已經不太可能得到更多的細節了。
灰度級分層(Intensity-level slicing)
說到底這個方法也是分段線性函式的一種變形形式,也就是把我們感興趣的灰度範圍高亮、增強,把不喜歡的隱藏掉或者降低它的強度值。
f ( X ) = { F 1 ( x 0 ) 0 ≤ x 0 < I 0 F 2 ( x 1 ) I 0 ≤ x 1 < I 1 ⋯ ⋯ F n ( x n ) I n ≤ x n ≤ 255 f(X) = \left\{\begin{matrix} F_1 \left ( x_0 \right ) & 0 \leq x_0 < I_0 \\ F_2 \left ( x_1 \right ) & I_0 \leq x_1 < I_1 \\ \cdots & \cdots \\ F_n \left ( x_n \right ) & I_n \leq x_n \leq 255 \end{matrix}\right. f(X)=⎩⎪⎪⎨⎪⎪⎧F1(x0)F2(x1)⋯Fn(xn)0≤x0<I0I0≤x1<I1⋯In≤xn≤255
假設,比如對於分段函式來說,我們令範圍 [ 0 , I 0 ] [0, I_0] [0,I0] 和 F m ∈ [ I m , I n ] F_m \in [I_m, I_n] Fm∈[Im,In] 及 [ I n , 255 ] [I_n, 255] [In,255] 為0,也就是強調其中的 [ I m − 1 , I m ] [I_{m-1}, I_m] [Im−1,Im]這一段,以上的分段函式就可以寫作:
f ( X ) = { F 1 ( x 0 ) = 0 0 ≤ x 0 < I 0 ⋯ F m − 1 ( x m ) = f m I m − 1 ≤ x m − 1 < I m ⋯ F n ( x n ) = 0 I n ≤ x n ≤ 255 f(X) = \left\{\begin{matrix} F_1 \left ( x_0 \right ) = 0 & 0 \leq x_0 < I_0 \\ \cdots \\ F_{m-1} \left ( x_m \right ) = f_m & I_{m-1} \leq x_{m-1} < I_m \\ \cdots \\ F_n \left ( x_n \right ) = 0 & I_n \leq x_n \leq 255 \end{matrix}\right. f(X)=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧F1(x0)=0⋯Fm−1(xm)=fm⋯Fn(xn)=00≤x0<I0Im−1≤xm−1<ImIn≤xn≤255
當然也可以只增強興趣區域的值,所以你能看到兩個不同的分段增強函式的對映曲線,這裡我就不寫程式碼示例了,其實實現方法和上面的那個拉伸方法是相似的。
位元面分層(Bit-plane slicing)
這個簡單的說一下,主要是用於影像壓縮的一種方法。對於一個灰度畫素,它的數字通常是由8個位元組成的,你可以想象是由包含8個位元的數字組成的:
[ ( 2 7 ) n 7 , ( 2 6 ) n 6 , ( 2 5 ) n 5 , ( 2 4 ) n 4 , ( 2 3 ) n 3 , ( 2 2 ) n 2 , ( 2 1 ) n 1 , ( 2 0 ) n 0 ] [(2^7)n_7, (2^6)n_6, (2^5)n_5, (2^4)n_4, (2^3)n_3, (2^2)n_2, (2^1)n_1, (2^0)n_0 ] [(27)n7,(26)n6,(25)n5,(24)n4,(23)n3,(22)n2,(21)n1,(20)n0]
其中的 n n n 表示的是一個數位開關,它只有開合兩種狀態,因此對於一個在 [ 0 , 255 ] [0, 255] [0,255]範圍的數來說,就有8個位元位,如果我們完整的記錄一個位元數,從儲存空間上來說,就需要記錄8個開關的狀態,比如[1, 0, 0, 1, 1, 0, 0, 1]。
對一個灰度的還原方法因此就成了這樣
P = ( 2 7 ) n 7 + ( 2 6 ) n 6 + ( 2 5 ) n 5 + ( 2 4 ) n 4 + ( 2 3 ) n 3 + ( 2 2 ) n 2 + ( 2 1 ) n 1 + ( 2 0 ) n 0 P = (2^7)n_7 + (2^6)n_6 + (2^5)n_5+ (2^4)n_4 + (2^3)n_3 + (2^2)n_2 + (2^1)n_1 + (2^0)n_0 P=(27)n7+(26)n6+(25)n5+(24)n4+(23)n3+(22)n2+(21)n1+(20)n0
實際上對於一張圖片來說,它有時候保留的有效開關資訊其實很少,比如說一張天空的照片,它的有效畫素資訊可能幾種在 ( n 0 , n 1 , n 4 ) (n_0, n_1, n_4) (n0,n1,n4),而在 n 7 n_7 n7有少量資訊,而其他位上則基本沒有資訊。如果為了獲得最大壓縮率,那麼其實我們就可以只保留 ( n 0 , n 1 , n 4 ) (n_0, n_1, n_4) (n0,n1,n4)這三個開關的資訊,為了更好的說明,我這裡用矩陣表示一下這個過程:
I = [ n 3 n 2 n 1 n 0 0 0 1 1 0 1 0 1 0 1 1 1 0 0 1 1 ] I = \begin{bmatrix} n_3 & n_2 & n_1 & n_0 \\ 0 & 0 & 1 & 1 \\ 0 & 1 & 0 & 1 \\ 0 & 1 & 1 & 1 \\ 0 & 0 & 1 & 1 \end{bmatrix} I=⎣⎢⎢⎢⎢⎡n30000n20110n11011n01111⎦⎥⎥⎥⎥⎤
例如以上的矩陣,一共有4個點, n 3 n_3 n3 由於沒有資料,所以在對資料進行分層的時候,我們就可以把這一層捨棄,而不損失任何精度和細節。如果我們只保留 n 1 n_1 n1和 n 0 n_0 n0兩層位元層,如果在保留一定的細節情況下,那麼就可以在理論上把資料壓縮一半:
I = [ n 1 n 0 1 1 0 1 1 1 1 1 ] I = \begin{bmatrix} n_1 & n_0 \\ 1 & 1 \\ 0 & 1 \\ 1 & 1 \\ 1 & 1 \end{bmatrix} I=⎣⎢⎢⎢⎢⎡n11011n01111⎦⎥⎥⎥⎥⎤
對於高階語言來說,要把某個數轉化位位元,通常需要與運算(and operation),具體這裡就不實現了。
取樣函式(Sampling Functions)
從上面的這些例子中,我們發現,能夠對於原影像的灰度圖的修改,很大程度上用到了某種函式,無論是拉伸,還是其他,我們都是通過 I o = I i ⨀ f s I_o = I_i \bigodot f_s Io=Ii⨀fs 這樣一種形式進行的擴充套件。這個式子中的 f s f_s fs 就是取樣函式。
⨀ \bigodot ⨀ 在這裡,我們不明確指明原始資料與取樣函式的計算方式,它可以是點乘,可以是矩陣乘,也可以是卷積,甚至就像上面介紹的這些分段函式一樣,或者單純的加一些常數。
例如對於原始資料,在圖中表示紅色曲線的部分,其取樣函式 f s f_s fs為正態分佈曲線,數學上寫作:
f s = 1 2 π δ 2 e ( − ( x − μ ) 2 2 δ 2 ) f_s = \frac{1}{\sqrt{2 \pi \delta^2}}e(-\frac{(x-\mu)^2}{2\delta^2}) fs=2πδ21e(−2δ2(x−μ)2)
那麼對於這樣一個資料,當
⨀
\bigodot
⨀表示為元素乘的時候,取樣函式為正態分佈,每一個畫素點的新輸出的計算方式即:
I
1
′
=
I
1
⋅
f
s
(
P
1
)
I
2
′
=
I
2
⋅
f
s
(
P
2
)
⋯
I
n
′
=
I
n
⋅
f
s
(
P
n
)
{I_1}'= I_1 \cdot f_s(P_1) \\ {I_2}'= I_2 \cdot f_s(P_2) \\ \cdots \\ {I_n}'= I_n \cdot f_s(P_n) \\
I1′=I1⋅fs(P1)I2′=I2⋅fs(P2)⋯In′=In⋅fs(Pn)
取樣函式通常可以用於影像去噪,或者增強某一些興趣區間(ROI:region of interest),有時候我們會在一個應用中使用多種取樣函式,而不僅僅是其中一種,以獲得我們想要的資料。當然這部分屬於比較高階的內容了,我會在後面進行介紹。
人比較懶,我就不太想實現對影像的直方圖用這個正態分佈取樣後,會得到什麼的效果。如果你剛剛接觸這一部分內容不妨挑戰一下自己,當作作業。上一篇文章加上這篇文章介紹的,包括我所展示的程式碼,你能花費大概不超過一個小時的時間,體會一下采樣函式的神奇之處。
為了驗證你的取樣函式是否正常,你可以把原影像的直方圖,和取樣後得到的新的直方圖都繪製出來,進行比對。
相關文章
- 數字影像處理讀書筆記(三)直方圖匹配筆記直方圖
- 數字影像處理學習筆記(1)——傅立葉變換在影像處理中的應用筆記
- OpenCV計算機視覺學習(9)——影像直方圖 & 直方圖均衡化OpenCV計算機視覺直方圖
- matplotlib的直方圖繪製(筆記)直方圖筆記
- 個人實驗程式碼記錄 | 數字影像處理實驗3·影像直方圖與均衡化處理直方圖
- Python 影像處理 OpenCV (16):影像直方圖PythonOpenCV直方圖
- 【影像處理筆記】小波變換筆記
- opencv——影像直方圖與反向投影OpenCV直方圖
- 圖形學學習筆記二:觀測變換筆記
- 深度學習(模型引數直方圖)深度學習模型直方圖
- 透過交換指標變數的值改變大小數字的位置-學習筆記指標變數筆記
- 直方圖學習直方圖
- 影像演算法之直方圖均衡化(灰度影像)演算法直方圖
- Python 學習筆記-2-1-變數Python筆記變數
- 【opencv學習筆記】027之直方圖反向投影 - calcBackProject函式詳解OpenCV筆記直方圖Project函式
- 【影像處理】基於OpenCV實現影像直方圖的原理OpenCV直方圖
- TensorFlow筆記(2) 常量與變數【僅供自學】筆記變數
- Python學習筆記(2)慎重使用全域性變數Python筆記變數
- webrtc QOS筆記一 Neteq直方圖演算法淺讀Web筆記直方圖演算法
- Python學習筆記 - 變數Python筆記變數
- Tensorflow學習筆記: 變數及共享變數筆記變數
- 數論筆記:快速傅立葉變換筆記
- Python批次繪製遙感影像資料的直方圖Python直方圖
- 3. OpenCV-Python——影像梯度演算法、邊緣檢測、影像金字塔與輪廓檢測、直方圖與傅立葉變換OpenCVPython梯度演算法直方圖
- javascript學習筆記,二、變數JavaScript筆記變數
- 快速傅立葉變換 學習筆記筆記
- RxJava 學習筆記 -- 變換操作符RxJava筆記
- Python學習筆記 - 字串,數字Python筆記字串
- 【火爐煉AI】機器學習047-影像的直方圖均衡化操作AI機器學習直方圖
- JavaScript學習筆記2: js書寫語法及變數JavaScript筆記JS變數
- 數論學習筆記 (2):質數筆記
- OpenCV計算機視覺學習(11)——影像空間幾何變換(影像縮放,影像旋轉,影像翻轉,影像平移,仿射變換,映象變換)OpenCV計算機視覺
- OpenCV計算機視覺學習(3)——影像灰度線性變換與非線性變換(對數變換,伽馬變換)OpenCV計算機視覺
- 快速沃爾什變換 (FWT)學習筆記筆記
- R繪圖(2): 離散/分類變數如何畫熱圖/方塊圖繪圖變數
- [go 學習筆記] 二、變數、常量Go筆記變數
- 直方圖均衡化直方圖
- 基於深度學習的醫學影像配準學習筆記2深度學習筆記