5.12. 二值閾值處理¶
許多影像處理管線最終都歸結為對每個像素提出的一個問題:這個亮度是否落在代表「前景」的範圍內?這個色彩是否夠接近紅色,足以成為應用正在追蹤的標記?這個像素是否屬於管線下一階段應該檢視的候選集合?閾值處理就是將這些問題在每個位置轉換成二值答案的運算——像素符合就為開,不符合就為關——並將整張影像化簡為其餘管線可據以運作的遮罩。
5.12.1. binary 方法¶
binary() 方法會在一次呼叫中對每個像素執行該分類。它接受一個閾值範圍的清單——也就是像素可符合並計為「開」的條件——並改寫影像,使每個至少符合其中一個範圍的像素設為該格式的最大值,每個不符合的像素則設為零。其結果就是其餘管線可直接使用的二值遮罩。
在最簡單的形式中,閾值清單只有一個範圍,這次呼叫會傳回一張落在該範圍內像素的遮罩:
img.binary([(120, 255)])
清單形式正是讓 binary 強大之處。想要追蹤兩個有色標記、或一個亮度範圍加上一個孤立飽和度峰值的管線,可以在同一份清單中傳入兩個範圍,並取得一張涵蓋所有符合項的單一輸出遮罩。
閾值處理會將連續值的影像轉換成二值遮罩:閾值範圍內的每個像素變成格式的最大值,範圍外的每個像素則變成零。¶
5.12.2. 灰階元組¶
對於灰階影像,閾值清單中的每個項目都是一個二元素元組 (lo, hi),描述一個閉區間的亮度範圍。值介於 lo 與 hi 之間(含端點)的像素符合;該範圍以外的一切都不符合。其自然的用法很直接:
(0, 60)符合暗像素——從黑色一直到深灰色的全部範圍。(180, 255)符合亮像素——從淺灰色一直到白色的全部範圍。(100, 160)符合中灰像素——亮度範圍中段的一個區帶。
元組中兩個值的順序並不重要;如果 lo 大於 hi,方法會在內部將它們對調,所以 (60, 0) 的效果與 (0, 60) 相同。
5.12.3. 用於色彩的 LAB 元組¶
對於 RGB565 影像,每個項目都是一個六元素元組 (l_lo, l_hi, a_lo, a_hi, b_lo, b_hi),描述的是 LAB 色彩空間中的閉區間範圍,而非直接以紅、綠、藍來描述。這些閾值分別是 L(明度)、A(綠到紅的色度軸)與 B(藍到黃的色度軸),各自與像素在該通道上的值比較。
選擇透過 LAB 而非直接對 RGB 套用閾值的原因,正是 LAB 色彩空間設計時所圍繞的特性:LAB 將明度與色度分離。兩個顯示相同色彩但亮度不同的像素,最終會落在不同的 L 值,但 A 與 B 值大致相同。這種分離讓閾值範圍能以一個色彩在 A 與 B 軸上的位置來描述它,並將 L 範圍開得很寬,以便從陰影到高光的每種亮度下都接受該色彩。以 RGB 為基礎的閾值做不到這一點——光線的任何變化都會同時改變 R、G、B 三個值,而建構在 RGB 閾值上的追蹤器,在第一次有雲飄過太陽時就會失效。
其實務用法是:挑選描述應用正在追蹤之色彩的 A 與 B 範圍,並將 L 範圍開得很寬——通常是 (0, 100) 以接受任何亮度——除非應用特別想在色彩之外也對亮度套用閾值。
對於少於六個值的元組,缺少的分量會預設為最大範圍(該軸不受限制)。因此在 RGB565 閾值清單中,一個二元素的 (l_lo, l_hi) 元組只會對明度套用閾值,並符合所有色彩。
備註
一個真正完全開放的 L 範圍在低端有個陷阱。當明度趨近於零時,每種色彩都會收斂於黑色,A 與 B 值塌縮趨近於零並由雜訊主導——因此暗像素可能漂入 A 與 B 範圍而被當成目標色彩追蹤。如果場景中的黑色區域亮起並被判為符合,請提高 l_lo 直到它們不再被納入。
5.12.4. 旗標¶
有三個關鍵字引數控制輸出:
invert=True會反轉結果。每個原本會符合的像素變成零,每個原本會是零的像素則變成最大值。當以「前景不是什麼」來描述前景更自然時,這很有用。zero=True會改變運算模式:符合的像素被歸零,不符合的像素則保留其原始值。當目標是從影像中抹除符合的像素,而非將影像化簡為它們的二值遮罩時,請使用這個。to_bitmap=True會將結果以一張BINARY影像傳回,而不是覆寫來源既有的格式。這種每像素一位元的結果正是後續遮罩引數能直接接受的形式,而且這種轉換往往能省下隨身攜帶一張完整格式遮罩的記憶體壓力。
遮罩與 ROI 遵循與其餘介面相同的慣例:roi 矩形將運算範圍限縮到一個子區域,mask 影像則將它限縮到任意的位置圖樣。
5.12.5. 預設就地運算¶
與算術運算一樣,binary 預設會就地執行:來源影像的像素會被二值輸出覆寫,呼叫之後原始值便不復存在。當需要保留來源、且輸出應為一張新配置的 BINARY 影像時,to_bitmap=True 形式是另一種選擇。若要在新緩衝區上取得相同格式的結果,也接受 copy=True 形式。