OpenCV 仿射变换与透视变换

本文系统讲解OpenCV中仿射变换(6自由度,保平行/长度比/面积比)与透视变换(8自由度,保直线与交比,引入灭点)的数学原理、自由度分解、DLT求解方法(3点解仿射、4点解透视)、坐标正规化(Hartley 1997)及数值稳定性要点;深入剖析OpenCV API三大陷阱:尺寸顺序(宽高 vs 高宽)、正变换传参(内部自动求逆)、插值与边界模式选择;并提供旋转不裁剪、文档扫描矫正、仿射配准等可运行实战代码。

0 · 导读:为什么是这两种变换

几何变换的本质是给每个像素坐标 (x,y)(x,y)(x,y) 找一个新位置 (x′,y′)(x',y')(x′,y′)。按「保真度」从强到弱,图像变换有一个阶梯:

变换 自由度 保什么 不保什么 OpenCV 主力函数
欧氏(刚体) 3 长度、角度、平行 — getRotationMatrix2D
仿射 affine 6 共线、平行、距离比、面积比 角度、长度 getAffineTransform / warpAffine
透视 perspective 8 共线、直线、交比 平行、距离比、面积比 getPerspectiveTransform / warpPerspective
投影(一般 3D) 15 直线 几乎都不保 需 3D 管线

一句话定位:仿射是「平面内的任意刚体运动 + 非均匀缩放 + 剪切」,它强制平行线仍然平行;透视是「把平面以任意角度摆到相机前」,平行线会汇聚到灭点——这正是人眼透视感的来源,也是文档扫描、车牌识别、AR 贴图的全部数学基础。

全文路线图:§1 把保真度阶梯钉死 → §2 仿射的 6 自由度分解 → §3 透视的 8 自由度与灭点 → §4 从对应点求解(DLT,函数背后在算什么)→ §5 API 参数陷阱 → §6 三个实战(旋转不裁剪 / 文档扫描 / 仿射配准)→ §7 常见错误清单 → §8 性能与内存。


1 · 几何变换的「保真度」阶梯

理解两种变换,最该记住的是不变量(invariant):

  • 仿射不变:三点共线仍共线;两线平行仍平行;一条线上线段的长度比不变;任意区域面积比恒定(等于 ∣det⁡A∣|\det A|∣detA∣);线段中点仍是中点。
  • 透视不变:只有「共线 → 共线」(直线仍是直线)和「四点共线时的交比 cross-ratio」不变。平行、长度比、面积比全丢。

用一个直觉判断该用谁:如果你能假设物体在「无限远平面」上、相机正对它(无透视倾斜),用仿射;如果物体在地面上、相机俯拍、或者是一张被斜着拍的纸,必须上透视。

交互版 W1/W2 把这条直接画出来:W1 用滑块调仿射(旋转/缩放/剪切),看单位方格如何变平行四边形却始终保平行;W2 拖拽 4 个角做透视,看原本平行的线如何汇聚到灭点,而交比滑块显示四个共线点的距离比如何被保持。


2 · 仿射变换(affine):6 自由度

2.1 矩阵形式

仿射用 2×32\times32×3 矩阵表示(OpenCV 的标准输出),齐次下是 3×33\times33×3:

在这里插入图片描述

式中线性部分 A=(abcd)A=\begin{pmatrix}a&b\\c&d\end{pmatrix}A=(ac​bd​),平移 t=(ef)\mathbf{t}=\begin{pmatrix}e\\f\end{pmatrix}t=(ef​)。

6 个未知数 { a,b,c,d,e,f}\{a,b,c,d,e,f\}{ a,b,c,d,e,f} → 6 自由度。

2.2 6 自由度的几何分解

AAA 可分解为「平移 · 旋转 · 缩放 · 剪切」四个矩阵的乘积(自左向右依次作用):

[10tx01ty001][cos⁡θ−sin⁡θ0sin⁡θcos⁡θ0001][sx000sy0001][1k0010001] \begin{bmatrix}1&0&t_x\\0&1&t_y\\0&0&1\end{bmatrix} \begin{bmatrix}\cos\theta&-\sin\theta&0\\\sin\theta&\cos\theta&0\\0&0&1\end{bmatrix} \begin{bmatrix}s_x&0&0\\0&s_y&0\\0&0&1\end{bmatrix} \begin{bmatrix}1&k&0\\0&1&0\\0&0&1\end{bmatrix} ​100​010​tx​ty​1​ ​ ​cosθsinθ0​−sinθcosθ0​001​ ​ ​sx​00​0sy​0​001​ ​ ​100​k10​001​ ​

  • 平移贡献 2 自由度(tx,tyt_x,t_ytx​,
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

reset2021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值