4. 拜耳域降噪基础", "title": "拜耳域降噪基础

任务目标

在拜耳域(Bayer域)直接对RAW图像进行均值滤波降噪,理解该操作对图像细节的影响。本案例将实现一个3×3窗口的拜耳域均值滤波器,仅对同颜色通道的像素取平均,避免跨通道颜色串扰。

实现原理

拜耳域图像每个像素仅包含R、G、B中的一个颜色分量,按RGGB模式排列。若直接对邻域所有像素做均值,会混入不同颜色通道的值,导致伪彩色。正确做法是:对每个像素,仅取其周围同颜色通道的像素值进行平均。由于拜耳阵列中同色像素间隔为2,3×3窗口内同色像素最多有4个(中心像素 + 对角/正交方向的同色邻居)。

代码实现

import numpy as np

def bayer_mean_filter(raw_img, pattern='RGGB'):
    """
    拜耳域3x3均值滤波(仅同通道平均)
    raw_img: HxW uint16 Bayer RAW图像
    pattern: 'RGGB' 或 'BGGR'(决定R/B通道起始位置)
    返回: 滤波后的uint16图像,边界像素保持原值
    """
    h, w = raw_img.shape
    out = raw_img.copy().astype(np.float32)
    
    # 确定R和B通道的偏移(G通道两种位置都处理)
    if pattern == 'RGGB':
        r_off, b_off = (0, 0), (1, 1)  # R在(0,0), B在(1,1)
    else:  # BGGR
        b_off, r_off = (0, 0), (1, 1)
    
    # 定义同色邻居的3x3掩码(相对坐标)
    # 同色像素在3x3内只出现在间隔2的位置
    offsets = [(-2, -2), (-2, 0), (-2, 2),
               (0, -2),           (0, 2),
               (2, -2),  (2, 0),  (2, 2)]
    
    # 遍历内部像素(边界1行/列不处理)
    for y in range(2, h-2):
        for x in range(2, w-2):
            # 判断当前像素颜色
            if (y % 2 == r_off[0] and x % 2 == r_off[1]) or \
               (y % 2 == b_off[0] and x % 2 == b_off[1]):
                # R或B通道:同色邻居在3x3内只有对角4个
                neighbors = [(y-2, x-2), (y-2, x+2), (y+2, x-2), (y+2, x+2)]
            else:
                # G通道:同色邻居在3x3内是上下左右4个
                neighbors = [(y-2, x), (y+2, x), (y, x-2), (y, x+2)]
            
            vals = [raw_img[ny, nx] for ny, nx in neighbors]
            out[y, x] = np.mean(vals)
    
    return out.astype(np.uint16)

# 最小验证示例
if __name__ == '__main__':
    # 构造8x8测试图(RGGB)
    test = np.zeros((8, 8), dtype=np.uint16)
    # 填充简单色块:左上R=100, 右下B=200, 其余G=50
    test[0:4, 0:4] = 100   # R位置
    test[0:4, 4:8] = 50    # G
    test[4:8, 0:4] = 50    # G
    test[4:8, 4:8] = 200   # B位置
    
    filtered = bayer_mean_filter(test)
    
    # 验证:中心区域(3,3)是R像素,其同色邻居(1,1),(1,5),(5,1),(5,5)均为R=100
    # 因此滤波后(3,3)应仍为100(均值不变)
    print(f"原始(3,3)={test[3,3]}, 滤波后(3,3)={filtered[3,3]}")
    print(f"原始(4,4)={test[4,4]}, 滤波后(4,4)={filtered[4,4]}")  # B像素,邻居均为200

运行与验证

环境依赖:仅需NumPy(pip install numpy)。

运行方式:直接执行脚本:python bayer_filter.py。

验证方法:

  • 观察输出:测试图中(3,3)位置为R像素,其4个同色邻居(1,1)、(1,5)、(5,1)、(5,5)均为R=100,均值仍为100,因此滤波前后该点值不变。
  • (4,4)为B像素,邻居均为B=200,滤波后仍为200。
  • 若滤波正确,上述两处打印值应相等(均为100和200)。

通过标准:程序无报错,且两行输出中滤波前后数值一致,说明同色通道均值逻辑正确。

细节影响分析

该滤波器对平坦区域无影响(均值等于原值),但在边缘或纹理区域会显著降低细节对比度。例如若某R像素周围同色邻居值差异大(如100与200),滤波后该点被拉向中间值,导致边缘模糊。这是均值滤波的固有代价——降噪的同时牺牲高频细节。实际ISP中通常改用边缘保护的双边滤波或小波降噪来缓解此问题。