【图像处理】透视变换 Perspective Transformation

article/2025/10/3 21:03:20

透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。通用的变换公式为:


u,v是原始图片左边,对应得到变换后的图片坐标x,y,其中
变换矩阵可以拆成4部分,表示线性变换,比如scaling,shearing和ratotion。用于平移,产生透视变换。所以可以理解成仿射等是透视变换的特殊形式。经过透视变换之后的图片通常不是平行四边形(除非映射视平面和原来平面平行的情况)。

重写之前的变换公式可以得到:


所以,已知变换对应的几个点就可以求取变换公式。反之,特定的变换公式也能新的变换后的图片。简单的看一个正方形到四边形的变换:
变换的4组对应点可以表示成:

根据变换公式得到:


定义几个辅助变量:


都为0时变换平面与原来是平行的,可以得到:


不为0时,得到:


求解出的变换矩阵就可以将一个正方形变换到四边形。反之,四边形变换到正方形也是一样的。于是,我们通过两次变换:四边形变换到正方形+正方形变换到四边形就可以将任意一个四边形变换到另一个四边形。


看一段代码:

PerspectiveTransform::PerspectiveTransform(float inA11, float inA21, float inA31, float inA12, float inA22, float inA32, float inA13, float inA23, float inA33) : a11(inA11), a12(inA12), a13(inA13), a21(inA21), a22(inA22), a23(inA23),a31(inA31), a32(inA32), a33(inA33) {}PerspectiveTransform PerspectiveTransform::quadrilateralToQuadrilateral(float x0, float y0, float x1, float y1,float x2, float y2, float x3, float y3, float x0p, float y0p, float x1p, float y1p, float x2p, float y2p,float x3p, float y3p) {PerspectiveTransform qToS = PerspectiveTransform::quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3);PerspectiveTransform sToQ =PerspectiveTransform::squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p);return sToQ.times(qToS);
}PerspectiveTransform PerspectiveTransform::squareToQuadrilateral(float x0, float y0, float x1, float y1, float x2,float y2, float x3, float y3) {float dx3 = x0 - x1 + x2 - x3;float dy3 = y0 - y1 + y2 - y3;if (dx3 == 0.0f && dy3 == 0.0f) {PerspectiveTransform result(PerspectiveTransform(x1 - x0, x2 - x1, x0, y1 - y0, y2 - y1, y0, 0.0f,0.0f, 1.0f));return result;} else {float dx1 = x1 - x2;float dx2 = x3 - x2;float dy1 = y1 - y2;float dy2 = y3 - y2;float denominator = dx1 * dy2 - dx2 * dy1;float a13 = (dx3 * dy2 - dx2 * dy3) / denominator;float a23 = (dx1 * dy3 - dx3 * dy1) / denominator;PerspectiveTransform result(PerspectiveTransform(x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0, y1 - y0+ a13 * y1, y3 - y0 + a23 * y3, y0, a13, a23, 1.0f));return result;}
}PerspectiveTransform PerspectiveTransform::quadrilateralToSquare(float x0, float y0, float x1, float y1, float x2,float y2, float x3, float y3) {// Here, the adjoint serves as the inverse:return squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).buildAdjoint();
}PerspectiveTransform PerspectiveTransform::buildAdjoint() {// Adjoint is the transpose of the cofactor matrix:PerspectiveTransform result(PerspectiveTransform(a22 * a33 - a23 * a32, a23 * a31 - a21 * a33, a21 * a32- a22 * a31, a13 * a32 - a12 * a33, a11 * a33 - a13 * a31, a12 * a31 - a11 * a32, a12 * a23 - a13 * a22,a13 * a21 - a11 * a23, a11 * a22 - a12 * a21));return result;
}PerspectiveTransform PerspectiveTransform::times(PerspectiveTransform other) {PerspectiveTransform result(PerspectiveTransform(a11 * other.a11 + a21 * other.a12 + a31 * other.a13,a11 * other.a21 + a21 * other.a22 + a31 * other.a23, a11 * other.a31 + a21 * other.a32 + a31* other.a33, a12 * other.a11 + a22 * other.a12 + a32 * other.a13, a12 * other.a21 + a22* other.a22 + a32 * other.a23, a12 * other.a31 + a22 * other.a32 + a32 * other.a33, a13* other.a11 + a23 * other.a12 + a33 * other.a13, a13 * other.a21 + a23 * other.a22 + a33* other.a23, a13 * other.a31 + a23 * other.a32 + a33 * other.a33));return result;
}void PerspectiveTransform::transformPoints(vector<float> &points) {int max = points.size();for (int i = 0; i < max; i += 2) {float x = points[i];float y = points[i + 1];float denominator = a13 * x + a23 * y + a33;points[i] = (a11 * x + a21 * y + a31) / denominator;points[i + 1] = (a12 * x + a22 * y + a32) / denominator;}
}
对一张透视图片变换回正面图的效果:

