雙線性插值-影象旋轉
阿新 • • 發佈:2019-01-23
首先,什麼是雙線性插值?具體的說明大家可參照各種百科,我在這裡從影象角度來簡單講下,大體相似。
看下面這個圖影象旋轉後,畫素點的整數座標必然會得到小數,顯然在影象的畫素點裡面是沒有小數座標的,那計算這些點的顏色值怎麼辦呢,為了保持準確性,我們把旋轉後的影象再旋轉回去,看這個點旋轉回去後在原圖上是否是整數座標,如果是,那沒問題,如果不是(即至少有一個座標是小數),假設這個點為P,我們可以用跟P點最近的四個點的顏色值的某種加權平均和來估計(Q幾個點均是在原圖上,是確實存在的,而P不存在)。如圖所示,P的周圍四點為Q11,Q12,Q21,Q22。Q11和Q21加權平均得到R1,Q12和Q22加權平均得到R2,再用R1,R2加權平均得到P,就OK啦。
怎麼加權平均?可用距離作為權值,而相鄰畫素點距離為1,那就更簡單了,具體見程式碼。
第二點就是怎麼計算旋轉的問題了,建議大家用矩陣來做,比較方便,同樣也是為了方便,關於旋轉矩陣,我轉載了一篇博文,就是下一篇《旋轉矩陣》供大家參考。
Rotation.m
%以影象中心為中心旋轉 theta=30;%自定義旋轉角度,順時針 angle=theta*pi/180; a= cos(angle); b= sin(angle); rotation=[a,-b;b,a];%順時針旋轉矩陣 %rotation=[a,b;-b,a];%逆時針旋轉矩陣 A=imread('image_bmp\55.bmp');%讀入原影象,命名為A h=size(A,1); w=size(A,2); A= double(A);%為了便於後面的計算,這裡強制轉換為double型,原影象為uint8型 newh=round(h*a+w*b);%重新計算旋轉以後的視窗的長和寬 neww=round(h*b+w*a); for x = 1 : neww for y = 1 : newh t = rotation * [ y - newh / 2; x - neww / 2 ] + [ h / 2; w / 2 ];%t是一個兩行一列的座標矩陣,記錄旋轉後圖像返回到原圖中所在的位置 %繼續上行的註釋:等式後面的是我已經計算簡化後的表示,中間過程大家可參考我那篇博文,動動筆計算一下就是我的結果 if( t(1) >= 1 && t(2) >= 1 && t(1) <= h && t(2) <= w )%保證點落在原圖內 m = floor( t(1) );%m,n表示位置t最近且最小的點的下標 n = floor( t(2) );%由於鄰近畫素點在x,y方向上的距離均為1,顯然鄰近的其餘三個點分別為(m,n+1),(m+1,n),(m+1,n+1) d1 = A( m + 1, n, : ) * ( t(1) - m ) + A(m, n, : ) * ( 1 +m - t(1) );%d1,d2分別表示兩次加權和 %這裡的加權大家注意下,我們用的是某個點的顏色值乘以離它更遠的那段距離,這樣交錯相乘,可以把P點如果有整數座標的情況都包含進來,程式更具一般性 d2 = A( m + 1,n + 1, : ) * ( t(1) - m) + A(m, n + 1, : ) * ( 1 + m - t(1) ); d = d2 * ( t(2) - n ) + d1 * ( 1 + n - t(2) );%根據新算出來的d1,d2再做一次加權,得到最終四個點的加權和d B( y, x, : ) = round(d);%把d的最近整數賦給B的RGB值,B是我們旋轉後的圖 end end end B= uint8(B); imshow(B);
原始影象:
效果圖: