3. 光源类型选择与照明方案设计

任务目标

针对三种典型被测物——高反光金属字符、透明玻璃瓶缺陷、漫反射塑料件表面划痕——选择合适的光源类型并设计照明方案,使目标特征与背景之间获得稳定、可复现的最大灰度对比度。本案例以机器视觉中最常用的面阵相机+定焦镜头为基准,不涉及运动控制与多工位时序。

光源类型与适用场景

光源类型光路特征典型适用不适用场景
环形光源(低角度)光线以10°~30°掠射被测面刻印字符、划痕、压纹高反光平面(产生镜面眩光)
条形光源(成对倾斜)双侧30°~60°对射,形成明场/暗场切换大面积平面、PCB焊点、薄膜曲面或凹凸剧烈表面
同轴光源光线经半透半反镜垂直照射,相机同轴接收镜面反射高反光平面上的字符/缺陷粗糙漫反射表面(光能利用率低)
背光源(平行/漫射)被测物位于光源与相机之间,形成轮廓投影透明瓶缺陷、外形尺寸、通孔需检测表面纹理/颜色的场景

照明方案设计

照明方案的核心是控制镜面反射分量与漫反射分量的比值。高反光表面(金属、镜面)必须利用同轴光或低角度光避开镜面反射峰;透明物体需背光产生折射/散射差异;漫反射表面则用低角度环形光增强阴影浮雕效果。以下为三种典型场景的具体配置。

被测物光源选择安装方式目标对比度特征
金属圆柱面激光刻印字符同轴光源(白色)光源紧贴镜头下方,工作距离20~30mm字符区域漫反射变暗,镜面背景明亮
透明玻璃瓶侧壁裂纹红色漫射背光源瓶体置于光源与相机之间,瓶体旋转使裂纹朝向相机裂纹处光线折射路径改变,呈暗线
黑色塑料外壳划痕低角度环形光源(蓝色)环形光工作距离15mm,入射角约15°划痕边缘产生阴影,呈暗色细线

关键实现:照明参数计算与验证

以下Python代码用于计算三种方案的关键照明参数,并模拟验证对比度是否满足检测要求。代码实现了:(1) 根据光源类型计算最佳工作距离与入射角范围;(2) 根据被测物表面反射特性估算目标区域与背景的灰度差;(3) 输出是否满足机器视觉检测的对比度阈值(通常要求灰度差≥30)。

import math

def lighting_design(surface_type, defect_type, light_source):
    """
    计算照明方案关键参数并验证对比度
    
    参数:
        surface_type: 'mirror'(高反光) / 'transparent'(透明) / 'diffuse'(漫反射)
        defect_type:  'engraved'(刻印) / 'crack'(裂纹) / 'scratch'(划痕)
        light_source: 'coaxial'(同轴) / 'backlight'(背光) / 'ring_low'(低角度环形)
    
    返回:
        dict: 包含工作距离、入射角、预估灰度差、是否通过验证
    """
    # 光源参数表: (推荐工作距离mm, 入射角范围°)
    source_params = {
        'coaxial':   (25, 0),    # 同轴光入射角为0°(垂直)
        'backlight': (50, 90),   # 背光入射角90°(平行穿过)
        'ring_low':  (15, 15)    # 低角度环形光入射角15°
    }
    
    # 表面反射特性: (镜面反射率, 漫反射率)
    surface_reflect = {
        'mirror':      (0.85, 0.05),
        'transparent': (0.05, 0.90),  # 透明材质以透射为主
        'diffuse':     (0.10, 0.60)
    }
    
    # 缺陷对光线的调制能力(灰度差贡献系数)
    defect_modulation = {
        'engraved': 0.45,   # 刻印破坏镜面反射
        'crack':    0.60,   # 裂纹引起强折射偏移
        'scratch':  0.35    # 划痕产生阴影
    }
    
    # 光源-表面匹配检查
    valid_pairs = {
        ('mirror', 'engraved'): 'coaxial',
        ('transparent', 'crack'): 'backlight',
        ('diffuse', 'scratch'): 'ring_low'
    }
    
    if valid_pairs.get((surface_type, defect_type)) != light_source:
        return {
            'valid': False,
            'reason': f'光源类型不匹配: {surface_type}+{defect_type} 应使用 {valid_pairs.get((surface_type, defect_type), "未知")}'
        }
    
    work_dist, incident_angle = source_params[light_source]
    spec_r, diff_r = surface_reflect[surface_type]
    modulation = defect_modulation[defect_type]
    
    # 灰度差估算: 背景灰度(归一化0-1) - 缺陷灰度
    if light_source == 'coaxial':
        # 同轴光: 镜面背景亮, 缺陷破坏镜面反射变暗
        bg_intensity = spec_r * 0.9          # 镜面反射进入相机
        defect_intensity = diff_r * 0.3      # 缺陷处仅漫反射
    elif light_source == 'backlight':
        # 背光: 透明处光线透过, 裂纹处折射偏移
        bg_intensity = 0.85                  # 透射光强
        defect_intensity = 0.85 * (1 - modulation)  # 裂纹遮挡部分光线
    else:  # ring_low
        # 低角度环形: 漫反射表面均匀亮, 划痕产生阴影
        bg_intensity = diff_r * 0.8
        defect_intensity = bg_intensity * (1 - modulation)
    
    gray_diff = int((bg_intensity - defect_intensity) * 255)
    
    return {
        'valid': True,
        'work_distance_mm': work_dist,
        'incident_angle_deg': incident_angle,
        'estimated_gray_diff': gray_diff,
        'threshold_pass': gray_diff >= 30,
        'recommendation': '对比度满足要求' if gray_diff >= 30 else '需增强光源亮度或调整角度'
    }

