第 2 章 图像数字化:采样与量化
学习目标:彻底搞懂”连续图像 → 数字图像”的每一步数学过程。 本章公式最多、但最重要——所有后续操作(缩放、FFT、重采样、配准)都依赖本章。
2.1 从连续到离散:整体框架
一幅自然光学图像是连续的——在空间上连续、在幅度上连续。要送入计算机,必须做两步离散化:
连续图像 f(x, y) │ │ ① 空间采样:对 (x, y) 离散化 ▼采样图像 f(m·Δx, n·Δy), m, n ∈ ℤ │ │ ② 幅度量化:对 f 的值离散化 ▼数字图像 f[m, n] ∈ {0, 1, ..., L-1}两步可以互换,结果相同。历史上先采样后量化,这是硬件管线的自然顺序。
易混概念警告:
- 采样:决定 “多少像素”(空间分辨率)
- 量化:决定 “每像素多少级”(灰度分辨率)
- 两者独立但共同决定图像总信息量。
2.2 空间采样 (Sampling)
2.2.1 一维采样回顾
设连续信号 (f(t)),以间隔 (T_s) 采样,得到离散序列 (f(nT_s))。
用冲激串描述这个操作: [ s_T(t) = \sum_{n=-\infty}^{\infty} \delta(t - nT_s) ] 采样结果: [ f_s(t) = f(t) \cdot s_T(t) = \sum_{n} f(nT_s) \delta(t - nT_s) ]
2.2.2 采样的频谱(核心推导)
冲激串 (s_T(t)) 的傅里叶变换: [ S(u) = \frac{1}{T_s} \sum_{k=-\infty}^{\infty} \delta\left(u - \frac{k}{T_s}\right) ] (提示:周期冲激串 FT 仍是冲激串,间隔 (1/T_s),幅值 (1/T_s))
由乘积→卷积定理: [ F_s(u) = F(u) * S(u) = \frac{1}{T_s}\sum_{k} F\left(u - \frac{k}{T_s}\right) ]
几何解释:原频谱 (F(u)) 被复制到每个采样频率 (k f_s)((f_s = 1/T_s))的整数倍上。
原频谱 F(u) 采样后 F_s(u) ▲ ▲ │ ∧ │ ∧ ∧ ∧ ∧ │╱ ╲ │╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ┼──────> u ┼─────────────────> u -W 0 W -f_s 0 f_s 2f_s2.2.3 Nyquist-Shannon 采样定理
定理:若 (f(t)) 频谱 (F(u) = 0) 对所有 (|u| \geq W)(带限),则只要 [ f_s \geq 2W, \quad \text{即} \quad T_s \leq \frac{1}{2W} ] 采样序列 ({f(nT_s)}) 可完美重建原信号。
(2W) 称为奈奎斯特率。
几何解释:只要相邻频谱副本不重叠,就能用理想低通 (H(u) = T_s) (\mathbf{1}_{[-W, W]}) 取出中心副本 → IFT 得到原信号。
2.2.4 混叠 (Aliasing)
若 (f_s < 2W),相邻频谱副本重叠:
∧ ∧ ∧ 发生重叠→╱ ╲ ╱ ╲ ╱ ╲ 无法分离原频谱 ╲╱ ╲╱高频 (u) 会”折叠”到低频位置,造成虚假低频——这就是混叠。
公式化:采样后观察到的频率 [ u_{\text{obs}} = u_{\text{true}} \bmod f_s, \quad \text{若 } u_{\text{true}} > f_s/2 ]
典型现象:
- 摩尔纹 (Moiré):拍摄屏幕、条纹衬衫出现彩色干涉纹
- 锯齿 (Jaggies):斜线边缘出现阶梯
- 轮辐逆转:电影中车轮看起来倒转
- 视频闪烁:高频细节在下采样时跳变
2.2.5 抗混叠低通滤波 (Anti-Aliasing)
解决办法:在采样之前用低通滤波器切掉高于 (f_s/2) 的分量。
连续信号 ── LPF(截止 f_s/2) ── 采样 ── 数字信号 ↑ 抗混叠滤波手机摄像头:
- 光学抗混叠滤波片(OLPF,镜头前)
- 传感器的像素大小本身就是一种积分(=矩形低通)
OpenCV 中的 INTER_AREA:下采样时内部先做区域平均(即低通),然后采样——这是唯一在下采样时抗混叠的插值。
2.2.6 二维采样(图像)
直接推广: [ f_s(x, y) = f(x, y) \cdot \sum_{m, n} \delta(x - m\Delta x, y - n\Delta y) ] 频域:二维频谱按 ((1/\Delta x, 1/\Delta y)) 间隔复制。
二维 Nyquist: [ \Delta x \leq \frac{1}{2 u_{\max}}, \quad \Delta y \leq \frac{1}{2 v_{\max}} ]
2.2.7 数值例子
例 2.1:一幅 A4 纸扫描件,最高空间频率 200 周/英寸。问:扫描分辨率至少多少 DPI?
答:需 (f_s \geq 2 \times 200 = 400) 样本/英寸 → 至少 400 DPI。 实际办公打印一般 300 DPI——对纯文本够用(文字最高空间频率约 150 周/英寸),对条纹插图就会出现摩尔纹。
例 2.2:某相机传感器 4000×3000 像素,拍摄 10 米远宽 2 米的物体。问可分辨的最小物体尺度?
答:每像素对应 2 m / 4000 = 0.5 mm(水平方向)。Nyquist 告诉我们:可分辨的最小条纹周期约为 2 倍采样间隔 = 1 mm,即约 1 个 line pair per mm。
2.3 幅度量化 (Quantization)
2.3.1 均匀量化
将连续幅度范围 ([f_{\min}, f_{\max}]) 等分为 (L = 2^k) 个子区间,每个子区间用一个代表值(通常是中点)。
量化函数: [ q(f) = \text{round}\left( \frac{f - f_{\min}}{f_{\max} - f_{\min}} \cdot (L - 1) \right) ]
量化步长: [ \Delta = \frac{f_{\max} - f_{\min}}{L} = \frac{f_{\max} - f_{\min}}{2^k} ]
2.3.2 量化误差与 SNR
量化误差 (e = f - \hat{f}) 满足 (|e| \leq \Delta/2)。
假设 (e) 在 ([-\Delta/2, \Delta/2]) 均匀分布(对高斯等复杂分布成立),则 [ \sigma_e^2 = \int_{-\Delta/2}^{\Delta/2} e^2 \cdot \frac{1}{\Delta} de = \frac{\Delta^2}{12} ]
信号峰峰值为 (L\Delta),若信号振幅为 (A = L\Delta/2),则信号功率 (\sigma_s^2 = A^2/2 = L^2\Delta^2/8)(正弦信号)。
量化 SNR: [ \text{SNR}{dB} = 10 \log{10} \frac{\sigma_s^2}{\sigma_e^2} = 10 \log_{10} \frac{L^2 \Delta^2 / 8}{\Delta^2/12} = 10\log_{10}(1.5 L^2) ] [ = 10\log_{10}(1.5) + 20\log_{10}(2^k) \approx 1.76 + 6.02k \text{ dB} ]
记住一句话:每增加 1 bit,量化 SNR 提升约 6 dB。
数值感:
| k | L | SNR (dB) |
|---|---|---|
| 1 | 2 | 7.78 |
| 4 | 16 | 25.84 |
| 8 | 256 | 49.92 |
| 10 | 1024 | 61.96 |
| 12 | 4096 | 74.00 |
| 16 | 65536 | 98.08 |
8-bit 相当于约 50 dB SNR——比自然光学噪声(一般 40 dB)还干净,所以 8-bit 对消费照片足够。但 HDR、医学要更高。
2.3.3 非均匀量化
真实信号分布往往非均匀,统一步长浪费比特。
Lloyd-Max 量化器:给定分布 (p(f)),最优量化器满足:
- 决策边界:(b_i = (\hat{f}_{i-1} + \hat{f}_i) / 2)
- 代表值:(\hat{f}i = E[f \mid f \in (b{i-1}, b_i)])
即”代表值在各区间的条件均值,边界在相邻代表值的中点”。迭代求解。
对数/μ 律量化:语音、亮度等服从”小信号概率高”的分布,对数压缩后再均匀量化,等效于暗部细、亮部粗。
示例:相机的 Log Gamma 曲线(S-Log、Log-C)—本质就是非均匀量化,让后期宽容度更大。
2.3.4 伪轮廓 (False Contour / Banding)
位深不足 → 本应平滑的过渡区出现条带状阶梯:
实际场景 6-bit 量化后 渐变天空 天空变成宽阶梯 ░░▒▒▓▓██ ░░░░▒▒▒▒▓▓▓▓████2.3.5 抖动 (Dithering) 去伪轮廓
在量化前故意加噪声,把量化误差打散到不同空间位置:
Floyd-Steinberg 误差扩散:量化当前像素 → 把量化误差按权重扩散到右、下、右下邻居:
* 7/16 3/16 5/16 1/16扩散后重新量化邻居,形成”像素级的半色调”——这是打印机和 GIF 都在用的技巧。
# skimage 实现from skimage.filters import threshold_otsufrom skimage.color import rgb2grayfrom skimage import img_as_ubyteimport numpy as np
def floyd_steinberg(img): a = img.astype(np.float32).copy() h, w = a.shape for y in range(h): for x in range(w): old = a[y, x] new = round(old / 255) * 255 a[y, x] = new err = old - new if x+1 < w: a[y, x+1] += err * 7/16 if y+1 < h: if x > 0: a[y+1, x-1] += err * 3/16 a[y+1, x] += err * 5/16 if x+1 < w: a[y+1, x+1] += err * 1/16 return np.clip(a, 0, 255).astype(np.uint8)2.3.6 位平面分解
任意灰度值 (f \in {0, \ldots, 255}) 可分解为 8 个二进制位: [ f = b_7 \cdot 128 + b_6 \cdot 64 + \cdots + b_1 \cdot 2 + b_0 ]
把每个位 (b_k) 作为一幅二值图,称为位平面。
- 高位平面((b_6, b_7)):主要结构
- 低位平面((b_0, b_1)):细节 + 噪声
应用:数字水印(藏在低位平面不易察觉)、压缩(JPEG2000 的 EBCOT 就是位平面编码)。
2.4 空间与灰度分辨率
2.4.1 分辨率的四种含义
| 类型 | 单位 | 决定 |
|---|---|---|
| 空间分辨率 | pixels, dpi, ppi, μm/px | 能分辨的最小几何细节 |
| 灰度分辨率 | levels, bit/pixel | 能分辨的最小灰度差 |
| 时间分辨率 | fps, Hz | 能分辨的最快变化 |
| 光谱分辨率 | nm/bin | 能分辨的最小波长差 |
2.4.2 空间与灰度的权衡
Huang 经典实验 (1965):在总 bit 预算 (M \times N \times k) 恒定下,改变 (M, N, k),看人主观评价。
结论:
- 典型自然图像,灰度先降到 16 级就出现明显伪轮廓
- 空间分辨率降到原来一半,主体仍可识别
- 优先分配 bit 给灰度通常更划算
反例:文字、线条图(二值内容),灰度只需 2 级就够,应优先空间分辨率。
2.4.3 视觉分辨率(dpi 与 ppi)
- dpi (dots per inch):打印机墨点密度
- ppi (pixels per inch):屏幕/图像像素密度
- 人眼25 cm 观看距离可分辨约 300 ppi(视力 1.0,1 arcmin)——所以 Retina 屏 330+ ppi 被称为”视网膜级”
2.5 图像插值 (Interpolation)
缩放、旋转、配准本质都是”在非整数坐标查图像值”——必须插值。
2.5.1 前向 vs 后向映射(务必理解)
假设变换 (T: (x, y) \mapsto (x’, y’))。
前向映射:对每个源像素 ((x, y)) 算出目标位置 ((x’, y’)),把值”推”过去。 问题:
- 目标像素可能被多次写入(重叠)
- 也可能无像素写入(空洞)
后向映射(工业标准):对每个目标像素 ((x’, y’)),用 (T^{-1}) 查源坐标 ((x, y)),查值放到目标。
- 每个目标像素一定被写入一次
- 源坐标非整数 → 用插值
# OpenCV 默认就是后向映射dst = cv2.warpAffine(src, M, dsize)2.5.2 最近邻插值
[ \hat{f}(x, y) = f(\text{round}(x), \text{round}(y)) ]
- 最快,无浮点
- 不引入新值(保留离散标签)
- 缺点:严重锯齿、马赛克
应用场景:分割标签图、掩膜、索引图——绝对不能引入新”类别”值。
2.5.3 双线性插值 (Bilinear)
用 ((x, y)) 周围 4 个整数像素,按距离线性加权。
记 (i = \lfloor x \rfloor, j = \lfloor y \rfloor, u = x - i, v = y - j),则: [ \hat{f}(x, y) = (1-u)(1-v) f(i, j) + u(1-v) f(i+1, j) + (1-u)v , f(i, j+1) + uv , f(i+1, j+1) ]
两步推导:
- 行方向线性插: (f_1 = (1-u) f(i, j) + u , f(i+1, j)) (f_2 = (1-u) f(i, j+1) + u , f(i+1, j+1))
- 列方向线性插: (\hat{f} = (1-v) f_1 + v f_2)
数值例子:在 (x=0.3, y=0.7) 处插值,邻域像素值:
f(0, 0)=100 f(1, 0)=200f(0, 1)=50 f(1, 1)=150按公式: [ \hat{f} = 0.7 \cdot 0.3 \cdot 100 + 0.3 \cdot 0.3 \cdot 200 + 0.7 \cdot 0.7 \cdot 50 + 0.3 \cdot 0.7 \cdot 150 ] [ = 21 + 18 + 24.5 + 31.5 = 95 ]
特点:
- 连续(但一阶导数不连续 → 肉眼轻微”模糊”)
- 速度快
- 默认选择
2.5.4 双三次插值 (Bicubic)
用 ((x, y)) 周围 4×4 = 16 个像素,三次多项式加权: [ W(t) = \begin{cases} (a+2)|t|^3 - (a+3)|t|^2 + 1 & |t| < 1 \ a|t|^3 - 5a|t|^2 + 8a|t| - 4a & 1 \leq |t| < 2 \ 0 & \text{其他} \end{cases} ]
常用 (a = -0.5)(Catmull-Rom),也有 (a = -0.75)(OpenCV INTER_CUBIC)。
好处:
- 一阶导数连续 → 视觉更锐利
- 能轻微锐化(负的旁瓣)
- 照片放大的默认选择
2.5.5 Lanczos 插值
理论上的”理想重构”是用 sinc 函数——但 sinc 无限长,不可实现。Lanczos 窗把 sinc 截断并加平滑窗: [ L(x) = \text{sinc}(x) \cdot \text{sinc}(x/a) \quad |x| < a ] 常取 (a = 2) 或 (3) 即 Lanczos-2 / Lanczos-3。
支持 6×6 或 8×8 邻域,比 bicubic 更锐但有轻微振铃。适合极致清晰度放大。
2.5.6 插值方法对比
| 方法 | 邻域 | 计算 | 质量 | 推荐 |
|---|---|---|---|---|
| 最近邻 | 1 | 最快 | 差(锯齿) | 标签图 |
| 双线性 | 4 | 快 | 中(轻模糊) | 默认 |
| 双三次 | 16 | 中 | 好 | 照片放大 |
| Lanczos | 36~64 | 慢 | 最好 | 高质量 |
| INTER_AREA | 可变 | 中 | 下采样最佳 | 缩小 |
经验规则:
- 放大用
INTER_CUBIC或INTER_LANCZOS4 - 缩小用
INTER_AREA(抗混叠) - 掩膜/标签用
INTER_NEAREST
2.5.7 缩放时为什么先模糊?
下采样 = 降低采样频率 → 必须先切掉高于新 Nyquist 的频率:
原图 → Gaussian blur (σ ∝ 缩放比) → 下采样cv2.pyrDown 内部就是这样做的。直接 cv2.resize(..., INTER_LINEAR) 放大后下采样会混叠;INTER_AREA 则内部做区域平均。
2.6 几何变换
2.6.1 齐次坐标 (Homogeneous Coordinates)
2D 点 ((x, y)) 扩展为 ((x, y, 1))。好处:所有变换(包括平移)都能写成矩阵乘法,方便级联。
反向变换:((x, y, w) \to (x/w, y/w))。
2.6.2 刚体变换(旋转 + 平移)
[ \begin{bmatrix} x’ \ y’ \ 1 \end{bmatrix} = \begin{bmatrix} \cos\theta & -\sin\theta & t_x \ \sin\theta & \cos\theta & t_y \ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \ y \ 1 \end{bmatrix} ] 自由度 (DoF) = 3((\theta, t_x, t_y))。保距、保角。
2.6.3 相似变换(刚体 + 各向同性缩放)
[ M = \begin{bmatrix} s\cos\theta & -s\sin\theta & t_x \ s\sin\theta & s\cos\theta & t_y \ 0 & 0 & 1 \end{bmatrix} ] DoF = 4。保角、不保距。
2.6.4 仿射变换
[ M = \begin{bmatrix} a_{11} & a_{12} & t_x \ a_{21} & a_{22} & t_y \ 0 & 0 & 1 \end{bmatrix} ] DoF = 6。保直线、保平行、保面积比,但不保角。
分解:任意仿射可分解为 “平移 × 旋转 × 剪切 × 缩放”。
常用特例:
| 变换 | 矩阵 |
|---|---|
| 平移 | (\begin{bmatrix} 1&0&t_x \ 0&1&t_y \ 0&0&1 \end{bmatrix}) |
| 缩放(锚点原点) | (\begin{bmatrix} s_x&0&0 \ 0&s_y&0 \ 0&0&1 \end{bmatrix}) |
| 旋转(锚点原点) | (\begin{bmatrix} \cos\theta&-\sin\theta&0 \ \sin\theta&\cos\theta&0 \ 0&0&1 \end{bmatrix}) |
| x 方向剪切 | (\begin{bmatrix} 1&s&0 \ 0&1&0 \ 0&0&1 \end{bmatrix}) |
| 水平翻转 | (\begin{bmatrix} -1&0&W \ 0&1&0 \ 0&0&1 \end{bmatrix}) |
绕非原点旋转: [ M = T(c) \cdot R(\theta) \cdot T(-c) ] 即”平移到原点 → 旋转 → 平移回去”。OpenCV 直接封装为:
M = cv2.getRotationMatrix2D(center, angle, scale) # 2x3仿射求解:3 对点可唯一确定(6 方程 6 未知)。
M = cv2.getAffineTransform(src_3pts, dst_3pts)2.6.5 透视/投影变换 (Homography)
[ \begin{bmatrix} x’w \ y’w \ w \end{bmatrix} = \begin{bmatrix} h_{11}&h_{12}&h_{13} \ h_{21}&h_{22}&h_{23} \ h_{31}&h_{32}&h_{33} \end{bmatrix} \begin{bmatrix} x \ y \ 1 \end{bmatrix} ]
关键区别:最后一行不是 ((0, 0, 1)),意味着 (w) 可以变化——不保持平行性!
DoF = 8(9 个元素减归一化)。4 对点可解。
不变量:保直线、保交比 (cross-ratio)。
典型应用:
- 文档扫描矫正(拍斜了的纸张)
- 车牌正视图
- 运动场广告替换
- 全景拼接
- 无人机航拍图正射
H = cv2.getPerspectiveTransform(src_4pts, dst_4pts)rect = cv2.warpPerspective(img, H, (W, H))2.6.6 变换层次总结
欧氏(3) ⊂ 相似(4) ⊂ 仿射(6) ⊂ 投影(8)保距 保角 保平行 保直线每增加一层,保留的几何性质减少,但能建模的变形增加。
2.6.7 数值例子:文档矫正
一张拍歪的 A4 纸,4 个角被检测到:
src = [(100, 80), (500, 120), (480, 720), (80, 680)] # 拍摄中的四角dst = [(0, 0), (600, 0), (600, 800), (0, 800)] # 要映射到 600×800 矩形H = cv2.getPerspectiveTransform( np.float32(src), np.float32(dst))out = cv2.warpPerspective(img, H, (600, 800))out 就是正视图——这是”手机扫描 App”的核心算法。
2.7 插值 + 几何变换 实战要点
- 变换后像素落在非整数坐标 → 插值
- 图像边界外的查询 → 边界处理(0 填充、镜像、复制边缘)
cv2.warpAffine(..., borderMode=cv2.BORDER_REFLECT_101)
- 旋转导致新图像尺寸变化 → 可能需要扩大画布:
(h, w) = img.shape[:2]M = cv2.getRotationMatrix2D((w/2, h/2), 30, 1.0)cos, sin = abs(M[0,0]), abs(M[0,1])nW = int(h*sin + w*cos)nH = int(h*cos + w*sin)M[0, 2] += (nW/2 - w/2)M[1, 2] += (nH/2 - h/2)rot = cv2.warpAffine(img, M, (nW, nH))
2.8 本章速查表
| 主题 | 公式/要点 |
|---|---|
| 采样定理 | (f_s \geq 2W) |
| 抗混叠 | 采样前做低通 |
| 量化 SNR | (\approx 6.02k + 1.76) dB |
| 量化误差方差 | (\Delta^2 / 12) |
| 双线性插值 | 4 邻域、((1-u)(1-v), \ldots, uv) 加权 |
| 双三次插值 | 16 邻域、三次多项式权重 |
| 仿射自由度 | 6,3 对点解 |
| 透视自由度 | 8,4 对点解 |
| 齐次坐标 | ((x, y) \to (x, y, 1)) |
2.9 本章要点与面试考点
✅ 必须掌握
- 采样定理的完整推导(冲激串 → 频谱复制 → 不重叠条件)
- 混叠的成因与实例
- 量化 SNR 公式 (6.02k + 1.76)
- 空间 / 灰度分辨率权衡
- Floyd-Steinberg 误差扩散原理
- 前向 / 后向映射,为什么选后向
- 双线性、双三次插值的公式与应用场景
-
INTER_AREA在下采样为什么最合适 - 齐次坐标 + 仿射 / 透视变换矩阵
- 计算点阵对应数:仿射 3 点、透视 4 点
💡 高频面试题
Q1. 为什么 1024×1024 图像的 FFT 尺寸一般选 2048?
答:防止循环卷积的混叠/边界效应。DFT 把信号当作周期延拓,长度 N 的线性卷积结果长度为 (2N - 1),需至少零填充到 (\geq 2N - 1),取 2 的幂故选 2048。
Q2. 下采样 2× 时,为什么 INTER_AREA 效果最好?
答:INTER_AREA 相当于对 2×2 区域求均值——这是一个 2×2 的低通滤波器,先抑制高于新 Nyquist 的频率,再隔点采样。INTER_LINEAR 只取 2×2 加权,没有抗混叠作用。
Q3. 为什么仿射只有 6 自由度、透视却有 8?
答:
- 仿射变换:2×2 线性部分(4 参数) + 2 维平移 = 6 DoF
- 透视变换:3×3 矩阵 9 参数,减去整体缩放不变(归一化)= 8 DoF
- 自由度决定了”至少需要几对点”:仿射 3 对(每对提供 2 个方程),透视 4 对。
Q4. 双线性插值能否保留图像的最大值?
答:保留。公式 (\hat{f} = \sum w_i f_i),其中 (w_i \geq 0, \sum w_i = 1),所以 (\min f_i \leq \hat{f} \leq \max f_i)——永不超出原值范围。 但双三次不能,它的权重有负值(旁瓣),会产生 over/undershoot。
Q5. 8-bit 量化的 SNR 是多少?实际照片为什么常低于此?
答:理论 (6.02 \times 8 + 1.76 \approx 49.9) dB。 实际照片受传感器噪声、镜头散射、JPEG 压缩等影响,通常只有 30-40 dB——量化噪声远非主导。
Q6. 如何检测 JPEG 的 8×8 块效应?
答:计算像素沿水平/垂直方向的二阶差分,若在 (k \cdot 8, k = 1, 2, \ldots) 处出现周期性峰值,就是块效应。现代去块滤波器(deblocking)专门检测并平滑这些位置。
Q7. 一张图像旋转 30° 后,需要多大画布?
答:新画布尺寸: [ W’ = W |\cos\theta| + H |\sin\theta|, \quad H’ = W |\sin\theta| + H |\cos\theta| ] 并需调整平移 (t_x, t_y),使旋转后图像居中。代码见 §2.7。
2.10 延伸阅读
- 采样定理原始论文:Shannon (1949) Communication in the Presence of Noise
- 量化理论:Gray & Neuhoff, Quantization, IEEE Trans. IT 1998(整本综述)
- 插值全集:Thévenaz, Blu, Unser, Interpolation Revisited(Lanczos、B-spline 等)
- 变换几何:Hartley & Zisserman, Multiple View Geometry in Computer Vision(透视变换的 Bible)
动手建议:自己实现一次双线性插值 + 仿射旋转(不调库),再对比 OpenCV 的结果——每一个数都能对上时,你就真懂了。
如果這篇文章對你有幫助,歡迎分享給更多人!
部分資訊可能已經過時





















