注:本文讲解 透视变换的原理 及matlab代码实现
一、透视变换内涵
透视变换本质:将图片重新投影映射到另外一个平面
透视变换思路:首先在新图与旧图之间找到4个基本坐标对,来求出映射矩阵,然后再向后映射插值
透视变换与仿射变换区别:详见这篇博客
二、透视变换的详细原理
这两篇博客没有故弄玄虚,对原理讲解的比较简洁清晰且易于理解,这里再强调一下思路步骤:
1. 求出投影映射矩阵:根据4个基准坐标对
2. 反求出源图像坐标:根据映射矩阵内参数,求一个二元一次方程组
三:Matlab代码实现
% 功能:透视变换
% 优点:在解决二元一次方程组问题上优化了算法,速度很快
% 缺点:插值采用最近邻插值,有点模糊
clear all;
clc;
img = imread('juxing.png');
img = rgb2gray(img);
imshow(img);
[m,n] = size(img);
dot=ginput(4); %取四个点,依次是左上,右上,左下,右下
dot(:,[1,2])= dot(:,[2,1]); % 变换x y坐标,x=行 y=列
col=round(sqrt((dot(1,1)-dot(2,1))^2+(dot(1,2)-dot(2,2))^2)); %从原四边形获得新矩形宽
row=round(sqrt((dot(1,1)-dot(3,1))^2+(dot(1,2)-dot(3,2))^2)); %从原四边形获得新矩形高
new_img = ones(row,col);
% 原图四个基准点的坐标
x = [dot(1,1),dot(2,1),dot(3,1),dot(4,1)];
y = [dot(1,2),dot(2,2),dot(3,2),dot(4,2)];
% 新图四个基准点坐标
X = [1,1,row,row];
Y = [1,col,1,col];
% 列出投影关系 求出投影矩阵
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)];%求解变换矩阵的行列式
B = [X(1),Y(1),X(2),Y(2),X(3),Y(3),X(4),Y(4)]';
C = inv(A)*B;
D = [C(1),C(2),C(3);
C(4),C(5),C(6);
C(7),C(8),1]; % 变换矩阵3*3模式
inv_D = inv(D);
for i = 1:row
for j = 1:col
% 解二元一次方程组,根据目标图像坐标反求出原图坐标
pix = inv_D * [i j 1]';
pix1 = inv([C(7)*pix(1)-1 C(8)*pix(1);C(7)*pix(2) C(8)*pix(2)-1])*[-pix(1) -pix(2)]';
if pix1(1)<m && pix1(2)<n
new_img(i,j) = img(round(pix1(1)),round(pix1(2))); %最近邻插值
else
new_img(i,j) = 255;
end
end
end
figure;
imshow(img,[]);title('原图');
figure;
imshow(new_img,[]);title('透视变换后')
程序效果:
注:代码中将原图转化成了灰度图,所以输出图像是黑白的
源图来源:https://blog.csdn.net/ChandelerGause/article/details/103029574