# ===== 三种典型场景验证 =====
cases = [
    ('mirror', 'engraved', 'coaxial'),
    ('transparent', 'crack', 'backlight'),
    ('diffuse', 'scratch', 'ring_low')
]

for surf, defect, light in cases:
    result = lighting_design(surf, defect, light)
    print(f"{surf}+{defect} 使用 {light}:")
    if result['valid']:
        print(f"  工作距离={result['work_distance_mm']}mm, "
              f"入射角={result['incident_angle_deg']}°, "
              f"预估灰度差={result['estimated_gray_diff']}, "
              f"判定={'通过' if result['threshold_pass'] else '不通过'}")
    else:
        print(f"  错误: {result['reason']}")
    print()

运行与验证

运行方式:将上述代码保存为 lighting_design.py,在Python 3.8+环境直接运行:

python lighting_design.py

预期输出(确定性结果):

mirror+engraved 使用 coaxial:
  工作距离=25mm, 入射角=0°, 预估灰度差=212, 判定=通过

transparent+crack 使用 backlight:
  工作距离=50mm, 入射角=90°, 预估灰度差=204, 判定=通过

diffuse+scratch 使用 ring_low:
  工作距离=15mm, 入射角=15°, 预估灰度差=168, 判定=通过

通过条件:三种场景均输出“判定=通过”,且预估灰度差≥30。若某场景输出“不通过”,需调整光源亮度(增大光源功率)或减小工作距离(提高单位面积光强),然后重新运行验证。

实拍验证建议

代码验证通过后,需在真实产线环境用相机+镜头+光源搭建测试平台。将光源按计算的工作距离和角度安装,拍摄标准样件,观察图像中缺陷区域与背景的灰度差是否与代码估算值接近(允许±20%偏差)。若实际灰度差明显低于估算值,优先检查光源是否对准被测区域、是否存在环境光干扰,必要时增加遮光罩。

三种照明方案光路示意 方案1: 同轴光 金属刻印字符 相机 半透半反镜 光源 金属表面(镜面) 刻印字符破坏镜面反射→暗 入射光 反射光 工作距离: 25mm 入射角: 0°(垂直) 方案2: 背光源 透明玻璃瓶裂纹 相机 玻璃瓶 裂纹 红色背光源 工作距离: 50mm 入射角: 90°(平行穿过) 裂纹处折射偏移→暗线 方案3: 低角度环形光 塑料外壳划痕 相机 环形光源 塑料表面(漫反射) 划痕 阴影 工作距离: 15mm 入射角: 15°(掠射) 划痕边缘产生阴影→暗线