ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

射影几何与透视单应性矩阵(Homography Matrix):前端四点畸变矫正

射影几何与透视单应性矩阵(Homography Matrix):前端四点畸变矫正 射影几何与透视单应性矩阵Homography Matrix前端四点畸变矫正在计算机视觉Computer Vision、文档扫描识别 App如扫描全能王、以及网页端先锋 3D 投影海报映射中“四点透视畸变矫正Perspective Rectification / Four-point Distortion Correction”是一项极其经典且高难度的几何算法用户斜着用手机对着桌上的合同发票拍了一张照片由于摄像机透视视角照片里的矩形合同变成了一个不规则的梯形/任意四边形用户在屏幕上拖动四个角点Top-Left, Top-Right, Bottom-Right, Bottom-Left系统瞬间将这个倾斜扭曲的四边形以像素级平滑的透视投影“拉直拍平”为一个方方正正的正向高清矩形在射影几何学Projective Geometry中连接两个不同平面透视投影的至高数学桥梁被称为单应性矩阵Homography Matrix / $3 \times 3$ 射影变换。本文将深入推导单应性矩阵的直接线性变换算法DLT并在纯 TypeScript 与 Canvas/CSSmatrix3d()中手写一个零外部依赖的四点透视畸变矫正引擎单应性变换的射影几何方程在二维齐次坐标系中设源平面上的任意一点为 $\mathbf{p} [x, y, 1]^T$经过透视变换后在目标平面上的投影坐标为 $\mathbf{p} [x, y, 1]^T$。两者通过一个 $3 \times 3$ 的单应性矩阵 $\mathbf{H}$ 线性相连相差一个非零尺度因子 $s$$$s \begin{bmatrix} x \ y \ 1 \end{bmatrix} \mathbf{H} \begin{bmatrix} x \ y \ 1 \end{bmatrix} \begin{bmatrix} h_{00} h_{01} h_{02} \ h_{10} h_{11} h_{12} \ h_{20} h_{21} h_{22} \end{bmatrix} \begin{bmatrix} x \ y \ 1 \end{bmatrix}$$展开齐次坐标并消除尺度因子 $s$齐次除法$$x \frac{h_{00} x h_{01} y h_{02}}{h_{20} x h_{21} y h_{22}}, \quad y \frac{h_{10} x h_{11} y h_{12}}{h_{20} x h_{21} y h_{22}}$$[源梯形四边形: 4 个顶点 (xi, yi)] │ ▼ (直接线性变换 DLT: 构建 8x8 线性方程组 A·h 0) [求解 3x3 单应性矩阵 H (8 个独立自由度)] │ ▼ (转换为 CSS matrix3d 或 Canvas 双线性纹理映射) [瞬间拉平为正向完美矩形 (0, 0) - (W, H)]直接线性变换算法DLT求解 8 自由度参数由于矩阵 $\mathbf{H}$ 具有整体尺度等价性我们令 $h_{22} 1$8 个未知数。每一个点对 $(\mathbf{p}_i \leftrightarrow \mathbf{p}_i)$ 可以提供两个独立的线性方程$$\begin{cases}x_i h_{00} y_i h_{01} h_{02} - x_i xi h{20} - y_i xi h{21} xi \x_i h{10} y_i h_{11} h_{12} - x_i yi h{20} - y_i yi h{21} y_i\end{cases}$$四对对应顶点恰好提供 $4 \times 2 8$ 个方程构成一个确定性的 $8 \times 8$ 线性方程组 $\mathbf{A} \mathbf{h} \mathbf{b}$利用高斯消元法Gaussian Elimination即可在 0.1ms 内精确求解TypeScript 纯数学单应性矩阵求解引擎// homography-solver.ts export type Point2D { x: number; y: number }; export class HomographySolver { // 求解高斯消元法 private static solveGaussian(A: number[][], b: number[]): number[] { const n b.length; for (let i 0; i n; i) { // 寻找主元 let maxEl Math.abs(A[i][i]); let maxRow i; for (let k i 1; k n; k) { if (Math.abs(A[k][i]) maxEl) { maxEl Math.abs(A[k][i]); maxRow k; } } // 交换行 for (let k i; k n; k) { const tmp A[maxRow][k]; A[maxRow][k] A[i][k]; A[i][k] tmp; } const tmpB b[maxRow]; b[maxRow] b[i]; b[i] tmpB; // 消元 for (let k i 1; k n; k) { const c -A[k][i] / A[i][i]; for (let j i; j n; j) { if (i j) A[k][j] 0; else A[k][j] c * A[i][j]; } b[k] c * b[i]; } } // 回代求解 const x new Array(n).fill(0); for (let i n - 1; i 0; i--) { x[i] b[i] / A[i][i]; for (let k i - 1; k 0; k--) { b[k] - A[k][i] * x[i]; } } return x; } // 输入 4 对顶点求解 3x3 单应性矩阵 [h00, h01, h02, h10, h11, h12, h20, h21, 1] public static findHomography(src: Point2D[], dst: Point2D[]): number[] { const A: number[][] []; const b: number[] []; for (let i 0; i 4; i) { const { x, y } src[i]; const { x: u, y: v } dst[i]; A.push([x, y, 1, 0, 0, 0, -x * u, -y * u]); b.push(u); A.push([0, 0, 0, x, y, 1, -x * v, -y * v]); b.push(v); } const h8 this.solveGaussian(A, b); return [h8[0], h8[1], h8[2], h8[3], h8[4], h8[5], h8[6], h8[7], 1.0]; } // 将 3x3 单应性矩阵映射为 CSS 4x4 matrix3d 字面量 public static toCssMatrix3D(H: number[]): string { // 映射齐次三维变换矩阵 const a1 H[0], b1 H[3], d1 H[6]; const a2 H[1], b2 H[4], d2 H[7]; const a4 H[2], b4 H[5], d4 H[8]; return matrix3d( ${a1.toFixed(6)}, ${b1.toFixed(6)}, 0, ${d1.toFixed(6)}, ${a2.toFixed(6)}, ${b2.toFixed(6)}, 0, ${d2.toFixed(6)}, 0, 0, 1, 0, ${a4.toFixed(6)}, ${b4.toFixed(6)}, 0, ${d4.toFixed(6)} ); } }生产实战四点拖拽透视矫正交互体验// 业务驱动示例 const srcQuad: Point2D[] [ { x: 40, y: 80 }, // Top-Left (梯形偏左) { x: 320, y: 40 }, // Top-Right { x: 360, y: 260 }, // Bottom-Right { x: 20, y: 220 }, // Bottom-Left ]; const targetRect: Point2D[] [ { x: 0, y: 0 }, { x: 300, y: 0 }, { x: 300, y: 200 }, { x: 0, y: 200 }, ]; // 求解透视矩阵 const H HomographySolver.findHomography(srcQuad, targetRect); const cssMatrix HomographySolver.toCssMatrix3D(H); // 提交给 DOM 执行 GPU 硬件级透视展开 const imageElement document.getElementById(distortedDocument)!; imageElement.style.transformOrigin 0 0; imageElement.style.transform cssMatrix;总结单应性矩阵是射影几何学赐予计算机图形学最锋利的几何解剖刀。看透 8 自由度线性方程的直接代数求解机制将复杂的图像透视畸变无损映射为标准的 CSSmatrix3d()硬件变换你就能在纯浏览器前端以零重型三方库的极致轻盈打造出媲美专业扫描软件的顶级四点透视矫正与高维图形映射体验。
返回列表