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):
- 仿射不变:三点共线仍共线;两线平行仍平行;一条线上线段的长度比不变;任意区域面积比恒定(等于 ∣detA∣|\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=(acbd),平移 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} 100010txty1 cosθsinθ0−sinθcosθ0001 sx000sy0001 100k10001
- 平移贡献 2 自由度(tx,tyt_x,t_ytx,

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

被折叠的 条评论
为什么被折叠?



