跳到主要内容

Vision SCL 编程

Vision SCL (Visual Structured Control Language) 是 Vision Studio 的视觉专用编程语言。它在标准 PLC SCL 基础上扩展了视觉数据类型、图像处理函数和推理调用接口,适合实现复杂视觉逻辑。

语言概述

与标准 SCL 的异同

特性标准 SCLVision SCL
基础语法IF/FOR/WHILE/CASE完全兼容
数据类型BOOL/INT/REAL/STRING/ARRAY全部继承
视觉类型不支持Image / Region / Contour / DetectionResult 等
视觉函数不支持200+ 视觉算子
推理调用不支持ONNX Runtime 推理
异步执行不支持Job 异步提交 + 回调
编译目标PLC VM 字节码视觉中间表示
运行环境PLC 运行时Vision Studio 运行时

编程模式

Vision SCL 支持两种编程模式:

1. 独立模式:纯 Vision SCL 编写完整视觉程序

PROGRAM VisionProgram
VAR
cam : Camera;
img : Image;
result : DetectionResult;
END_VAR

img := CAM_Capture(cam, TIMEOUT := 5000);
result := OBJ_Detect(img, MODEL := "model.onnx");
VIS_WriteResult(result);
END_PROGRAM

2. 混合模式:卡片图 + Vision SCL 代码片段

在卡片图编辑器中,可以使用 SCL 脚本 卡片嵌入自定义逻辑:

// 在卡片图流程中插入自定义后处理
IF result.confidence > 0.8 THEN
result := result; // 保留高质量检测
ELSE
result.confidence := 0.0; // 过滤低置信度
END_IF;

视觉专用数据类型

Image (图像)

TYPE Image :
STRUCT
width : DWORD; // 图像宽度 (像素)
height : DWORD; // 图像高度 (像素)
channels : BYTE; // 通道数 (1=灰度, 3=BGR, 4=BGRA)
format : ImageFormat; // 像素格式 (enum)
timestamp : LWORD; // 采集时间戳 (TSC)
data_ptr : DWORD; // 图像数据指针 (仅供内部使用)
metadata : STRING[256]; // 元数据 JSON
END_STRUCT
END_TYPE

ImageFormat 枚举

枚举值说明每像素位数
FORMAT_GRAY88 位灰度8 bit
FORMAT_GRAY1616 位灰度16 bit
FORMAT_BGR2424 位 BGR24 bit
FORMAT_BGRA3232 位 BGRA32 bit
FORMAT_RGB2424 位 RGB24 bit
FORMAT_YUV420YUV 420 平面12 bit

Region (区域)

TYPE Region :
STRUCT
pixel_count : DWORD; // 像素数
bounding_box : Rect; // 外接矩形
centroid_x : REAL; // 质心 X
centroid_y : REAL; // 质心 Y
area : REAL; // 面积 (平方像素)
perimeter : REAL; // 周长 (像素)
// ... 其他矩特征
END_STRUCT
END_TYPE

Contour (轮廓)

TYPE Contour :
STRUCT
point_count : DWORD; // 轮廓点数
length : REAL; // 轮廓长度
is_closed : BOOL; // 是否闭合
center_x : REAL; // 中心 X
center_y : REAL; // 中心 Y
// ... 几何属性
END_STRUCT
END_TYPE

DetectionResult (检测结果)

TYPE DetectionResult :
STRUCT
object_count : DWORD; // 检测目标数
objects : ARRAY[0..255] OF // 目标列表 (最多 256 个)
STRUCT
class_id : WORD; // 类别 ID
class_name : STRING[64]; // 类别名称
confidence : REAL; // 置信度 (0.0~1.0)
x : REAL; // 中心 X
y : REAL; // 中心 Y
width : REAL; // 宽度
height : REAL; // 高度
angle : REAL; // 旋转角度 (度)
END_STRUCT;
inference_time_ms : REAL; // 推理耗时 (毫秒)
status : DWORD; // 状态码
END_STRUCT
END_TYPE

其他数据类型

类型说明主要字段
Rect矩形区域x, y, width, height
Circlecenter_x, center_y, radius
Line直线段x1, y1, x2, y2, angle
Measurement测量结果value, unit, status, deviation
DecodeResult条码/二维码解码结果content, format, confidence
OCRResult文字识别结果text, confidence, chars
MatchResult模板匹配结果score, x, y, angle
AnomalyResult异常检测结果anomaly_score, is_anomaly, heatmap
ClassifierResult分类结果class_id, class_name, probabilities

视觉专用函数

相机控制

函数说明语法
CAM_Open打开相机设备cam := CAM_Open(device_id)
CAM_Close关闭相机CAM_Close(cam)
CAM_SetParam设置相机参数CAM_SetParam(cam, param, value)
CAM_GetParam读取相机参数value := CAM_GetParam(cam, param)
CAM_Capture采集一帧图像img := CAM_Capture(cam, TIMEOUT:=ms)
CAM_StartStream启动连续采集CAM_StartStream(cam, callback)
CAM_StopStream停止连续采集CAM_StopStream(cam)

图像处理

函数说明语法
IMG_Read从文件加载图像img := IMG_Read(path)
IMG_Save保存图像到文件IMG_Save(img, path, format)
IMG_Resize缩放图像resized := IMG_Resize(img, w, h, mode)
IMG_CvtColor色彩空间转换gray := IMG_CvtColor(img, FORMAT_GRAY8)
IMG_GaussianBlur高斯滤波blurred := IMG_GaussianBlur(img, ksize, sigma)
IMG_MedianBlur中值滤波filtered := IMG_MedianBlur(img, ksize)
IMG_CannyCanny 边缘检测edges := IMG_Canny(img, low, high)
IMG_Threshold二值化binary := IMG_Threshold(img, thresh, maxval, type)
IMG_ROI提取感兴趣区域roi := IMG_ROI(img, rect)
IMG_DrawRect绘制矩形IMG_DrawRect(img, rect, color, thickness)
IMG_DrawText绘制文字IMG_DrawText(img, text, pos, color, scale)
IMG_MatchTemplate模板匹配result := IMG_MatchTemplate(img, templ, method)

