3. 坏点校正

坏点校正 学习卡片

任务目标

传感器坏点(Dead Pixel)表现为固定位置上的异常像素值,不随场景变化,在图像中形成固定噪声。本案例实现坏点检测与校正:通过邻域统计识别异常像素,并用中值替换完成修复。

核心原理

坏点检测基于局部统计特性:正常像素与其邻域高度相关,而坏点与邻域差异显著。对每个像素,计算其与周围8邻域的中值偏差,若偏差超过自适应阈值则判定为坏点。阈值由邻域偏差的中位数(MAD)估计噪声水平,避免全局固定阈值在不同亮度区域的误检。

完整实现

import numpy as np

def detect_and_correct_dead_pixels(image, threshold_factor=3.0):
    """
    坏点检测与校正
    Args:
        image: 单通道灰度图, uint8, shape (H, W)
        threshold_factor: 阈值因子, 越大检测越保守
    Returns:
        corrected: 修复后图像, uint8
        dead_mask: 坏点掩码, bool
    """
    img = image.astype(np.float32)
    h, w = img.shape
    padded = np.pad(img, 1, mode='reflect')
    corrected = img.copy()
    dead_mask = np.zeros_like(img, dtype=bool)

    for i in range(h):
        for j in range(w):
            # 提取3x3邻域(不含中心)
            neighborhood = padded[i:i+3, j:j+3].flatten()
            center_val = img[i, j]
            neighbors = neighborhood[neighborhood != center_val]

            if len(neighbors) < 4:  # 边缘保护
                continue

            median_val = np.median(neighbors)
            # 邻域偏差中位数(MAD)估计噪声
            mad = np.median(np.abs(neighbors - median_val))
            if mad < 1e-6:
                mad = 1.0  # 平坦区域保护

            # 自适应阈值
            threshold = threshold_factor * 1.4826 * mad

            # 坏点判定: 中心值与邻域中值偏差过大
            if abs(center_val - median_val) > threshold:
                dead_mask[i, j] = True
                corrected[i, j] = median_val

    return corrected.astype(np.uint8), dead_mask

# 最小验证示例
if __name__ == "__main__":
    # 构造含坏点的测试图: 渐变背景 + 3个坏点
    test_img = np.tile(np.arange(256, dtype=np.uint8), (256, 1))
    test_img[50, 50] = 0      # 暗坏点
    test_img[100, 200] = 255  # 亮坏点
    test_img[200, 100] = 30   # 偏移坏点

    corrected_img, mask = detect_and_correct_dead_pixels(test_img)

    # 验证: 坏点应被修复, 正常像素不变
    print(f"检测到坏点数: {mask.sum()}")
    print(f"坏点位置: {np.argwhere(mask).tolist()}")
    print(f"修复后坏点处像素值: {corrected_img[50,50]}, {corrected_img[100,200]}, {corrected_img[200,100]}")
    print(f"正常像素保持: {corrected_img[10,10] == test_img[10,10]}")

运行与验证

依赖:仅需NumPy。

运行方式:

python dead_pixel_correction.py

预期输出:

检测到坏点数: 3
坏点位置: [[50, 50], [100, 200], [200, 100]]
修复后坏点处像素值: 50, 200, 100
正常像素保持: True

判定标准:程序输出检测到3个坏点且位置正确;修复后坏点处像素值等于其邻域中值(渐变图中即原渐变值);正常像素未被误修改。

关键说明

  • MAD估计对平坦区域会退化,代码中设置最小阈值1.0防止平坦区误检。
  • 阈值因子threshold_factor默认3.0,实际ISP中可根据传感器噪声特性调整(通常2.5~4.0)。
  • 本实现为逐像素遍历,适合教学演示;工程落地可用滑动窗口或GPU并行加速。
  • 对彩色图像需逐通道处理,或转为YUV后在Y通道检测、RGB三通道同时修复。