幾何變換改進圖像中像素間的空間關係。這些變換一般稱爲橡皮模變換,由於它們可當作是在一塊橡皮模上印刷一幅圖像,而後根據預約的一組規則拉伸該薄膜。在數字圖像處理中,幾何變換由兩個基本操做組成:算法
(1)座標的空間變換spa
(2)灰度內插,即對變換後的像素賦灰度值code
座標變換公式blog
(x,y) = T{(v, w)}圖片
其中,(v, w)是原圖像中像素的座標,(x, y)是變換後圖像中像素的座標。最經常使用的空間座標變換之一是仿射變換io
基於上式的仿射變換公式圖像處理
實際上,咱們能夠用兩種方法來使用上式。第一種方法稱爲向前映射,它由掃描輸入圖像的像素,並在每一個位置(v, w)用上式直接計算輸出圖像中相應像素的空間位置(x, y)組成。向前映射算法的一個問題是輸入圖像中的兩個或更多個像素可被變換到輸出圖像的同一位置,這就產生了如何把多個輸出值合併到一個輸出像素的問題。第二種方法,反向映射,掃描輸出像素的位置,並在每個位置(x, y)使用(v, w) = T-1(x, y)計算輸入圖像中的相應位置。而後經過內插決定輸出像素的灰度值。本篇文章使用反向映射。class
<以上基礎知識來源於 《數字圖像處理》岡薩雷斯 P50-P51 讀者可自行查閱>基礎
在上一篇文章中,主要是圖片的放大與縮小,在灰度內插的過程當中也涉及到目標圖像到原圖像的座標變換,代碼以下原理
1 void bilinera_interpolation(short** in_array, short height, short width, 2 short** out_array, short out_height, short out_width) 3 { 4 double h_times = (double)out_height / (double)height, 5 w_times = (double)out_width / (double)width; 6 short x1, y1, x2, y2, f11, f12, f21, f22; 7 double x, y; 8 9 for (int i = 0; i < out_height; i++){ 10 for (int j = 0; j < out_width; j++){ 11 x = j / w_times; 12 y = i / h_times; 13 x1 = (short)(x - 1); 14 x2 = (short)(x + 1); 15 y1 = (short)(y + 1); 16 y2 = (short)(y - 1); 17 f11 = is_in_array(x1, y1, height, width) ? in_array[y1][x1] : 0; 18 f12 = is_in_array(x1, y2, height, width) ? in_array[y2][x1] : 0; 19 f21 = is_in_array(x2, y1, height, width) ? in_array[y1][x2] : 0; 20 f22 = is_in_array(x2, y2, height, width) ? in_array[y2][x2] : 0; 21 out_array[i][j] = (short)(((f11 * (x2 - x) * (y2 - y)) + 22 (f21 * (x - x1) * (y2 - y)) + 23 (f12 * (x2 - x) * (y - y1)) + 24 (f22 * (x - x1) * (y - y1))) / ((x2 - x1) * (y2 - y1))); 25 } 26 } 27 }
其中,第11,12行爲目標圖像到原圖像的座標變換,接下來根據仿射變換公式對圖像作進一步處理
水平偏移變換公式爲
x = v
y = Sh * v + w
反解上述公式得
v = x
w = y - Sh * v
結果爲目標圖像到原圖像的座標變換,令Sh = 0.5,並對應用到上述代碼11,12行,同時將圖像擴大到2800*1280,結果爲
旋轉變換公式
x = vcosθ - wsinθ
y = vsinθ + wcosθ
令θ = ∏/4,反解得
v = x + y
w = y - x
將圖像擴大爲2000*2000,可是這個時候獲得的圖像爲
爲了解決這一問題,使旋轉後的圖像位於中央,我將所得圖片右移m_w, 下移m_h,則公式變爲
x = vcosθ - wsinθ + m_w
y = vsinθ + wcosθ + m_h
令θ = ∏/4,反解得
v = x + y - m_h - m_w
w = y - x - m_h + m_w
結果爲
其他變換原理基本相同,所以再也不進行演示