目标检测

函数说明语法
OBJ_Detect目标检测result := OBJ_Detect(img, MODEL:="path")
OBJ_DetectCustom自定义配置推理result := OBJ_DetectCustom(img, cfg)
OBJ_Classify图像分类result := OBJ_Classify(img, MODEL:="path")
OBJ_Segment语义分割mask := OBJ_Segment(img, MODEL:="path")
OBJ_Anomaly异常检测result := OBJ_Anomaly(img, MODEL:="path")

测量

函数说明语法
MEAS_FindCircle拟合圆circle := MEAS_FindCircle(img, roi)
MEAS_FindLine拟合直线line := MEAS_FindLine(img, roi)
MEAS_DistancePP点间距dist := MEAS_DistancePP(p1, p2)
MEAS_DistancePL点到线距离dist := MEAS_DistancePL(point, line)
MEAS_Angle两线夹角angle := MEAS_Angle(line1, line2)
MEAS_Calibrate像素到物理单位mm := MEAS_Calibrate(pixels, scale)

识别

函数说明语法
DEC_Barcode条码识别result := DEC_Barcode(img, roi)
DEC_QRCodeQR 码识别result := DEC_QRCode(img, roi)
DEC_DataMatrixDataMatrix 识别result := DEC_DataMatrix(img, roi)
OCR_RecognizeOCR 文字识别result := OCR_Recognize(img, roi, lang)

结果输出

函数说明语法
VIS_WriteResult写结果到 PLC 变量VIS_WriteResult(result)
VIS_WriteVariable写指定 PLC 变量VIS_WriteVariable(name, value)
VIS_ReadVariable读 PLC 变量value := VIS_ReadVariable(name)
VIS_Log写入视觉日志VIS_Log(level, message)
VIS_SaveImage保存图像VIS_SaveImage(img, path)

完整示例

产品外观检测

PROGRAM SurfaceInspection
VAR_INPUT
trigger : BOOL;
END_VAR
VAR
cam : Camera;
img : Image;
result : DetectionResult;
defect_count : INT;
pass : BOOL;
END_VAR

// 打开相机
cam := CAM_Open("USB_CAM_1");

// 等待触发
IF trigger THEN
// 采集图像
img := CAM_Capture(cam, TIMEOUT := 3000);

// 预处理
img := IMG_CvtColor(img, FORMAT_GRAY8);
img := IMG_GaussianBlur(img, KSIZE := 5, SIGMA := 1.5);

// 目标检测 (缺陷检测模型)
result := OBJ_Detect(img, MODEL := "surface_defect.onnx");

// 判断结果
defect_count := result.object_count;
pass := (defect_count = 0);

// 输出结果
VIS_WriteVariable("VIS_DEFECT_COUNT", INT_TO_REAL(defect_count));
VIS_WriteVariable("VIS_INSPECT_PASS", BOOL_TO_REAL(pass));

// 有缺陷时保存图像
IF NOT pass THEN
VIS_SaveImage(img, "C:\Darra\HMI\defect_images\");
END_IF;

// 记录日志
VIS_Log(LOG_INFO, "检测完成: " +
(INT_TO_STRING(defect_count)) + " 个缺陷");
END_IF;

CAM_Close(cam);
END_PROGRAM

定位引导

PROGRAM RobotGuiding
VAR_INPUT
part_present : BOOL;
END_VAR
VAR
cam : Camera;
img : Image;
result : MatchResult;
offset_x, offset_y, offset_angle : REAL;
END_VAR

IF part_present THEN
cam := CAM_Open("GIGE_CAM_1");
img := CAM_Capture(cam, TIMEOUT := 2000);

// 模板匹配定位
result := IMG_MatchTemplate(img,
TEMPLATE := "reference_part.png",
METHOD := MATCH_NORMED);

IF result.score > 0.8 THEN
// 计算偏移
offset_x := result.x - 320.0; // 图像中心偏移
offset_y := result.y - 240.0;
offset_angle := result.angle;

// 写偏移量到 PLC (单位: mm)
VIS_WriteVariable("ROBOT_OFFSET_X", offset_x * 0.1);
VIS_WriteVariable("ROBOT_OFFSET_Y", offset_y * 0.1);
VIS_WriteVariable("ROBOT_OFFSET_ANGLE", offset_angle);
VIS_WriteVariable("VIS_JOB_DONE", 1.0);
ELSE
VIS_Log(LOG_WARN, "模板匹配失败, 评分=" +
REAL_TO_STRING(result.score));
VIS_WriteVariable("VIS_JOB_ERROR", 1.0);
END_IF;

CAM_Close(cam);
END_IF;
END_PROGRAM

注意事项

  1. 异步执行:Vision SCL 程序以 Job 形式异步执行,不会阻塞 PLC 扫描周期
  2. 内存管理:图像数据占用较大内存,使用后及时释放 IMG_Release(img)
  3. 超时处理:采集和推理操作必须设置超时,防止无限等待
  4. 模型路径:模型路径支持相对路径(相对于项目目录)和绝对路径
  5. 错误处理:视觉函数返回值包含状态码,建议检查后再继续