1. 程式人生 > >matlab 中的仿射變換函式

matlab 中的仿射變換函式

執行一般的二維空間變換包括如下三步:這三步是最基本的步驟

1.定義空間變換的引數;
2.建立變換結構體TFORM,它定義了你所要執行變換的型別;


TFORM結構體包含了執行變換需要的所有引數。你可以定義很多型別的空間變換,包括放射變換affine transformations(如平移translation,縮放scaling,旋轉rotation,剪下shearing)、投影變換projective transformations和自定義的變換custom transformations。

建立結構體的方法有兩種:使用maketform或者使用cp2tform。

 3.執行變換。
通過將要變換的影象和TFORM結構體傳遞給imtransform函式即可實現變換。

例項

Step 1: 匯入要變換的影象

Matlab提供了一個棋盤影象,可以以此作為例子,它的呼叫函式為checkerboard,它將建立一個80X80畫素的影象。

cb = checkerboard; % 匯入影象
figure,
imshow(cb)

Step 2: 定義空間變換
定義二維的空間變換需要一個3X3的變換矩陣,也可以通過在輸入影象和輸出影象上指定對應點的方式由maketform自動建立變換矩陣。這裡使用如下的變換矩陣來定義空間平移變換
% 定義變換矩陣
xform = [ 1   0     0
                0   1     0
                40 40  1 ];
% 在這個矩陣中,xform(3, 1)定義了影象在水平方向上平移的畫素數,xform(3, 2)定義了影象在垂直方向上平移的畫素數。


Step 3: 建立TFORM結構體
使用maketform函式可以建立TFORM結構體,引數為希望執行變換的型別和變換矩陣。
% 建立TFORM結構體
tform_translate = maketform('affine', xform);

Step 4: 執行變換


 使用imtransform函式執行變換,引數為要變換的影象和TFORM結構體,函式將返回變換後的影象。
% 執行變換
[cb_trans xdata ydata]= imtransform(cb, tform_translate);

%返回值中包含的另兩個額外輸出引數xdata和ydata,表示輸出影象在輸出座標空間的位置。xdata包含了輸出影象拐角處畫素的x座標,ydata包含了這些畫素的y座標(這裡說的x、y座標是指畫素的中點)。

平移變換的效果,可以看到,(1, 1)點的畫素轉移到了(41, 41)的位置,注意那一點的畫素值沒有變。

imtransform函式決定輸出影象的畫素值是把新位置映射回輸入影象的相應位置。在平移變換中,由於影象的大小和旋轉角度沒有變,所以是一一對映;對於其他型別的變換,如放縮、旋轉,此函式將在輸入影象上插值計算輸出影象的畫素值。學過影象處理的這個應該很清楚。


從結果看來,貌似變換沒有效果,變換後圖像和原影象是一樣的。但如果你檢查xdata和ydata的數值,就會看到影象的空間座標已經改變了。原始影象左上角的座標由(1, 1)變為了(41, 41),右下角由(80, 80)變為了(120, 120),40已經被加到了每個畫素的空間座標上。
>> xdata
xdata =    41   120
>> ydata
ydata =41   120

而顯示結果上沒有變化的原因是函式imtransform得到的輸出影象足夠包含了變換後的影象,但沒有包含全部的座標空間。要看到變換的效果,需要使用imtransform函式的額外輸入引數來指定輸出影象的大小和能包含輸出影象的輸出空間。
下面的程式碼使用了XData和YData兩個額外引數來指定能包含輸出影象的輸出空間,而對於輸出空間中不在輸出影象上的畫素預設為黑色,這可以通過改變imtransform函式的FillValues引數來指定。
% 修正的變換結果
cb_trans2 = imtransform(cb, tform_translate,...
    'XData', [1 (size(cb,2)+ xform(3,1))],...

    'YData', [1 (size(cb,1)+ xform(3,2))]);
figure,
imshow(cb_trans2)


定義空間變換的方式
         下面來討論定義空間變換的兩種方式:使用變換矩陣和使用對應點。


使用變換矩陣
         Maketform函式可以接受一個N維的變換矩陣來產生TFORM結構體。而由於imtransform只能做二維變換,故只能指定3X3的轉換矩陣。
如使用3X3的矩陣來指定任何的仿射變換,而對於仿射變換,最後一列必須是0 0 1,所以你指定3X2的矩陣就足夠了,在這種情況下,imtransform會自動新增第三列。

使用對應點
         除了指定變換矩陣,你還可以通過使用對應點來定義一個變換,讓maketform自動生成變換矩陣。 要對一個仿射變換使用此方法,需要在輸入、輸出影象上拾取3對非線性的點,而對於投影變換,則需要指定四對點。如
in_points = [11 11;21 11; 21 21];
out_points = [51 51;61 51;61 61];
tform2 = maketform('affine', in_points, out_points);


建立TFORM結構體
         有了上面的變換資料,就可以用maketform建立TFORM結構體了,也可以使用cp2tform函式來建立,具體詳見Image Registration。
         在使用maketform建立TFORM結構時,需要指定必要的變換方式。如要做平移變換需要指定為仿射變換方式,除此maketform還支援投影變換,另外可以使用custom和composite選項來指定任意的空間變換。
 
執行空間變換

         有了上面的TFORM結構體,就可以呼叫imtransform執行變換了。正如上面例子中所使用的那樣


[cb_trans xdata ydata]= imtransform(cb, tform_translate);

         另外,imtransform函式還支援幾個可選輸入引數來控制轉換的不同效果,如輸出影象的大小、填充值等。上面例子中的XData和YData就是控制輸出影象大小的輸入引數。對於填充值可以如下設定。

指定填充值
         當執行一個變換時,輸出影象上有很多畫素不在位於原輸入影象的位置,這些畫素必須被賦予一些值,這就是填充值。預設情況下,imtransform函式設定這些畫素為0,顯示為黑色。而通過使用FillValues引數可以指定不同的顏色。

對於灰度影象
         如果待轉換的影象是灰度影象,就需要指定一個標量值來設定灰度的陰暗度。如下
cb_fill = imtransform(cb, tform_translate,...
    'XData', [1 (size(cb,2)+xform(3,1))],...
    'YData', [1 (size(cb,1)+xform(3,2))],...
    'FillValues', .7 );

Figure
imshow(cb_fill)


對於RGB影象
         對於RGB彩色影象,可以使用一個標量值或者一個1X3的向量。如果使用標量,imtransform會使用相應陰暗度的灰度值來填充;如果使用向量,則會將其按RGB彩色值來使用。
% 彩色影象處理
rgb = imread('onion.png');
xform = [ 1 0 0
    0 1 0
    40 40 1 ];
tform_translate = maketform('affine',xform);
cb_rgb = imtransform(rgb, tform_translate,...
    'XData', [1 (size(rgb,2)+xform(3,1))],...
    'YData', [1 (size(rgb,1)+xform(3,2))],...
    'FillValues', [187;192;57]);
figure
imshow(cb_rgb)