圖像的幾何變換

包含相同內容的兩幅圖像可能因爲成像角度、透視關係乃至鏡頭自身緣由所形成的幾何失
真而呈現出大相徑庭的外觀,這就給觀測者或是圖像識別程序帶來了困擾。經過適當的幾何變
換能夠最大程度地消除這些幾何失真所產生的負面影響,有利於咱們在後續的處理和識別工做
中將注意力集中子圖像內容自己,更確切地說是圖像中的對象,而不是該對象的角度和位置等。
所以, 幾何變換經常做爲其餘圖像處理應用的預處理步驟, 是圖像歸一化的核心工做之一。 算法

本文主要包括如下內容 bash

  • 圖像的各類幾何變換, 如平移、鏡像和旋轉等
  • 插值算法
  • 圖像配準
  • 本章的典型案例分析
    • 基於直方圖均衡化的圖像灰度歸一化
    • 汽車牌照的投影失真校訂

解決幾何變換的通常思路

圖像幾何變換又稱爲圖像空間變換, 它將一幅圖像中的座標位置映射到另外一幅圖像中的
新座標位置. 咱們學習幾何變換的關鍵就是要肯定這種空間映射關係, 以及映射過程當中的變
換參數。
幾何變換不改變圖像的像素值, 只是在圖像平面上進行像素的從新安排。一個幾何變換
須要兩部分運算:首先是空問變換所需的運算, 如平移、旋轉和鏡像等, 須要用它來表示輸
出圖像與輸入圖像之間的〈像素〉映射關係:此外, 還須要使用灰度插值算法, 由於按照這
種變換關係進行計算, 輸出圖像的像素可能被映射到輸入圖像的非整數座標上。markdown


之因此要逆變換是由於:
函數

圖像平移

圖像平移就是將圖像中全部的點按照指定的平移量水平或者垂直移動。 學習

圖像平移的變換公式
ui

對於原圖中被移出圖像顯示區域的點一般也有兩種處理方法:直接丟棄或者經過加目標圖像的尺寸〈將新生成的圖像寬度增長 Tx ,高度增長 Ty 〉的方法使新圖像中可以包含這些點,在稍後給出的程序實現中,咱們來用了第一種處理方法。. spa

init = imread('lena.bmp'); % 讀取圖像
[R, C] = size(init); % 獲取圖像大小
res = zeros(R, C); % 構造結果矩陣。每一個像素點默認初始化爲0(黑色)
delX = 50; % 平移量X
delY = 50; % 平移量Y
tras = [1 0 delX; 0 1 delY; 0 0 1]; % 平移的變換矩陣 

for i = 1 : R
    for j = 1 : C
        temp = [i; j; 1];
        temp = tras * temp; % 矩陣乘法
        x = temp(1, 1);
        y = temp(2, 1);
        % 變換後的位置判斷是否越界
        if (x <= R) & (y <= C) & (x >= 1) & (y >= 1)
            res(x, y) = init(i, j);
        end
    end
end;

figure;
subplot(1,2,1);
imshow(uint8(init)); title('原圖像'); 
subplot(1,2,2);
imshow(uint8(res)); % 顯示圖像
title('平移後');

圖像鏡像

鏡像變換又分爲水平鏡像和堅直鏡像。水平鏡像即將圖像左半部分和右半部分以圖像堅直中軸線爲中心軸進行對換;而豎直鏡像則是將圖像上半部分和下半部分以圖像水平中軸線爲中心軸進行對換. 3d

圖像鏡像的交換公式
rest

matlab實現
imtransform函數用於完成通常的二維空間變換,形式以下:
B=imtransform(A,TFrom,method)
code

A=imread('lena.bmp');
[height,width,dim]=size(A);
tform= maketform('affine',[-1 0 0;0 1 0;width 0 1]);

B = imtransform(A,tform,'nearest');
tform2=maketform('affine',[1 0 0;0 -1 0;0 height 1]);
C = imtransform(A,tform2,'nearest');

subplot(1,3,1),imshow(A);
title('原圖像');
subplot(1,3,2),imshow(B);
title('水平鏡像');
subplot(1,3,3),imshow(C);
title('豎直鏡像');

圖像轉置

圖像轉置是指將圖像像素的x座標和y座標互換,圖像的大小會隨之改變:高度和寬度將互換。

圖像轉置的交換公式

matlab實現

