Matlab 透视变换 原理及其代码实现
生活随笔
收集整理的這篇文章主要介紹了
Matlab 透视变换 原理及其代码实现
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一、透視變換內(nèi)涵
透視變換本質(zhì):將一個圖像投影到新的視平面
透視變換思路:
將二維坐標(biāo)系轉(zhuǎn)換為三維坐標(biāo)系。
將三維坐標(biāo)系投影到新的二維坐標(biāo)系。
該過程屬于非線性變換過程,一個菱形在經(jīng)過非線性變換后得到一個四邊形,但是不在平行。
透視變換又可以稱為投影變換,仿射變換屬于透視變換的特例。透視變換能夠保持直線性,即原圖中的直線,在經(jīng)透視變換后仍為直線。
二、透視變換的詳細(xì)原理
總體思路:
求出投影映射矩陣:根據(jù)4個基準(zhǔn)坐標(biāo)對
反求出源圖像坐標(biāo):根據(jù)映射矩陣內(nèi)參數(shù),求一個二元一次方程組
透視變換矩陣變換公式為:
另外定點(diǎn),即移動到的目標(biāo)點(diǎn)為:
其中透視變換矩陣:
要移動的點(diǎn),即源目標(biāo)點(diǎn)(可以手動標(biāo)記)為:
這是一個從二維空間變換到三維空間的轉(zhuǎn)換,因?yàn)閳D像在二維平面,故除以Z,(X’;Y’;Z’)表示圖像上的點(diǎn):
另a33=1,展開上面的公式,可得到一個點(diǎn)為:
四個點(diǎn),即可得到8個方程,便可求解出透視變換矩陣A。
三、Matlab代碼實(shí)現(xiàn)
clear all; close all; clc;img= imread('1.jpg'); img= rgb2gray(img); imshow(mat2gray(img)); [M N] = size(img);dot=ginput(); %取四個點(diǎn),依次是左上,右上,左下,右下,這里我取的是書的四個角 w=round(sqrt((dot(1,1)-dot(2,1))^2+(dot(1,2)-dot(2,2))^2)); %從原四邊形獲得新矩形寬 h=round(sqrt((dot(1,1)-dot(3,1))^2+(dot(1,2)-dot(3,2))^2)); %從原四邊形獲得新矩形高y=[dot(1,1) dot(2,1) dot(3,1) dot(4,1)]; %四個原頂點(diǎn) x=[dot(1,2) dot(2,2) dot(3,2) dot(4,2)];%這里是新的頂點(diǎn),我取的矩形,也可以做成其他的形狀 %大可以原圖像是矩形,新圖像是從dot中取得的點(diǎn)組成的任意四邊形.:) Y=[dot(1,1) dot(1,1) dot(1,1)+h dot(1,1)+h]; X=[dot(1,2) dot(1,2)+w dot(1,2) dot(1,2)+w];B=[X(1) Y(1) X(2) Y(2) X(3) Y(3) X(4) Y(4)]'; %變換后的四個頂點(diǎn),方程右邊的值 %聯(lián)立解方程組,方程的系數(shù) A=[x(1) y(1) 1 0 0 0 -X(1)*x(1) -X(1)*y(1); 0 0 0 x(1) y(1) 1 -Y(1)*x(1) -Y(1)*y(1);x(2) y(2) 1 0 0 0 -X(2)*x(2) -X(2)*y(2);0 0 0 x(2) y(2) 1 -Y(2)*x(2) -Y(2)*y(2);x(3) y(3) 1 0 0 0 -X(3)*x(3) -X(3)*y(3);0 0 0 x(3) y(3) 1 -Y(3)*x(3) -Y(3)*y(3);x(4) y(4) 1 0 0 0 -X(4)*x(4) -X(4)*y(4);0 0 0 x(4) y(4) 1 -Y(4)*x(4) -Y(4)*y(4)];fa=inv(A)*B; %用四點(diǎn)求得的方程的解,也是全局變換系數(shù) a=fa(1);b=fa(2);c=fa(3); d=fa(4);e=fa(5);f=fa(6); g=fa(7);h=fa(8);rot=[d e f;a b c;g h 1]; %公式中第一個數(shù)是x,Matlab第一個表示y,所以我矩陣1,2行互換了pix1=rot*[1 1 1]'/(g*1+h*1+1); %變換后圖像左上點(diǎn) pix2=rot*[1 N 1]'/(g*1+h*N+1); %變換后圖像右上點(diǎn) pix3=rot*[M 1 1]'/(g*M+h*1+1); %變換后圖像左下點(diǎn) pix4=rot*[M N 1]'/(g*M+h*N+1); %變換后圖像右下點(diǎn)height=round(max([pix1(1) pix2(1) pix3(1) pix4(1)])-min([pix1(1) pix2(1) pix3(1) pix4(1)])); %變換后圖像的高度 width=round(max([pix1(2) pix2(2) pix3(2) pix4(2)])-min([pix1(2) pix2(2) pix3(2) pix4(2)])); %變換后圖像的寬度 imgn=zeros(height,width);delta_y=round(abs(min([pix1(1) pix2(1) pix3(1) pix4(1)]))); %取得y方向的負(fù)軸超出的偏移量 delta_x=round(abs(min([pix1(2) pix2(2) pix3(2) pix4(2)]))); %取得x方向的負(fù)軸超出的偏移量 inv_rot=inv(rot);for i = 1-delta_y:height-delta_y %從變換圖像中反向?qū)ふ以瓐D像的點(diǎn),以免出現(xiàn)空洞,和旋轉(zhuǎn)放大原理一樣for j = 1-delta_x:width-delta_xpix=inv_rot*[i j 1]'; %求原圖像中坐標(biāo),因?yàn)閇YW XW W]=fa*[y x 1],所以這里求的是[YW XW W],W=gy+hx+1;pix=inv([g*pix(1)-1 h*pix(1);g*pix(2) h*pix(2)-1])*[-pix(1) -pix(2)]'; %相當(dāng)于解[pix(1)*(gy+hx+1) pix(2)*(gy+hx+1)]=[y x],這樣一個方程,求y和x,最后pix=[y x];if pix(1)>=0.5 && pix(2)>=0.5 && pix(1)<=M && pix(2)<=Nimgn(i+delta_y,j+delta_x)=img(round(pix(1)),round(pix(2))); %最鄰近插值,也可以用雙線性或雙立方插值end end end figure; imshow(uint8(imgn));四、效果展示
總結(jié)
以上是生活随笔為你收集整理的Matlab 透视变换 原理及其代码实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开源项目学习笔记(1)——狗屁不通文章生
- 下一篇: 2022施工员-土建方向-岗位技能(施工