基于双线性插值的图像旋转原理及MATLAB实现(非自带函数)
目錄
- 1.圖像旋轉(zhuǎn)的原理
- 1.1.旋轉(zhuǎn)矩陣
- 1.2.雙線性插值
- 1.3.像素點(diǎn)匹配
- 2.實(shí)現(xiàn)效果與說明
1.圖像旋轉(zhuǎn)的原理
1.1.旋轉(zhuǎn)矩陣
旋轉(zhuǎn)一幅圖像(假設(shè)這幅圖像大小是矩形的),當(dāng)然應(yīng)該從像素點(diǎn)(pixels)開始,在直角坐標(biāo)系中,對點(diǎn)x0=[a0b0]x_0=\begin{bmatrix}a_0\\b_0\\ \end{bmatrix}x0?=[a0?b0??]逆時針旋轉(zhuǎn)角度θ\thetaθ到x1=[a1b1]x_1=\begin{bmatrix}a_1\\b_1\\ \end{bmatrix}x1?=[a1?b1??]的變換公式為
x1=[cosθ?sinθsinθcosθ]x0x_1=\begin{bmatrix}cos\theta & -sin\theta \\ sin\theta & cos\theta\\ \end{bmatrix}x_0x1?=[cosθsinθ??sinθcosθ?]x0?
那么對圖像上的每個點(diǎn)調(diào)用這個旋轉(zhuǎn)公式,將舊圖像像素點(diǎn)的RGB值搬移到新圖像像素點(diǎn),就可以將圖像旋轉(zhuǎn)到任意位置。
但是問題來了,顯示屏的像素點(diǎn)是有限的,這意味著顯示在顯示屏上的像素點(diǎn)坐標(biāo)必須是整數(shù),旋轉(zhuǎn)過后的圖像的每個像素點(diǎn)坐標(biāo)難免有非整數(shù)的情況,那么這種情況下我們怎么處理呢?
我們不妨假設(shè)逆時針旋轉(zhuǎn)θ\thetaθ旋轉(zhuǎn)后的圖形上所有的像素點(diǎn)都是整點(diǎn),對于旋轉(zhuǎn)后的圖形的每個像素點(diǎn)x1x_1x1?,求旋轉(zhuǎn)前圖形的對應(yīng)像素點(diǎn)的坐標(biāo)x0x_0x0?,取ω=?θ\omega=-\thetaω=?θ為逆旋轉(zhuǎn)角度,則旋轉(zhuǎn)后的像素點(diǎn)和旋轉(zhuǎn)前的像素點(diǎn)的對應(yīng)關(guān)系為:
x0=[cosω?sinωsinωcosω]x1x_0=\begin{bmatrix}cos\omega & -sin\omega \\ sin\omega & cos\omega\\ \end{bmatrix}x_1x0?=[cosωsinω??sinωcosω?]x1?
此時x0x_0x0?不一定為整點(diǎn),x0x_0x0?的像素值需要做一定的近似。近似的方法有最近鄰插值、雙線性插值等等,在這里我們就介紹比較實(shí)用且不是很復(fù)雜的雙線性插值,該插值方法不會產(chǎn)生明顯失真現(xiàn)象。
對于像素點(diǎn)的旋轉(zhuǎn)坐標(biāo)函數(shù)編寫如下:
①坐標(biāo)旋轉(zhuǎn)變換函數(shù):rot.m
1.2.雙線性插值
對于x和y坐標(biāo)非整數(shù)的非整點(diǎn)xpx_pxp?,假設(shè)它周圍的四個整點(diǎn)坐標(biāo)分別為x11,x12,x21,x22x_{11},x_{12},x_{21},x_{22}x11?,x12?,x21?,x22?(構(gòu)成一個矩形)。假設(shè)第一維度是x坐標(biāo),第二維度是y坐標(biāo)。則x11(1)=x21(1)≤xp(1)≤x12(1)=x22(1)x_{11}(1)=x_{21}(1)≤x_p(1)≤x_{12}(1)=x_{22}(1)x11?(1)=x21?(1)≤xp?(1)≤x12?(1)=x22?(1)
x11(2)=x12(2)≥xp(2)≥x21(2)=x22(2)x_{11}(2)=x_{12}(2)≥x_p(2)≥x_{21}(2)=x_{22}(2)x11?(2)=x12?(2)≥xp?(2)≥x21?(2)=x22?(2)
顯然,即使xpx_pxp?為整點(diǎn),仍然存在這樣的四個點(diǎn)x11,x12,x21,x22x_{11},x_{12},x_{21},x_{22}x11?,x12?,x21?,x22?使得上式成立。
在下圖中,P為非整點(diǎn),存在4個整點(diǎn)Q12,Q11,Q22,Q21Q_{12},Q_{11},Q_{22},Q_{21}Q12?,Q11?,Q22?,Q21?將P點(diǎn)包圍在其中,設(shè)縱向比例系數(shù)β=y?y2y1?y2\color{blue}\beta=\frac{y-y_2}{y_1-y_2}β=y1??y2?y?y2??,橫向比例系數(shù)α=x?x1x2?x1\color{blue}\alpha=\frac{x-x_1}{x_2-x_1}α=x2??x1?x?x1??顏色函數(shù)F(P)F(P)F(P)在四個整點(diǎn)處的值分比為F12,F11,F22,F21F_{12},F_{11},F_{22},F_{21}F12?,F11?,F22?,F21?,則P點(diǎn)的函數(shù)值
FP=β[(1?α)F11+αF21]+(1?β)[(1?α)F12+αF22]F_P=\beta[(1-\alpha)F_{11}+\alpha F_{21}]+(1-\beta)[(1-\alpha)F_{12}+\alpha F_{22}]FP?=β[(1?α)F11?+αF21?]+(1?β)[(1?α)F12?+αF22?]寫成矩陣的形式即為:
FP=[1?αα][F11F12F21F22][β1?β]F_P=\begin{bmatrix}1-\alpha & \alpha \end{bmatrix}\begin{bmatrix} F_{11} & F_{12} \\[2ex] F_{21} & F_{22} \end{bmatrix}\begin{bmatrix}\beta \\[2ex] 1-\beta \end{bmatrix}FP?=[1?α?α?][F11?F21??F12?F22??][β1?β?]
對于灰度圖像,F(P)F(P)F(P)是一維函數(shù),對于RGB圖像,F(P)=[FR(P)FG(P)FB(P)]F(P)=\begin{bmatrix}F_R(P) \\F_G(P) \\ F_B(P) \end{bmatrix}F(P)=???FR?(P)FG?(P)FB?(P)????
由于該公式較為復(fù)雜,可以單獨(dú)編寫雙線性插值函數(shù),輸入為一個任意點(diǎn)坐標(biāo),和圖像每個點(diǎn)的像素;輸出為該點(diǎn)進(jìn)行雙線性插值后的顏色函數(shù)值。但需要主要的是,若給采集的4個周圍整點(diǎn),有其中一個超出了圖像邊界,考慮到圖像邊界一般為白色,則以白色為替代。檢測點(diǎn)是否在畫布內(nèi)只需要條件判斷語句就夠了。
②檢測是否在畫布內(nèi)的判斷程序:isinrect.m
③雙線性插值函數(shù):linear_interp.m
function y=linear_interp(p,img)%p為需要雙線性插值的點(diǎn)坐標(biāo)(向量)x=p(1);y=p(2);m=size(img,1);n=size(img,2);x1=floor(x);x2=ceil(x);y1=floor(y);y2=ceil(y);%[x,y]四周的四個整點(diǎn)left=x-x1;%距左邊線距離bottom=y-y1;%距底線距離plt=[x1,y2;x2,y2;x1,y2;x2,y2];img_rect=[1,m,1,n];%原圖像的矩形框pix_rect=zeros(1,4,3);for t=1:4if isinrect(plt(t,:),img_rect)for color=1:3pix_rect(1,t,color)=img(plt(t,1),plt(t,2),color);endelsepix_rect(1,t,:)=255;%背景色為白色endendpixels=zeros(1,3);%保存該點(diǎn)的三原色的三個像素pix_rect=reshape(pix_rect,2,2,3);for color=1:3pixels(color)=[bottom,1-bottom]*pix_rect(:,:,color)*[1-left;left];%雙線性像素插值endy=pixels; end1.3.像素點(diǎn)匹配
假設(shè)圖像的點(diǎn)都是整點(diǎn)的情況下,新圖像是一個旋轉(zhuǎn)后的矩形,此時需要給新圖像定界使得新圖像能夠包括在一個旋轉(zhuǎn)角度為0°大矩形中。
left=max(x1,x2,x3,x4),right=min(x1,x2,x3,x4)left=max(x_1,x_2,x_3,x_4),right=min(x_1,x_2,x_3,x_4)left=max(x1?,x2?,x3?,x4?),right=min(x1?,x2?,x3?,x4?)
top=max(y1,y2,y3,y4),bottom=min(y1,y2,y3,y4)top=max(y_1,y_2,y_3,y_4),bottom=min(y_1,y_2,y_3,y_4)top=max(y1?,y2?,y3?,y4?),bottom=min(y1?,y2?,y3?,y4?)
定界完成后,只需要求出新圖像定界后每個像素點(diǎn)對應(yīng)的原圖像像素點(diǎn)坐標(biāo),并按照雙線性插值的方法取得像素值,對應(yīng)到新圖像點(diǎn)中,即可求出每個新圖像點(diǎn)的像素值,旋轉(zhuǎn)步驟即完成。要注意的是,如果雙線性插值遇到了原圖像界限外的點(diǎn),為保證程序不出錯,可以直接將界限外的點(diǎn)置為0(相當(dāng)于非常弱的邊緣虛化效果),或者直接將最外層邊界整點(diǎn)進(jìn)行最近鄰插值(這種分段算法實(shí)現(xiàn)會略微麻煩)。主函數(shù)文件代碼如下:
④主函數(shù)文件:img_process.m
2.實(shí)現(xiàn)效果與說明
將上述標(biāo)紅的4個M文件放在一個文件夾,并更改MATLAB目錄為該文件夾,并在該文件夾添加一張名為“足球.bmp”的位圖文件,在命令行輸入img_process(30)即可將該圖像旋轉(zhuǎn)30°顯示,顯示效果如下:
本文從原理上用MATLAB代碼實(shí)現(xiàn)了圖像的旋轉(zhuǎn),如果想直接調(diào)用MATLAB的函數(shù),請查看imrotate函數(shù)的相關(guān)說明:
new_img=imrotate(initial_img,angle,method, ‘crop’)
- angle:逆時針旋轉(zhuǎn)的角度,是角度值
- method:該參數(shù)為插值方法,其中’bilinear’為雙線性插值,可選
- crop:旋轉(zhuǎn)后增大圖像
總結(jié)
以上是生活随笔為你收集整理的基于双线性插值的图像旋转原理及MATLAB实现(非自带函数)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【逆强化学习-1】学徒学习(Appren
- 下一篇: JAVA基础之容器基础内容