跳到主要内容

视觉应用示例

本文档提供 Vision Studio 的五个典型工业视觉应用示例,涵盖外观检测、定位引导、条码识别、尺寸测量和 OCR 字符识别等常见场景。

1. 产品外观检测

场景描述

在注塑件生产线上,对产品表面进行外观缺陷检测,包括划痕、凹陷、缺料、飞边等缺陷类型。检测合格的产品流入下一工序,不合格品自动剔除。

视觉流程

┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│ 相机采集 │ → │ 预处理 │ → │ 缺陷检测 │ → │ 结果输出 │
│ GigE │ │ 灰度+滤波 │ │ ONNX │ │ 分拣信号 │
│ 2448×2048│ │ 2560×2048│ │ 缺陷模型 │ │ + 图像保存 │
└──────────┘ └──────────┘ └──────────┘ └──────────┘

关键配置

参数配置值说明
相机Basler acA2440-75umGigE, 75fps
触发方式硬件触发 (PLC DO)产品到位时触发
曝光时间3000 µs适应白色注塑件
预处理灰度 + 高斯滤波 (5×5)去噪 + 突出特征
模型surface_defect.onnxYOLOv8m, 640×640
置信度阈值0.5过滤低质量检测
检测类别划痕, 凹陷, 缺料, 飞边4 类缺陷
结果输出分拣 DO + 数据通信分拣 + MES 上报

PLC 逻辑 (SCL)

FUNCTION_BLOCK FB_SurfaceInspection
VAR_INPUT
part_present : BOOL; // 产品到位传感器
ejector_ready : BOOL; // 剔除器就绪
END_VAR
VAR_OUTPUT
ejector : BOOL; // 剔除信号
pass_count : INT; // 合格计数
fail_count : INT; // 不合格计数
END_VAR
VAR
trigger_prev : BOOL;
trigger_pulse : BOOL;
fault_type : STRING[32];
END_VAR

// 触发视觉
trigger_pulse := part_present AND NOT trigger_prev;
trigger_prev := part_present;

IF trigger_pulse AND ejector_ready THEN
VIS_JOB_START := TRUE;
END_IF;

// 读取结果
IF VIS_JOB_DONE THEN
VIS_JOB_DONE := FALSE;

IF NOT VIS_JOB_ERROR THEN
IF VIS_RESULT_COUNT > 0 THEN
// 有缺陷,不合格
ejector := TRUE;
fail_count := fail_count + 1;

// 记录缺陷类型
// VIS_RESULT_01_CLASS 包含缺陷类型
ELSE
// 无缺陷,合格
ejector := FALSE;
pass_count := pass_count + 1;
END_IF;
ELSE
// 视觉异常,安全处理
ejector := TRUE;
LOG_ERROR("视觉检测异常");
END_IF;
END_IF;

// 剔除延时复位
IF ejector AND (NOT part_present) THEN
ejector := FALSE;
END_IF;
END_FUNCTION_BLOCK

性能指标

指标
检测节拍800 ms/件
检测精度99.2%
误检率0.5%
漏检率0.3%
最大吞吐量75 件/分钟

2. 定位引导机器人抓取

场景描述

在无序来料场景中,视觉系统识别工件位置和姿态,引导机器人准确抓取。工件在传送带上随机分布,视觉系统计算每个工件的位置偏移和旋转角度。

视觉流程

┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│ 相机采集 │ → │ 模板匹配 │ → │ 坐标转换 │ → │ 结果输出 │
│ 俯视安装 │ │ 形状匹配 │ │ 像素→mm │ │ 机器人 │
│ 2448×2048│ │ 参考工件 │ │ 手眼标定 │ │ 抓取坐标 │
└──────────┘ └──────────┘ └──────────┘ └──────────┘

手眼标定

视觉系统与机器人之间需要进行手眼标定(Eye-to-Hand 或 Eye-in-Hand),将像素坐标转换为机器人基坐标系下的位置。