int main(){Mat img=imread("boy.png");int img_height = img.rows;int img_width = img.cols;Mat img_trans = Mat::zeros(img_height,img_width,CV_8UC3);PerspectiveTransform tansform = PerspectiveTransform::quadrilateralToQuadrilateral(0,0,img_width-1,0,0,img_height-1,img_width-1,img_height-1,150,250, // top left771,0, // top right0,1023,// bottom left650,1023);vector<float> ponits;for(int i=0;i<img_height;i++){for(int j=0;j<img_width;j++){ponits.push_back(j);ponits.push_back(i);}}tansform.transformPoints(ponits);for(int i=0;i<img_height;i++){uchar*  t= img_trans.ptr<uchar>(i);for (int j=0;j<img_width;j++){int tmp = i*img_width+j;int x = ponits[tmp*2];int y = ponits[tmp*2+1];if(x<0||x>(img_width-1)||y<0||y>(img_height-1))continue;uchar* p = img.ptr<uchar>(y);t[j*3] = p[x*3];t[j*3+1] = p[x*3+1];t[j*3+2] = p[x*3+2];}}imwrite("trans.png",img_trans);return 0;
}




另外在OpenCV中也实现了基础的透视变换操作,有关函数使用请见下一篇: 【OpenCV】透视变换 Perspective Transformation(续)



(转载请注明作者和出处:http://blog.csdn.net/xiaowei_cqu 未经允许请勿用于商业用途)




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

相关文章

Opencv中的透视变换

唐宇迪视频学习笔记 def four_point_transform(image, pts):# 获取输入坐标点rect order_points(pts)(tl, tr, br, bl) rect# 计算输入的w和h值widthA np.sqrt(((br[0] - bl[0]) ** 2) ((br[1] - bl[1]) ** 2))widthB np.sqrt(((tr[0] - tl[0]) ** 2) ((tr[1] - tl[1])…

OpenCV中的透视变换介绍

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶” 重磅干货&#xff0c;第一时间送达本文转自&#xff1a;opencv学堂 透视变换原理 透视变换是将图像从一个视平面投影到另外一个视平面的过程&#xff0c;所以透视变换也被称为投影映射&#xff08;Project…

仿射变换和透视变换

透视变换 1. 欧式变换2. 相似变换3. 仿射变换4. 射影变换/透视变换概念OpenCV 实现 3D 空间存在集中变换方式。 1. 欧式变换 欧式变换保持了向量的长度和夹角&#xff0c;相当于我们把一个刚体原封不动地进行了移动或旋转&#xff0c;不改变它自身的样子&#xff0c;其矩阵表…

基于OpenCV的图像透视变换详解(从理论到实现再到实践)

一、仿射变换与透视变换 一直无法理解两种仿射变换与透视变换的区别&#xff0c;因此详细学习了两种变换的具体细节&#xff0c;重新书写了公式&#xff0c;并给出自己的一些看法。 1.仿射变换 可以认为&#xff0c;仿射变换是透视变换的一种特例。 仿射变换是一种二维坐标到二…

透视变换(perspective transformation)

透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane)&#xff0c;也称作投影映射(Projective Mapping)。如下图所示 透视变换 透视变换的原理和公式推导见如下博客 【图像处理】透视变换 Perspective Transformation 【OpenCV】透视变换 Perspe…

OpenCV 透视变换

OpenCV 透视变换 1. 简介2. 仿射变换2.1. 平移2.2. 旋转2.3. 放缩2.4. 错切2.5. 仿射变换 3. 透视变换 1. 简介 汽车的360度全景影像&#xff0c;从拍照视角变成鸟瞰图 这种变换常常用到透视变换 在了解透视变换前&#xff0c;需要了解一下其他的变换&#xff0c;包括 平移&am…

深入探索透视投影变换

深入探索透视投影变换 最近更新&#xff1a;2013年11月22日 -Twinsen编写 -本人水平有限&#xff0c;疏忽错误在所难免&#xff0c;还请各位数学高手、编程高手不吝赐教 -email: popyynetease.com -B站专栏&#xff1a; https://b23.tv/oWsl6PD 透视投影是3D固定流水线的重要组…

图像透视变换原理及实现

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

(十四)透视变换

透视变换(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…