OpenISP 模块拆解 · 第11讲:非局部均值降噪 (NLM)
模块作用
NLM 是非局部均值降噪。openISP 主流程中它处理 YUV 图像的 Y 通道,也就是亮度通道。
它的核心假设是:图像中存在重复或相似的小块。对于当前像素,不只看附近单个像素,而是在搜索窗口里寻找相似 patch,用相似程度作为权重做平均。
openISP 实现
源码类名为 NLM(img, ds, Ds, h, clip)。
| 参数 | 含义 |
|---|---|
ds |
patch 半径,1 表示 3x3 patch |
Ds |
搜索窗口半径 |
h |
滤波强度 |
clip |
输出上限 |
主程序调用:
python
NLM(yuvimg_csc[:, :, 0], 1, 4, nlm_h, nlm_clip)
核心公式
计算候选 patch 与中心 patch 的距离:
text
dist = sum(kernel * (neighbor_patch - center_patch)^2)
距离越小权重越大:
text
w = exp(-dist / h^2)
输出为候选中心像素的加权平均。
代码流程
- 按搜索半径
Ds做 reflect padding。 - 构造均匀 patch kernel。
- 对每个像素,在搜索窗口内遍历候选 patch。
- 计算 patch 距离和指数权重。
- 累加加权像素值。
- 用最大权重补偿中心像素自身。
- 输出裁剪结果。
学习重点
- NLM 能比普通均值滤波更好保留重复纹理。
h越大,降噪越强,但细节越容易被抹。- 搜索窗口越大,效果可能更好,但计算量明显增加。
读源码注意点
源码是纯 Python 循环,大图运行会很慢。calWeights() 中判断候选是否为中心的条件也比较粗糙,但不影响理解 NLM 基本思想。
面试问答
Q1: NLM 和均值滤波有什么区别?
均值滤波只按空间位置平均,容易模糊边缘。NLM 按 patch 相似度加权,相似纹理贡献更大,因此更能保留结构。
Q2: NLM 的 h 参数代表什么?
h 控制权重随 patch 距离衰减的速度。h 大,差异较大的 patch 也会参与平均,降噪强但更模糊;h 小,只有很相似的 patch 权重大,保细节但降噪弱。
Q3: NLM 为什么计算量大?
每个像素都要在搜索窗口内比较多个 patch,每个 patch 又包含多个像素,复杂度远高于普通 3x3 或 5x5 滤波。
Q4: 为什么 openISP 只对 Y 通道做 NLM?
亮度通道对视觉细节最重要。只处理 Y 可以降低计算量,并避免直接平滑 UV 导致颜色发灰或色彩边界异常。
Q5: NLM 适合所有噪声吗?
不一定。它适合具有相似 patch 的自然图像,对随机噪声有效,但可能对运动、强纹理、非重复结构或高 ISO 彩噪效果有限。