5.24. 極座標轉換

極座標以相對於某個參考方向的角度,以及相對於某個選定中心的距離來標示每個像素,而不是以相對於左上角原點的水平與垂直偏移量來標示。這種表示法的價值在於一個恆等關係:繞選定中心的旋轉會變成沿角度軸的平移,這讓需要旋轉不變性的演算法能夠在比直接處理旋轉簡單得多的參數空間中進行搜尋。linpolar()logpolar() 負責執行這項重新投影。

5.24.1. 兩個方法

linpolar()線性距離軸執行從笛卡兒座標到極座標的重新投影。每個輸出欄對應繞中心的一個固定角度;每個輸出列對應距中心的一個固定距離。

img.linpolar()

logpolar()對數距離軸執行相同的重新投影。角度的處理方式完全相同;不同之處在於,距離沿輸出列向下是以指數而非線性方式成長。這個差異之所以重要,是因為極座標所揭示的第二個幾何恆等關係:繞選定中心對來源進行縮放會變成沿距離軸的平移——但僅在該軸為對數時成立。在線性距離軸下,縮放會拉伸極座標影像;在對數距離軸下,縮放則只是將它平移一個固定的量。

img.logpolar()

這兩個方法都接受 x=y= 關鍵字,用來以來源像素座標設定極座標重新投影的中心,分別預設為影像寬度的一半與高度的一半。中心的選擇很重要:以錯誤的點為中心進行極座標轉換,最終會使內容以破壞旋轉/平移恆等關係的方式被打亂。

三個並排的面板。最左邊 是一張笛卡兒座標的來源影像,顯示一個 時鐘錶面——兩個同心圓,外緣 以 30 度的倍數環繞著十二個刻度, 以及一根指向某個方向的單一指針。 中間的面板顯示該來源的 linpolar 重新投影: 一張矩形輸出影像,其中那 十二個刻度在頂列 呈現為等距分布的垂直線條, 兩個同心圓 呈現為位於不同垂直位置的兩條水平線, 而時鐘指針則在對應其角度的 位置呈現為一條單一的 垂直線。最右邊的面板顯示 logpolar 重新投影:沿 水平軸有相同的 角度分布,但內圈與外圈之間的 間隙因距離軸 為對數而受到壓縮。

一個時鐘錶面分別經由 linpolar()logpolar() 重新投影。來源中的同心圓在輸出中變成水平線;角度刻度則變成沿角度軸等距分布的垂直線。log-polar 變體會壓縮徑向間距。

5.24.2. 何時選用哪一個

linpolar()logpolar() 之間做選擇,就是在選擇應用程式所需要的是哪一種不變性。若僅需旋轉不變性——例如偵測同一個場景出現在兩個影格中,而第二個影格旋轉了一個未知的角度——linpolar() 就足夠了:旋轉在極座標影像中變成水平位移,而像 find_displacement() 這類僅處理平移的匹配器便能以該位移的大小還原出角度。當尺度不變性也很重要時——第二個影格既被旋轉被縮放——logpolar() 會將兩個未知量都收斂為平移:水平方向對應旋轉,垂直方向對應尺度。

這正是讓追蹤器對旋轉與尺度變化具有強健性的標準做法:將參考影格與每個即時影格繞同一中心重新投影為 log-polar,對這組影像執行 find_displacement(),然後從結果中讀取 rotationscale 欄位。

5.24.3. 展開圓形特徵

極座標轉換的另一種用途是展開影像中本質上呈圓形的特徵。時鐘錶面、儀表盤面、設計上即為圓形的檢測目標——這些在極座標投影中全都會變成線性的,而這正是大多數演算法較容易處理的形式。

上方的圖直接展示了這一點:時鐘錶面上那十二個刻度,在笛卡兒座標中沿圓周等距分布,在極座標影像中變成十二條等距分布的垂直線。在極座標影像中圍繞任何一個刻度畫一個矩形,便能標示出該刻度的位置,而無論擷取時時鐘錶面被旋轉到哪個方向都一樣。對極座標影像執行樣板匹配器,便能在一次掃描中找出每一個刻度。

5.24.4. 逆向映射

reverse=True 執行正向極座標投影的逆運算:給定一張極座標影像,產生出其極座標投影即為該影像的笛卡兒影像。應用程式呼叫正向形式以在極座標中執行演算法,接著呼叫逆向形式將結果投影回笛卡兒座標,供任何需要查看它的下游階段使用。

最常見的用途是修改極座標影像後再投影回去:對極座標影像套用一個濾鏡——一種水平平滑,以極座標的角度而言,它會跨越角度進行模糊但保留徑向結構——所產生的笛卡兒結果便是經過角度模糊的,而這是笛卡兒濾鏡無法直接做到的。