标定流程

  1. 安装标定板(棋盘格或圆点阵列)
  2. 机器人带动标定板移动到 9 个不同位置
  3. 视觉系统记录每个位置的像素坐标
  4. 记录对应的机器人坐标
  5. 系统自动计算仿射变换矩阵

关键配置

参数配置值说明
相机Hikvision MV-CA013-UCUSB 3.0, 1280×1024
镜头12mm 定焦视野 400×300mm
安装方式固定俯视 (Eye-to-Hand)相机固定于支架
匹配方法形状匹配 (ShapeMatch)不受光照变化影响
匹配评分阈值0.7最低匹配评分
标定精度< 0.5 mm平均标定误差
输出坐标X, Y, 角度机器人抓取位姿

Vision SCL 代码

PROGRAM RobotGuidingProg
VAR
img : Image;
result : MatchResult;
robot_x, robot_y, robot_angle : REAL;
calib_matrix : ARRAY[0..5] OF REAL; // 仿射变换矩阵
END_VAR

// 采集图像
img := CAM_Capture(cam, TIMEOUT := 2000);

// 形状匹配定位
result := IMG_MatchTemplate(img,
TEMPLATE := "workpiece_template.png",
METHOD := MATCH_SHAPE);

// 检查匹配结果
IF result.score > 0.7 THEN
// 像素坐标转机器人坐标 (仿射变换)
robot_x := calib_matrix[0] * result.x +
calib_matrix[1] * result.y + calib_matrix[2];
robot_y := calib_matrix[3] * result.x +
calib_matrix[4] * result.y + calib_matrix[5];
robot_angle := result.angle;

// 输出到机器人
VIS_WriteVariable("ROBOT_TARGET_X", robot_x);
VIS_WriteVariable("ROBOT_TARGET_Y", robot_y);
VIS_WriteVariable("ROBOT_TARGET_ANGLE", robot_angle);
VIS_WriteVariable("ROBOT_GRAB_REQ", 1.0);
ELSE
VIS_Log(LOG_WARN, "定位失败, 评分=" +
REAL_TO_STRING(result.score));
VIS_WriteVariable("ROBOT_GRAB_REQ", 0.0);
END_IF;
END_PROGRAM

性能指标

指标
定位精度±0.3 mm
角度精度±0.5°
单次定位时间150 ms
抓取成功率99.5%

3. 条码/二维码读取

场景描述

在物流分拣线上,通过条码或二维码读取包裹上的标识信息,根据信息内容将包裹分拣到不同通道。

视觉流程

┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│ 相机采集 │ → │ 图像增强 │ → │ 条码识别 │ → │ 分拣输出 │
│ 线阵相机 │ │ 对比度 │ │ Code128 │ │ 通道号 │
│ 4096×1 │ │ 自适应 │ │ QR Code │ │ + 数据库 │
└──────────┘ └──────────┘ └──────────┘ └──────────┘

关键配置

参数配置值说明
相机线阵相机 4096 像素适合高速传送带
触发方式编码器触发与传送带同步
图像增强自适应直方图均衡改善条码对比度
条码类型Code128, QR Code, DataMatrix自适应识别
识别超时1000 ms快速识别
分拣输通道号 + 数据库记录实时分拣 + 数据追溯

卡片图配置

[编码器触发] ──→ [线阵扫描] ──→ [图像增强] ──→ [条码识别]

├──→ [分拣输出]
│ └→ 通道号 DO

└──→ [数据库写入]
└→ 追溯记录

结果处理逻辑

// 条码识别后处理
IF decode_result.content <> "" THEN
// 根据条码内容决定分拣通道
CASE decode_result.format OF
FORMAT_CODE128:
// 分拣逻辑
IF LEFT(decode_result.content, 3) = "ORD" THEN
channel := 1; // 订单包裹
ELSIF LEFT(decode_result.content, 3) = "RET" THEN
channel := 2; // 退货包裹
ELSE
channel := 3; // 其他
END_IF;

FORMAT_QRCODE:
channel := 1; // 二维码统一走通道 1

FORMAT_DATAMATRIX:
channel := 4; // DataMatrix 走通道 4
END_CASE;

