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%偏差)。若实际灰度差明显低于估算值,优先检查光源是否对准被测区域、是否存在环境光干扰,必要时增加遮光罩。