图像透视变换原理及实现

article/2025/10/3 21:29:12

上篇博客讲解了图像的仿射变换原理及实现,这篇博客讲讲透视变换的原理和实现,透视变换也叫投影变换,仿射变换是透视变换的特例。主要是透视变换能保持“直线性”,即原图像里面的直线,经透视变换后仍为直线。下面给出数学推导:

透视变换矩阵变换公式为:

其中透视变换矩阵:

               

要移动的点,即源目标点为:

                          

另外定点,即移动到的目标点为:

                       

这是一个从二维空间变换到三维空间的转换,因为图像在二维平面,故除以Z,  (X';Y';Z')表示图像上的点:

,展开上面公式,得到一个点的情况:

                                    

4个点可以得到8个方程,即可解出A。

                            

下面代码是上面公式的具体实现,getPerspective()是根据4组点对获取的透视变换矩阵。

function perspective_mat = getPerspective(moving_points,fixed_points)
% GETPERSPECTIVE 根据点获取透视变换矩阵
% 输入:
%     moving_points:n*2点集坐标(x,y)
%     fixed_points:n*2点集坐标(x,y),点顺序要对应moving_points
% 输出:
%     perspective_mat:3*3透视变换矩阵
% 
%  perspective_mat矩阵形式为[a11,a12,a13; a21,a22,a23; a31,a32,1];
%   满足fixed_points = perspective_mat*moving_points
% author: cuixing158@foxmail.com
%assert(size(moving_points,1) == size(fixed_points,1)&& ...
size(moving_points,1)>=4);nums = size(moving_points,1);
coefficient_mat = zeros(2*nums,8);
b = zeros(2*nums,1);
for i = 1:numscurrentPoint = moving_points(i,:);currentFixedPoint = fixed_points(i,:);coefficient_mat(2*i-1,:) = [currentPoint(1),currentPoint(2),1,...0,0,0,...-currentPoint(1)*currentFixedPoint(1),-currentFixedPoint(1)*currentPoint(2)];b(2*i-1) = currentFixedPoint(1);coefficient_mat(2*i,:) = [0,0,0,...currentPoint(1),currentPoint(2),1,...-currentPoint(1)*currentFixedPoint(2),-currentPoint(2)*currentFixedPoint(2)];b(2*i) = currentFixedPoint(2);
end
perspective_mat = coefficient_mat\b; % 大于4个点时候为最小二乘法计算
perspective_mat = reshape([perspective_mat;1],3,3)';

上面函数是通过4组点(大于等于)获取透视变换矩阵。下面给出测试代码,分别用手写的和系统的函数,对比时间加以说明。

%% prepare
img = rgb2gray(imread('book.jpg'));
width = size(img,2);
height = size(img,1);
figure;imshow(img)
% moving_points = [0,0;
%                 100,50;
%                 0,50;
%                 50,100];
moving_points = ginput(4);
hold on ; plot(moving_points(:,1),moving_points(:,2),'ro');
fixed_points = [0,0;100,0;0,200;100,200];%% method 1,use matlab function
tfom = fitgeotrans(moving_points,fixed_points,'projective');
X = moving_points(:,1);
Y = moving_points(:,2);
[x,y] = transformPointsForward(tfom,X(:),Y(:));
figure;plot(x,y,'ro');title('验证坐标点对齐')
grid on
tic;
dst_img = imwarp(img,tfom);
t_sys = toc;
figure;imshow(dst_img);title(['图像仿射变换后(系统函数),耗时(s):',num2str(t_sys)])%% method 2, get perspective matrix
perspective_mat = getPerspective(moving_points,fixed_points);
A = perspective_mat;
X = [1;width;1;width]; % 原图片的四个角点x坐标
Y = [1;1;height;height]; % 原图片的四个角点y坐标
moving_points_mat = [X(:)';Y(:)';ones(1,size(X(:),1))];
dst_points = A*moving_points_mat;
for i = 1:size(dst_points,2)dst_points(1:2,i) = dst_points(1:2,i)/dst_points(3,i);
end
figure;plot(dst_points(1,:),dst_points(2,:),'bo');title('原图像仿射变换后的坐标范围')
grid on;%% 仿射变换后图像逐像素进行插值赋值
min_x = min(dst_points(1,:));
max_x = max(dst_points(1,:));
min_y = min(dst_points(2,:));
max_y = max(dst_points(2,:));
W = round(max_x - min_x);
H = round(max_y -min_y);
wrapImg = zeros(H,W);
tic;
for i = 1:Hfor j = 1:Wx = min_x+j; % 使得x,y的范围在原坐标范围内y = min_y+i;moving_point = A\[x;y;1];temp_point = [moving_point(1);moving_point(2)]./moving_point(3);if temp_point(1)>=1&&temp_point(1)<width&& ...temp_point(2)>=1&&temp_point(2)<heightwrapImg(i,j) = img(round(temp_point(2)),round(temp_point(1)));endend
end
t_manual = toc;
figure;
imshow(uint8(wrapImg));title(['图像仿射变换后(手写函数),耗时(s):',num2str(t_manual)])

红色圆圈为鼠标点选的点,顺序为书籍左上点、右上点、左下点、右下点。图中对比可以看出,效果是一样的,不过系统的函数效率高,耗时较少。

2022.12.9 开源地址(10行代码实现透视变换贴广告图):GitHub - cuixingxing150/perspective-homography-matlab


http://chatgpt.dhexx.cn/article/RVUKKx0F.shtml

相关文章

(十四)透视变换

透视变换(Perspective Transformation) 一 图像变换与平面坐标系的关系 1、旋转&#xff1a; 2、平移&#xff1a; 3、刚体变换 4、仿射变换 5、投影变换&#xff08;单应性变换&#xff09; 6 总结一下&#xff1a; 1、刚体变换&#xff1a;平移旋转&#xff0c;只改变物体…

图像畸变矫正——透视变换

图像畸变矫正——透视变换 由于相机制造精度以及组装工艺的偏差引入的畸变&#xff0c;或者由于照片拍摄时的角度、旋转、缩放等问题&#xff0c; 可能会导致原始图像的失真&#xff0c;如果要修复这些失真&#xff0c;我们可以通过透视变换&#xff0c;对图像进行畸变矫正。 …

透视变换原理实例代码详解

导读 在上篇文章中&#xff0c;我们介绍了仿射变换&#xff0c;我们只需要通过一个两行三列的变换矩阵M就能够对图像实现平移、缩放、翻转、旋转操作。我们发现这些变换其实都属于平面变换&#xff0c;如果我们想要进行空间变换呢&#xff1f; 将上图的扑克牌单独提取出来&am…

[解疑]图像、矩阵的二维空间变换

本文经过参考多个文章整理而成&#xff0c;感谢各位博主的无私分享。 综述 图像&#xff08;2维平面&#xff09;到图像&#xff08;2维平面&#xff09;的四种变换包括&#xff1a;等距变换&#xff0c;相似变换&#xff0c;仿射变换&#xff0c;投影变换。对图像的几何变换…

数字图像处理(入门篇)十四 透视变换

目录 一 透视变换 二 实践 &#xff08;1&#xff09;代码 &#xff08;2&#xff09;结果图 一 透视变换 现实生活中的空间是三维的&#xff0c;图像中的物体存在近大远小的特征&#xff0c;这种畸变仿射变换不能矫正。因此&#xff0c;我们需要使用到三维空间的变化&…

【图像理论】透视变换

透视变换&#xff1a; 定义&#xff1a;本质是将图像投影到一个新的视平面。仿射变换可以理解为透视变换的特殊形式。利用透视中心、像点、目标点三点共线的条件&#xff0c;按透视旋转定律使承影面&#xff08;透视面&#xff09;绕迹线&#xff08;透视轴&#xff09;旋转某…

Python图像处理之透视变换

1 引言 如果你想对图像进行校准&#xff0c;那么透视变换是非常有效的变换手段。透视变换的定义为将图像投影到一个新的视平面&#xff0c;通常也被称之为投影映射。 2 公式 一般来说&#xff0c;通用的图像变换公式如下所示&#xff1a; 上述公式中&#xff0c;u,v代表原…

维特比算法 python_维特比算法理解与实现(Python)

前言 写这篇文章就是想以通俗易懂的方式解析维特比算法&#xff0c;最后给出Python代码的实现。下面的公式和原理均出自《统计学习方法》。 算法的原理 算法的原理1.PNG 算法的原理2.PNG 上面写了一大堆&#xff0c;意思就是&#xff1a;每个时刻选择出概率最大的路径&#xf…

viterbi-algorithm 维特比算法的例子解析

维特比算法的目的&#xff1a; 寻找最可能的隐藏状态序列(Finding most probable sequence of hidden states) 关于原理的讲解可以参考下面两篇文章&#xff0c;讲的比较清楚 小白给小白详解维特比算法1. 小白给小白详解维特比算法2. 本文通过分析维特比算法的例子&#xff0c…

维特比算法代码

维特比算法实现python语言版 本文主要写一个关于维特比算法的代码&#xff0c;具体理论请参考一文搞懂HMM&#xff08;隐马尔可夫模型&#xff09;&#xff1a; HMM&#xff08;隐马尔可夫模型&#xff09;是用来描述隐含未知参数的统计模型&#xff0c;举一个经典的例子&…

维特比算法学习

参考文章1&#xff1a; 简直不要太通俗易懂&#xff0c;这篇文章&#xff0c;很值得看 参考文章2&#xff1a; 解释一些概念性的问题&#xff0c;我把他的一些内容写下来 维特比(Viterbi)算法的核心是动态规划。 对于 HMM 而言&#xff0c;其中一个重要的任务就是要找出最有…

5分钟理解维特比算法

安德鲁维特比老人家发明了维特比算法&#xff0c;用非常巧妙的方法简化了隐马尔可夫第二个问题运算过程。维特比先生后来发明了CDMA技术并与人一起创办了高通公司&#xff0c;高通现在是通信巨头&#xff0c;不生产产品却每年收取大量的专利费。 下面我们用简单的例子&#xff…

Viterbi-Algorithm(维特比算法)

Viterbi-Algorithm 维特比算法是一个特殊但应用最广的动态规划算法。利用动态规划&#xff0c;可以解决任何一个图中的最短路径问题。而维特比算法是针对一个特殊的图-篱笆网了&#xff08;Lattice&#xff09;的有向图最短路径问题而提出来的。它之所以重要&#xff0c;是因为…

NLP学习笔记06-维特比算法

一序 本文属于NLP学习笔记系列。 上一篇整理了前向最大匹配算法与所有组合算法缺点&#xff08;时间复杂度太高了&#xff09;。 二 维特比算法 log(x*y*z) log(x)log(y)log(z) 概率上为了避免小数练乘出现的超范围溢出&#xff0c;改用log&#xff0c;改用-log,使得原来求概…

HMM-维特比算法

HMM-维特比算法&#xff08;viterbi&#xff09; HMM回顾隐马科夫链解法&#xff1a;维特比算法&#xff08;Viterbi&#xff09; HMM回顾 最终的公式可以解释主要分为两个部分&#xff1a; P(xi|yi)&#xff0c;发射概率&#xff0c;字面意思是从一个词性中发射/生成出某一个…

Viterbi算法(维特比算法)

维特比算法背景&#xff1a; 安德鲁维特比&#xff08;Andrew J. Viterbi&#xff09;&#xff0c;CDMA之父&#xff0c;IEEE Fellow&#xff0c;高通公司创始人之一&#xff0c;高通首席科学家。他开发了卷积码编码的最大似然算法而享誉全球。1991年香农奖&#xff08;Claude …

HMM+维特比算法

一、简介 Viterbi 算法 考虑到穷举方法的缺点&#xff0c;可以采用&#xff1a;Viterbi 算法: 动态搜索最优状态序列&#xff0c;这样每个节点保存的是到当前节点的局部最优概率&#xff1b;依据最后一个时刻中概率最高的状态&#xff0c;逆向找其路径中的上一个最大部分最优路…

维特比算法的java实现_原创:维特比算法

看了宗成庆博士的《统计自然语言处理(中文信息处理)》的第六章&#xff0c;对维特比算法有着非常精辟的讲解。把其中的讲解上传上来&#xff0c;个人感觉比较正统。 今天用Java实现了这个算法&#xff0c;也可以转换为C代码&#xff1a; package com.nlp.hmm.algorithm.viterbi…

隐马尔可夫(HMM)、前/后向算法、Viterbi算法 再次总结

本总结是是个人为防止遗忘而作&#xff0c;不得转载和商用。 说明&#xff1a;此篇是作者对“隐马尔可夫模型”的第二次总结&#xff0c;因此可以算作对上次总结的查漏补缺以及更进一步的理解&#xff0c;所以很多在第一次总结中已经整理过的内容在本篇中将不再重复&#xff0c…

维特比(Viterbi)算法

维特比算法 (Viterbi algorithm) 是机器学习中应用非常广泛的动态规划算法&#xff0c;在求解隐马尔科夫、条件随机场的预测以及seq2seq模型概率计算等问题中均用到了该算法。实际上&#xff0c;维特比算法不仅是很多自然语言处理的解码算法&#xff0c;也是现代数字通信中使用…