第 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 一维采样回顾
设连续信号 ,以间隔 采样,得到离散序列 。
用冲激串描述这个操作:
采样结果:
2.2.2 采样的频谱(核心推导)
冲激串 的傅里叶变换:
(提示:周期冲激串 FT 仍是冲激串,间隔 ,幅值 )
由乘积→卷积定理:
几何解释:原频谱 被复制到每个采样频率 ()的整数倍上。
原频谱 F(u) 采样后 F_s(u) ▲ ▲ │ ∧ │ ∧ ∧ ∧ ∧ │╱ ╲ │╱ ╲ ╱ ╲ ╱ ╲ ╱ ╲ ┼──────> u ┼─────────────────> u -W 0 W -f_s 0 f_s 2f_s2.2.3 Nyquist-Shannon 采样定理
定理:若 频谱 对所有 (带限),则只要
采样序列 可完美重建原信号。
称为奈奎斯特率。
几何解释:只要相邻频谱副本不重叠,就能用理想低通 取出中心副本 → IFT 得到原信号。
2.2.4 混叠 (Aliasing)
若 ,相邻频谱副本重叠:
∧ ∧ ∧ 发生重叠→╱ ╲ ╱ ╲ ╱ ╲ 无法分离原频谱 ╲╱ ╲╱高频 会"折叠"到低频位置,造成虚假低频——这就是混叠。
公式化:采样后观察到的频率
典型现象:
- 摩尔纹 (Moiré):拍摄屏幕、条纹衬衫出现彩色干涉纹
- 锯齿 (Jaggies):斜线边缘出现阶梯
- 轮辐逆转:电影中车轮看起来倒转
- 视频闪烁:高频细节在下采样时跳变
2.2.5 抗混叠低通滤波 (Anti-Aliasing)
解决办法:在采样之前用低通滤波器切掉高于 的分量。
连续信号 ── LPF(截止 f_s/2) ── 采样 ── 数字信号 ↑ 抗混叠滤波手机摄像头:
- 光学抗混叠滤波片(OLPF,镜头前)
- 传感器的像素大小本身就是一种积分(=矩形低通)
OpenCV 中的 INTER_AREA:下采样时内部先做区域平均(即低通),然后采样——这是唯一在下采样时抗混叠的插值。
2.2.6 二维采样(图像)
直接推广:
频域:二维频谱按 间隔复制。
二维 Nyquist:
2.2.7 数值例子
例 2.1:一幅 A4 纸扫描件,最高空间频率 200 周/英寸。问:扫描分辨率至少多少 DPI?
答:需 样本/英寸 → 至少 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 均匀量化
将连续幅度范围 等分为 个子区间,每个子区间用一个代表值(通常是中点)。
量化函数:
量化步长:
2.3.2 量化误差与 SNR
量化误差 满足 。
假设 在 均匀分布(对高斯等复杂分布成立),则
信号峰峰值为 ,若信号振幅为 ,则信号功率 (正弦信号)。
量化 SNR:
记住一句话:每增加 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 量化器:给定分布 ,最优量化器满足:
- 决策边界:
- 代表值:
即"代表值在各区间的条件均值,边界在相邻代表值的中点"。迭代求解。
对数/μ 律量化:语音、亮度等服从"小信号概率高"的分布,对数压缩后再均匀量化,等效于暗部细、亮部粗。
示例:相机的 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 位平面分解
任意灰度值 可分解为 8 个二进制位:
把每个位 作为一幅二值图,称为位平面。
- 高位平面():主要结构
- 低位平面():细节 + 噪声
应用:数字水印(藏在低位平面不易察觉)、压缩(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 预算 恒定下,改变 ,看人主观评价。
结论:
- 典型自然图像,灰度先降到 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 后向映射(务必理解)
假设变换 。
前向映射:对每个源像素 算出目标位置 ,把值"推"过去。 问题:
- 目标像素可能被多次写入(重叠)
- 也可能无像素写入(空洞)
后向映射(工业标准):对每个目标像素 ,用 查源坐标 ,查值放到目标。
- 每个目标像素一定被写入一次
- 源坐标非整数 → 用插值
# OpenCV 默认就是后向映射dst = cv2.warpAffine(src, M, dsize)2.5.2 最近邻插值
- 最快,无浮点
- 不引入新值(保留离散标签)
- 缺点:严重锯齿、马赛克
应用场景:分割标签图、掩膜、索引图——绝对不能引入新"类别"值。
2.5.3 双线性插值 (Bilinear)
用 周围 4 个整数像素,按距离线性加权。
记 ,则:
两步推导:
- 行方向线性插:
- 列方向线性插:
数值例子:在 处插值,邻域像素值:
f(0, 0)=100 f(1, 0)=200f(0, 1)=50 f(1, 1)=150按公式:
特点:
- 连续(但一阶导数不连续 → 肉眼轻微"模糊")
- 速度快
- 默认选择
2.5.4 双三次插值 (Bicubic)
用 周围 4×4 = 16 个像素,三次多项式加权:
常用 (Catmull-Rom),也有 (OpenCV INTER_CUBIC)。
好处:
- 一阶导数连续 → 视觉更锐利
- 能轻微锐化(负的旁瓣)
- 照片放大的默认选择
2.5.5 Lanczos 插值
理论上的"理想重构"是用 sinc 函数——但 sinc 无限长,不可实现。Lanczos 窗把 sinc 截断并加平滑窗:
常取 或 即 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 点 扩展为 。好处:所有变换(包括平移)都能写成矩阵乘法,方便级联。
反向变换:。
2.6.2 刚体变换(旋转 + 平移)
自由度 (DoF) = 3()。保距、保角。
2.6.3 相似变换(刚体 + 各向同性缩放)
DoF = 4。保角、不保距。
2.6.4 仿射变换
DoF = 6。保直线、保平行、保面积比,但不保角。
分解:任意仿射可分解为 "平移 × 旋转 × 剪切 × 缩放"。
常用特例:
| 变换 | 矩阵 |
|---|---|
| 平移 | |
| 缩放(锚点原点) | |
| 旋转(锚点原点) | |
| x 方向剪切 | |
| 水平翻转 |
绕非原点旋转:
即"平移到原点 → 旋转 → 平移回去"。OpenCV 直接封装为:
M = cv2.getRotationMatrix2D(center, angle, scale) # 2x3仿射求解:3 对点可唯一确定(6 方程 6 未知)。
M = cv2.getAffineTransform(src_3pts, dst_3pts)2.6.5 透视/投影变换 (Homography)
关键区别:最后一行不是 ,意味着 可以变化——不保持平行性!
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 本章速查表
| 主题 | 公式/要点 |
|---|---|
| 采样定理 | |
| 抗混叠 | 采样前做低通 |
| 量化 SNR | dB |
| 量化误差方差 | |
| 双线性插值 | 4 邻域、 加权 |
| 双三次插值 | 16 邻域、三次多项式权重 |
| 仿射自由度 | 6,3 对点解 |
| 透视自由度 | 8,4 对点解 |
| 齐次坐标 |
2.9 本章要点与面试考点
✅ 必须掌握
- 采样定理的完整推导(冲激串 → 频谱复制 → 不重叠条件)
- 混叠的成因与实例
- 量化 SNR 公式
- 空间 / 灰度分辨率权衡
- Floyd-Steinberg 误差扩散原理
- 前向 / 后向映射,为什么选后向
- 双线性、双三次插值的公式与应用场景
-
INTER_AREA在下采样为什么最合适 - 齐次坐标 + 仿射 / 透视变换矩阵
- 计算点阵对应数:仿射 3 点、透视 4 点
💡 高频面试题
Q1. 为什么 1024×1024 图像的 FFT 尺寸一般选 2048?
答:防止循环卷积的混叠/边界效应。DFT 把信号当作周期延拓,长度 N 的线性卷积结果长度为 ,需至少零填充到 ,取 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. 双线性插值能否保留图像的最大值?
答:保留。公式 ,其中 ,所以 ——永不超出原值范围。 但双三次不能,它的权重有负值(旁瓣),会产生 over/undershoot。
Q5. 8-bit 量化的 SNR 是多少?实际照片为什么常低于此?
答:理论 dB。 实际照片受传感器噪声、镜头散射、JPEG 压缩等影响,通常只有 30-40 dB——量化噪声远非主导。
Q6. 如何检测 JPEG 的 8×8 块效应?
答:计算像素沿水平/垂直方向的二阶差分,若在 处出现周期性峰值,就是块效应。现代去块滤波器(deblocking)专门检测并平滑这些位置。
Q7. 一张图像旋转 30° 后,需要多大画布?
答:新画布尺寸:
并需调整平移 ,使旋转后图像居中。代码见 §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 的结果——每一个数都能对上时,你就真懂了。
如果這篇文章對你有幫助,歡迎分享給更多人!
部分資訊可能已經過時





