A = imread('lena.bmp');
tform = maketform('affine',[0 1 0;1 0 0;0 0 1]);
B = imtransform(A,tform,'nearest');

subplot(1,2,1),imshow(A);
title('原圖像');   
subplot(1,2,2),imshow(B);
title('圖像轉置');

圖像縮放

圖像縮放是指圖像大小按照指定的比率放大或者縮小

圖像縮放的變換公式

直接根據縮放公式計算獲得的目標圖像中,某些映射源座標可能不是整數,從而找不到
對應的像素位置。例如,當 Sx=Sy=2 時,圖像放大2倍,放大圖像中的像素(0, 1)對應於
原圖中的像素(0, 0.5),這不是整數座標位置,天然也就沒法提取其灰度值。所以咱們必須
進行某種近似處理,這裏介紹一種簡單的策略即直接將它最鄰近的整數座標位置(0,0)或者
(0,1)處的像素灰度值賦給它,這就是所謂的最近鄰插值。固然還能夠經過4.7節將介紹的其
他插值算法來近似處理.

matlab實現
縮放變換仍然可藉助前面幾節中使用的imtransform函數來實現。此外,Matlab還提供
專門的圖像縮放函數imresize,具體調用形式爲:

B = imresize(A,Scale,method);

參數說明:
a爲縮放的原始圖像
Scale爲統一縮放比例
method用於指定插值方法,其合法取值同imtransform

A = imread('lena.bmp');
B = imresize(A,1.2,'nearest');

figure,imshow(A);title('原圖像');   
figure,imshow(B);title('圖像縮放');

圖像旋轉

旋轉通常是指將圖像圍繞某一指定點旋轉必定的角度。旋轉一般也會改變圖像的大小,
和4.2 節中圖像平移的處理同樣, 能夠把轉出顯示區域的圖像截去, 也能夠改變輸出圖像的
大小以擴展顯示範圍.

以原點爲中心的圖像旋轉

以任意點爲中心的圖像旋轉
在4.6.1小節中給出的旋轉示例是以座標原點爲中心進行的,那麼如何圍繞任意的指定
點來旋轉呢?將平移和旋轉操做相結合便可,即先進行座標系平移,再以新的座標原點爲中
心旋轉,而後將新原點平移回原座標系的原點。這一過程可概括爲如下3個步驟:

至此,咱們已經實現了上述3個步驟中的第1步和第3步,再加上第2步的旋轉變換就
獲得了圍繞圖像中心點旋轉的最終變換矩陣,該矩陣其實是3個變換步驟中分別用到的3
個變換矩陣的級聯。

matlab實現
圖像旋轉變換的效果受具體插值方法的影響較爲明顯,本節給出的實現均採用最近鄰插 值,在 4.7 節中將給出來用不一樣的插值算法時圖像旋轉變換的效果比較。

可經過4.6.2 小節中學習的方法設置適當的變換結構TFORM,從而調用imtansform來
實現以任意點爲中心的圖像旋轉。此外, Matlab 還專門提供了圍繞圖像中心的旋轉變換函數
imrotate ,其調用方式以下:
B=imrotate(A,angle,method,’crop’)
參數說明:

  • A是要旋轉的圖像.
    • angle 爲旋轉角度,單位爲度,若是爲其指定一個正值,則imrotate 函數接逆時針方
    向旋轉圈像.
    · 可選參數method爲imrotate 函數指定插佳方法.
    • ‘crop'選項會裁剪旋轉後增大的圖像,使獲得的圈像和原圖大小一致.
A = imread('lena.bmp');
B = imrotate(A,30,'nearest','crop');
subplot(1,2,1),imshow(A);
title('原圖像');
subplot(1,2,2),imshow(B);
title('逆時針旋轉30度');

插值算法

實現幾何運算時, 有兩種方法。第一種稱爲向前映射法, 其原理是將輸入圖像的灰度逐
個像索地轉移到輸出圖像中,即從原圖像座標計算出目標圖像座標: g(x_1,y_1) = f(a(x_o,y_o}, b(x_o,  
y_o))
。前面的平移、鏡像等操做就能夠採用這種方法。

另一種稱爲向後映射法, 它是向前映射變換的逆操做, 即輸出像素逐個映射回輸入圖
像中。若是一個輸出像素映射到的不是輸入圖像來樣柵格的整數座標處的像素點, 則其灰度
值就須要基於整數座標的灰度值進行推斷, 這就是插值。因爲向後映射法是逐個像素產生輸
出圖像, 不會產生計算浪費問題, 因此在縮放、旋轉等操做中多采用這種方法, 本書採用的
也所有爲向後映射法。