// 输出分拣信号
VIS_WriteVariable("SORT_CHANNEL", INT_TO_REAL(channel));
VIS_WriteVariable("SORT_TRIGGER", 1.0);

// 记录到数据库
DB_Write("sorting_records",
decode_result.content,
INT_TO_STRING(channel),
NOW());
ELSE
// 未识别,走异常通道
VIS_WriteVariable("SORT_CHANNEL", 0.0);
VIS_Log(LOG_WARN, "条码未识别");
END_IF;

性能指标

指标
识别率99.7%
识别速度< 100 ms/次
传送带速度2 m/s
最大包裹尺寸600×400×300 mm

4. 尺寸测量

场景描述

在机加工产线上,对加工完成的零件进行关键尺寸测量,包括孔径、外径、间距、角度等,判断是否在公差范围内。

视觉流程

┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│ 相机采集 │ → │ 边缘检测 │ → │ 几何测量 │ → │ 结果判断 │
│ 背光照明 │ │ Canny │ │ 圆拟合 │ │ 公差范围 │
│ 500万像素 │ │ 亚像素 │ │ 直线拟合 │ │ OK/NG │
└──────────┘ └──────────┘ └──────────┘ └──────────┘

关键配置

参数配置值说明
相机5MP 全局快门500 万像素
镜头远心镜头消除透视误差
照明背光 LED轮廓清晰
边缘检测Canny + 亚像素精度 0.1 pixel
标定标定板 0.05 mm/pixel像素当量
测量项目孔径 3 处, 间距 2 处, 角度 1 处6 个测量项

测量结果输出

┌──────────────────────────────────────────────┐
│ 测量报告 │
│ 零件: 支架-A292 │
│ 时间: 2026-07-20 14:30:00 │
│ │
│ ┌──────────┬──────┬──────┬──────┬────────┐ │
│ │ 测量项 │ 标称值 │ 实测值 │ 公差 │ 结果 │ │
│ ├──────────┼──────┼──────┼──────┼────────┤ │
│ │ 孔径 #1 │ 20.0 │ 20.02│ ±0.1 │ OK │ │
│ │ 孔径 #2 │ 12.0 │ 12.03│ ±0.1 │ OK │ │
│ │ 孔径 #3 │ 8.0 │ 8.01 │ ±0.05│ OK │ │
│ │ 间距 #1 │ 50.0 │ 49.98│ ±0.2 │ OK │ │
│ │ 间距 #2 │ 30.0 │ 30.05│ ±0.2 │ OK │ │
│ │ 角度 │ 90.0 │ 89.8 │ ±1.0 │ OK │ │
│ └──────────┴──────┴──────┴──────┴────────┘ │
│ │
│ 总体判定: OK │
└──────────────────────────────────────────────┘

Vision SCL 代码

PROGRAM DimensionMeasurement
VAR
img : Image;
circle1, circle2, circle3 : Circle;
line1, line2 : Line;
dist1, dist2 : REAL;
angle : REAL;
all_ok : BOOL;
BEGIN
// 采集
img := CAM_Capture(cam, TIMEOUT := 3000);

// 边缘检测
img := IMG_Canny(img, LOW := 50, HIGH := 150);

// 测量 3 个孔
circle1 := MEAS_FindCircle(img, ROI := RECT(100, 200, 300, 300));
circle2 := MEAS_FindCircle(img, ROI := RECT(500, 200, 200, 200));
circle3 := MEAS_FindCircle(img, ROI := RECT(300, 500, 200, 200));

// 测量两条边
line1 := MEAS_FindLine(img, ROI := RECT(0, 0, 800, 50));
line2 := MEAS_FindLine(img, ROI := RECT(0, 750, 800, 50));

// 计算间距
dist1 := MEAS_DistancePP(circle1.center_x, circle1.center_y,
circle2.center_x, circle2.center_y);
dist2 := MEAS_DistancePP(circle1.center_x, circle1.center_y,
circle3.center_x, circle3.center_y);

// 计算角度
angle := MEAS_Angle(line1, line2);

