4. 光照不均校正
任务说明
本案例针对工业现场常见的光照不均字符图像(如金属表面反光、侧向照明导致的半边亮半边暗),使用直方图均衡化方法增强字符与背景的对比度。输入为一张模拟光照不均的灰度字符图像,输出为均衡化后的增强图像,并给出可量化的对比度改善指标。
实现方案
采用OpenCV实现完整处理流程:首先读取灰度图像并计算原始直方图;然后应用全局直方图均衡化(Histogram Equalization);最后计算均衡前后的图像标准差与灰度级分布范围,作为对比度改善的量化依据。为验证算法对光照不均的适应性,代码内置一张合成的渐变光照字符图作为样例输入,该图左侧暗、右侧亮,字符灰度与背景差异在暗区较小。
代码实现
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。
验证方法:
- 观察控制台输出的标准差与灰度范围:均衡化后灰度范围应扩展至接近[0, 255]全动态范围,标准差应明显大于原始值(通常提升2倍以上);
- 打开生成的
equalized_result.png,与original_uneven.png对比:原始图中左侧暗区字符与背景难以区分,均衡化后暗区字符轮廓清晰可辨,亮区字符不过曝; - 判定标准:暗区字符边缘可肉眼识别,且图像整体灰度分布不再集中于狭窄区间。
预期输出(基于代码逻辑推导):原始图像因光照不均灰度集中在[60,200]区间,标准差约40左右;均衡化后灰度范围扩展至接近[0,255],标准差提升至约70以上,暗区字符对比度显著增强。