最近鄰插值

最近鄰插值可表示爲:
f(x,y) = g(round(x), round (y) );
咱們在以前的各類變換Visual C++實現中均採用了最近鄰插值的算法,由於它計算簡單,
並且在不少狀況下的輸出效果也能夠接受。然而, 最近鄰插值法會在圖像中產生人爲加工的
痕跡, 詳見例4.1.

雙線性插值

雙線性插值又稱爲一階插值,是線性插值擴展到二維的一種應用。它能夠經過一系列的一階線性插值獲得.

輸出像素的值爲輸入圖像中距離它最近的2×2鄰域內來樣點像素灰度值的加權平均。
設己知單位正方形的頂點座標分別爲f(O,0)、f(1 ,O)、f(O,1)、f(1,1), 如圖4.14所示, 咱們
要經過雙線性插值獲得正方形內任意點f(x,y)的值。

上面的推導是在單位正方形的前提下進行的, 稍加變換就能夠推廣到通常狀況中.
線性插值的假設是原圖的灰度在兩個像素之問是統性變化的, 顯然這是一種比較合理的
假設.所以在通常狀況下,雙線住插值都能取得不錯的效果。更精確的方法是果用曲線插值,
即認爲像素’之間的灰度變化規律符合某種曲線方程, 固然這種處理的計算量是很大的。

高階插值

在一些幾何運算中, 雙線性插值的平滑做用會使圖像的細節退化, 而其斜率的不連續性
則會致使變換產生不但願的結果. 這些均可以經過高階插值獲得彌補, 高階插值經常使用卷積來
實現。輸出像素的值爲輸入圖像中距離它最近的4×4領域內採樣點像素值的加權平均值。
下面以三次插值爲例, 它使用了以下的三次多項式來逼近理論上的最佳插值函數
sin(x)/x,如圖4.15 所示.

插值方法比較
下面的程序對兩幅不一樣的圖像進行圖像旋轉, 分別採用了最近鄰、雙線性和三次插值,
觀察它們的不一樣效果.

A = imread('rectangle.bmp');
B = imrotate(A,30,'nearest');
C = imrotate(A,30,'bilinear');
D = imrotate(A,30,'bicubic');

subplot(2,2,1),imshow(A);
title('原圖像');
subplot(2,2,2),imshow(B);
title('最近鄰插值');
subplot(2,2,3),imshow(C);
title('雙線性插值');
subplot(2,2,4),imshow(D);
title('雙三次插值');

從圖4.17能夠看出最近鄰的插值方法獲得的結果仍是能夠接受的,但當圖像中包含的像素之間灰度級有明顯變化時(見圖4.16),從結果圖像的鋸齒形邊能夠看出三種插值方法的效果依次遞減,最近插值的效果明顯不如另外兩個好,鋸齒比較多,而雙三次插值得出的圖像較好地保持了圖像的細節。這是由於參與計算輸出點的像章值的擬合點個數不一樣,個數越多效果越精確,固然參與計算的像素個數會影響計算的複雜度:實驗結果也清楚地代表雙三 次插值法花費的時間比另外兩種的要長一些。最近鄰和線性插值的速度在這次圖像處理中幾乎分不出來。因此,在討算時間與質量之間有一個折中問題。

圖像配準

什麼是圖像配準
所謂圖像配準就是將同一場景的兩幅或多幅圖像進行對準。如航空照片的配準, 以及在
不少人臉自動分析系統中的人臉歸一化, 即要使各張照片中的人臉具備近似的大小, 儘可能處
於相同的位置。
通常來講, 咱們以基準圖像爲參照, 並經過一些基準點(fudical points)找到適當的空
間變換關係s和r,對輸入圖像進行相應的幾何變換,從而實現它與基準圖像在這些基準點位
置上的對齊。
下面就以人臉圖像的校準爲例, 介紹如何在Matlab中實現圖像配準。

Iin = imread('lena2.bmp');
Ibase = imread('lena.bmp');

figure;
subplot(1,2,1),imshow(Iin);
subplot(1,2,2),imshow(Ibase);
cpselect(Iin,Ibase);

tform = cp2tform(movingPoints,fixedPoints,'affine');

相關文章
相關標籤/搜索