4. 光照不均校正

任务说明

本案例针对工业现场常见的光照不均字符图像(如金属表面反光、侧向照明导致的半边亮半边暗),使用直方图均衡化方法增强字符与背景的对比度。输入为一张模拟光照不均的灰度字符图像,输出为均衡化后的增强图像,并给出可量化的对比度改善指标。

实现方案

采用OpenCV实现完整处理流程:首先读取灰度图像并计算原始直方图;然后应用全局直方图均衡化(Histogram Equalization);最后计算均衡前后的图像标准差与灰度级分布范围,作为对比度改善的量化依据。为验证算法对光照不均的适应性,代码内置一张合成的渐变光照字符图作为样例输入,该图左侧暗、右侧亮,字符灰度与背景差异在暗区较小。

输入:光照不均 直方图均衡化 cv2.equalizeHist() A B 输出:对比度增强 原始直方图 均衡化直方图 灰度范围拉伸至全动态范围 暗区细节对比度提升

代码实现


import cv2
import numpy as np

def generate_test_image(size=(300, 400)):
    """生成带字符的光照不均测试图(左侧暗、右侧亮)"""
    # 创建渐变背景:灰度值从暗(60)到亮(200)线性变化
    gradient = np.linspace(60, 200, size[1], dtype=np.uint8)
    bg = np.tile(gradient, (size[0], 1))
    
    # 在背景上绘制字符(字符灰度比暗区背景亮30,比亮区背景暗30)
    img = bg.copy()
    font = cv2.FONT_HERSHEY_SIMPLEX
    cv2.putText(img, "OCR", (60, 180), font, 3, color=90, thickness=12)
    cv2.putText(img, "4/100", (80, 250), font, 1.5, color=150, thickness=6)
    return img

def analyze_contrast(img):
    """计算图像标准差与灰度动态范围"""
    std = float(np.std(img))
    gray_min = int(np.min(img))
    gray_max = int(np.max(img))
    return std, gray_min, gray_max

def main():
    # 1. 生成/读取输入图像
    img = generate_test_image()
    
    # 2. 直方图均衡化
    equalized = cv2.equalizeHist(img)
    
    # 3. 量化对比度指标
    orig_std, orig_min, orig_max = analyze_contrast(img)
    eq_std, eq_min, eq_max = analyze_contrast(equalized)
    
    # 4. 输出结果
    print("=== 光照不均校正结果 ===")
    print(f"原始图像  标准差: {orig_std:.1f}, 灰度范围: [{orig_min}, {orig_max}]")
    print(f"均衡化后  标准差: {eq_std:.1f}, 灰度范围: [{eq_min}, {eq_max}]")
    print(f"标准差提升: {eq_std / orig_std:.2f} 倍")
    
    # 5. 保存结果(可选)
    cv2.imwrite("original_uneven.png", img)
    cv2.imwrite("equalized_result.png", equalized)

if __name__ == "__main__":
    main()

运行与验证

依赖:Python 3.x,OpenCV(pip install opencv-python),NumPy。

运行方式:将上述代码保存为 hist_equalize_demo.py,在终端执行 python hist_equalize_demo.py。

验证方法:

  1. 观察控制台输出的标准差与灰度范围:均衡化后灰度范围应扩展至接近[0, 255]全动态范围,标准差应明显大于原始值(通常提升2倍以上);
  2. 打开生成的 equalized_result.png,与 original_uneven.png 对比:原始图中左侧暗区字符与背景难以区分,均衡化后暗区字符轮廓清晰可辨,亮区字符不过曝;
  3. 判定标准:暗区字符边缘可肉眼识别,且图像整体灰度分布不再集中于狭窄区间。

预期输出(基于代码逻辑推导):原始图像因光照不均灰度集中在[60,200]区间,标准差约40左右;均衡化后灰度范围扩展至接近[0,255],标准差提升至约70以上,暗区字符对比度显著增强。