// 单位转换 (mm)
circle1.radius := circle1.radius * 0.05;
circle2.radius := circle2.radius * 0.05;
circle3.radius := circle3.radius * 0.05;
dist1 := dist1 * 0.05;
dist2 := dist2 * 0.05;

// 公差判断
all_ok := TRUE;

all_ok := all_ok AND (ABS(circle1.radius - 10.0) < 0.1);
all_ok := all_ok AND (ABS(circle2.radius - 6.0) < 0.1);
all_ok := all_ok AND (ABS(circle3.radius - 4.0) < 0.05);
all_ok := all_ok AND (ABS(dist1 - 50.0) < 0.2);
all_ok := all_ok AND (ABS(dist2 - 30.0) < 0.2);
all_ok := all_ok AND (ABS(angle - 90.0) < 1.0);

// 输出结果
VIS_WriteResult(all_ok);
VIS_WriteVariable("MEAS_OK", BOOL_TO_REAL(all_ok));
END_PROGRAM

性能指标

指标
测量精度±0.01 mm
重复精度±0.005 mm
单次测量时间500 ms
误判率< 0.1%

5. OCR 字符识别

场景描述

在电子元件生产线上,读取产品表面激光刻印的字符序列号,用于生产追溯和品质管理。字符可能因刻印质量、材料反光等因素导致识别困难。

视觉流程

┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│ 相机采集 │ → │ 预处理 │ → │ OCR 识别 │ → │ 结果验证 │
│ 高倍放大 │ │ 二值化 │ │ Tesseract │ │ 校验位 │
│ 暗场照明 │ │ 形态学 │ │ 数字+字母 │ │ 格式检查 │
└──────────┘ └──────────┘ └──────────┘ └──────────┘

关键配置

参数配置值说明
相机12MP 高分辨率1200 万像素
镜头50mm 微距高放大倍率
照明环形暗场突出刻印字符
预处理二值化 + 形态学闭运算字符区域增强
OCR 引擎Tesseract OCR工业级 OCR
识别语言英文 + 数字白名单: A-Z, 0-9
字符格式"SN-XXXXXXXX-XX"12 位序列号格式
最低置信度0.8低于此值视为识别失败

结果验证逻辑

PROGRAM SerialNumberOCR
VAR
ocr_result : OCRResult;
serial : STRING[32];
valid : BOOL;
checksum : INT;
i : INT;
char_sum : INT;
END_VAR

// 采集与预处理
img := CAM_Capture(cam, TIMEOUT := 3000);
img := IMG_Threshold(img, THRESH := 128, MAXVAL := 255, TYPE := BINARY);
img := IMG_Morphology(img, OP := CLOSE, KSIZE := 3);

// OCR 识别
ocr_result := OCR_Recognize(img,
LANG := "eng",
WHITELIST := "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-");

// 验证结果
valid := FALSE;

IF ocr_result.confidence > 0.8 THEN
serial := ocr_result.text;

// 格式检查: "SN-XXXXXXXX-XX"
IF LEN(serial) = 13 AND
LEFT(serial, 3) = "SN-" AND
MID(serial, 12, 1) = "-" THEN

// 校验位验证 (Luhn 算法)
char_sum := 0;
FOR i := 4 TO 11 DO
char_sum := char_sum + INT_OF_CHAR(MID(serial, i, 1));
END_FOR;
checksum := INT_OF_CHAR(RIGHT(serial, 2));

valid := (char_sum MOD 97 = checksum);
END_IF;
END_IF;

// 输出结果
IF valid THEN
VIS_WriteVariable("PROD_SERIAL", REAL_OF_STRING(serial));
VIS_WriteVariable("PROD_TRACK_OK", 1.0);

// 记录到追溯系统
DB_Write("tracking", serial, NOW());
ELSE
VIS_WriteVariable("PROD_TRACK_OK", 0.0);
VIS_Log(LOG_WARN, "序列号识别失败");
END_IF;
END_PROGRAM

性能指标

指标
识别率99.3%
误识率0.02%
识别速度< 300 ms/次
最小字符高度15 像素
适应字符类型点阵、激光、喷码