本節我們總結一下數字圖像的幾何變換,區別於前面幾種操作(白平衡,灰度變換,空間濾波)針對於像素強度,幾何變換主要針對像素的位置。
對空間的操作主要包括仿射(線性)變換(平移,旋轉,伸縮,剪切)和投影變換。每種變換方法的具體細節不展開闡述,就是把對像素(變量)的操作提取出來作為變換矩陣(其實也就是線性代數中的線性變換,推薦B站從空間幾何的角度理解線性代數:https://b23.tv/BV1ys411472E/p1)。每個矩陣對應一種變換空間,如果進行多種疊加操作就是對應矩陣不斷左乘,多個線性空間不斷作用的結果。
仿射變換
平移,旋轉,伸縮是嚴格的2D線性變換,是剛體變換(本身的形態不發生變換),剪切可以保證圖中的平行線不變。2D線性變換中的變量有6個,也就是自由度DOF=6。
2D線性變換通項如下:
具體來說:
(圖中的旋轉對應逆時針旋轉)
投影變換
(投影變換中不保證平行線仍然平行)投影變換對應原來的線性變換再除以一個線性變換,投影變換矩陣中前兩行對應線性變換中的參數,這樣可以用該3 X 3的矩陣統一線性變換及投影變換,當最后一行為[0 0 1]時就是線性變換。
圖像插值
由圖像幾何變換帶來一個問題就是變換之后的像素值可能不是一個整數,而我們所使用的像素值一般是整數,所以需要近似來解決。插值的關鍵思想就是保證變換后的像素點和最近的鄰居最相似,最遠的鄰居最不相似,考慮的鄰居越多,圖像越光滑。一般插值方法有以下幾種:
下面解釋一下雙線性插值的思路:
由上圖知雙線性插值使用了4個相鄰的點,假設為a, b, c, d,經過變換后x落入abcd區間內,用經過x的橫縱線將該區間分塊,分別得到1,2,3,4四個點。
1點處的像素值由a, b兩點決定,並且應該和b最相近,所以給b的權值應該更大,x1=(1-α)a+αb,類似的,我們可以得到x2=(1-β)a+βc,x3=(1-β)b+βb,x4=(1-α)c+αd。
相似地,x的像素值可以由23決定也可以由14決定,得到的結果是一樣的。
x=(1-β)x1+βx4=(1-α)x2+αx3
應用及例子
本節內容最直接的例子就是圖像的配准。
再舉個幾何變換的具體栗子:將圖像順時針旋轉35度,x方向伸縮變換比例為0.6,平移50,y方向伸縮變換比例為0.8,平移15。
作出結果如下(左圖是原圖,右圖是變換后的圖)
參考代碼(雖然代碼比較簡單,但是里面有很多容易犯錯的地方,主要是matlab的定義方式略有不同)另:默認的插值方法是線性插值
addpath('E:\Digital_img_processing\Lecture_7_dicussion_geometry'); fig=imread('zombie.jpg'); rotate=[cosd(-35) sind(-35) 0; -sind(-35) cosd(-35) 0; 0 0 1]; % 圍繞原點逆時針旋轉-35度 scale=[0.6 0 0; 0 0.8 0; 0 0 1]; shift=[1 0 50; 0 1 15; 0 0 1]; tf=affine2d((shift*scale*rotate)'); % 需要轉置 output=imwarp(fig,tf); figure;imshowpair(fig,output,'montage'); axis on; xlabel x; ylabel y;
總結(易出錯的地方)
① matlab中幾何變換矩陣是我們定義的變換矩陣的轉置,這與其具體實現有關,所以記得轉置
(affine2d函數官方文檔)
② matlab中圖像坐標系統與圖像的坐標相反,如一般數字圖像原點在左上角,x軸向下,y軸向右,而matlab中y軸向下,x軸向右。這導致我們需要使用定義的順時針操作來實現逆時針,如栗子中的rotate變換定義。
③ 還有一個沒提到的問題就是根據變換矩陣推出進行了哪些變換操作(也就是上述操作的逆過程):
以一個matlab中的變換矩陣為例:
該矩陣是變換矩陣的轉置,平移很好看出來就是(-87.5517, 301.3816),而伸縮和旋轉是疊加的,利用變換前后的不變性sin2θ+cos2θ=1或者tanθ得到。θ=arctan(-0.7969/0.4853 = -58.6596°)
④ 弧度制問題,matlab中角度制函數后面比弧度制通常多一個d (degree), 如弧度制:cos() 角度制:cosd()。弧度->角度:rad2deg() 角度->弧度:deg2rad()。
ref:
matlab中的圖像坐標系統: https://blog.csdn.net/Enjolras_fuu/article/details/66530196