线材在生产制造过程中需要按规范的颜色来进行排序,以往用传统人工去检测易出现漏检、错检的情况,通过正运动技术机器视觉运动控制一体机线束颜色排序识别系统,可自动识别线束颜色及排列顺序是否有误或插错空位等情况。
它能够24小时不停止运行,工作效率高,提高产能。以及它的检测结果和人工检测相比一致性较高、可靠性强。
上期课程,我们讲述了机器视觉方案中零件分拣的应用例程,本期课程我们将和大家一起分享如何实现线束颜色排序识别的功能。
机器视觉运动控制一体机应用例程(九)线束颜色排序识别
一、 检测原理
(一)检测需求
识别出线束的线材颜色排序是否规范,并显示当前的线材识别的颜色和检测结果。
(二)软件算法
先用彩色相机拍摄图片后依次截取线束上不同颜色区域进行颜色样本学习,将颜色样本结果存放到列表中。
其次将RGB图像转为灰度图后用形状匹配工具学习模板,将模板位置结果作为基准位置。
当前匹配到的目标结果和基准位置结果进行计算输出位置变换矩阵,3个颜色识别的ROI区域和创建模板时设置的ROI区域位置使用同一个变换矩阵进行仿射变换,即使用形状匹配作为识别颜色区域的补正源。
最后将识别的线束颜色的颜色排序为“ red”“ black”“ yellow”才会输出“ OK”的状态结果,否则输出“ NG”的状态结果。
二 、软件实现
(一)软件实现
1.打开ZDevelop软件:新建项目→新建“HMI”文件→新建“main.bas”文件,用于编写界面响应函数→新建“global_variable.bas”文件用于存放全局变量并开启HMI自动运行任务→新建“InitLocator.bas”文件用于初始化测量参数→新建“camera.bas”文件用于实现相机采集功能→新建draw.bas文件用于更新绘制图形刷新界面→文件添加到项目。
2.设计HMI界面。
3.在“global_variable.bas”文件中定义全局变量,定义完成后运行“Hmi.hmi”文件。
'''''全局变量大部分使用数组结构'''''
''注:basic编程中很多函数会以TABLE(系统的数据结构)做为参数
''table 说明 table 说明
''0~1 获取到的图像宽高 15~18 定位器roi图像坐标数据
''0~1 匹配结果矩阵的行列数 25~28 定位器roi控件和图像数据
''3~7 匹配结果 30~31 橡皮擦roi坐标
''11~12 鼠标操作时获取的坐标 50~81 线1识别颜色结果
''82~113 线2识别颜色结果 114~145 线3识别颜色结果
''160 识别分数 150 线1识别ID
''151 线2识别ID 152 线3识别ID
''170~172 线1ROI区域数据 173~175 线2ROI区域数据
''176~178 线3ROI区域数据
''225~228 训练样本ROI控件坐标数据 231~235 线1ROI控件坐标数据
''331~335 线2ROI控件坐标数据 431~435 线3ROI控件坐标数据
''VR(0) 模板保存标志,1-已保存 VR(1) 参数保存标志,1-已保存
''VR(10)~(18)模板参数断电保存地址 VR(20)~(26)匹配参数断电保存地址
''VR(30)~(34)线1ROI坐标数据 VR(40)~(44)线2ROI坐标数据
''VR(50)~(54)线3ROI坐标数据 VR(60)~(63)训练学习ROI坐标数据
''VR(70)~(74)匹配基准数据 VR(76) 识别分数
'***********定义程序任务相关变量**********************
'主任务状态
'0 - 未初始化
'1 - 停止
'2 - 运行中
'3 - 正在停止
GLOBAL DIM main_task_state
main_task_state = 1
'运行任务开关
GLOBAL DIM run_switch
run_switch = 0
'采集任务开关
'0 - 停止采集
'1 - 请求采集
GLOBAL DIM grab_switch
grab_switch = 0
'定位检测主任务id - 10
GLOBAL DIM main_task_id
main_task_id = 10
'相机连续采集线程id - 7
GLOBAL DIM grab_task_id
grab_task_id = 7
'***********结束定义程序任务相关变量******************
'***********定义相机采集相关变量**********************
'相机种类,此处使用海康相机-"mvision"
GLOBAL DIM CAMERA_TYPE(100)
'CAMERA_TYPE = "mindvision;basler;mvision;huaray;zmotion"
CAMERA_TYPE = "mvision"
'相机个数
GLOBAL cam_num
cam_num = 0
'相机模式,-1 连续采集,0-软件触发采集
GLOBAL cam_mode
cam_mode = 0
'***********结束定义相机采集相关变量******************
'定义返回主界面标志,1-已返回,0-未返回
GLOBAL DIM d_is_rtn_loc
d_is_rtn_loc = 1
'***********定义模板相关变量*************************
'定义鼠标按下标志位,1-已按下,0-未按下
GLOBAL DIM is_set_roi_m_down
is_set_roi_m_down = 0
'定义创建模板标志位,1-已创建模板,0-未创建模板
GLOBAL DIM d_is_creModel
d_is_creModel = 0
'学习模板参数,starAngle、endAngle、minScale、maxScale、thresh、numlevel、reduce、angleStep、scaleStep
GLOBAL DIM d_mod_param(9)
'***********结束定义模板相关变量**********************
'***********定义编辑模板相关变量*********************
'定义编辑模板标志,0-表示不编辑模板,1-表示编辑模板
GLOBAL DIM d_edit_m
d_edit_m = 0
'定义使用橡皮擦功能标志,0-表示恢复擦除的区域,1-表示擦除区域
GLOBAL DIM d_isMask_m
d_isMask_m = 1
'定义橡皮擦的roi参数,依次是矩形左上角和右下角图像坐标x、y、x、y
GLOBAL DIM d_locator_roi(4),d_eraser_roi(4)
'定义正方形橡皮擦尺寸宽度
GLOBAL DIM d_eraser_size
d_eraser_size = 5
'定义界面控件上橡皮擦的矩形区域
GLOBAL DIM c_rect(4)
'定义鼠标状态标志,0-表示鼠标处于松开状态,1-表示鼠标处于按下状态
GLOBAL DIM d_mouse_s
d_mouse_s = 0
'***********结束定义编辑模板相关变量******************
'***********定义匹配检测相关变量*********************
'匹配检测参数,minScore、matchNum、minDist、thresh、accuracy、speed、polor
GLOBAL DIM d_match_param(7)
'定义学习模板的roi参数和橡皮擦的roi参数,依次是矩形左上角和右下角图像坐标x、y、x、y
GLOBAL DIM d_locator_roi(4),d_eraser_roi(4)
'匹配结果,score、x、y、angle、scale, 目前对于多目标匹配也只存第一个目标
GLOBAL DIM d_match_rst(5)
GLOBAL DIM d_match_time '定义匹配定位消耗的时间变量
d_match_time = 0
'***********结束定义匹配检测相关变量******************
'定义程序执行过程中缓存中间图片和结果图片的变量
GLOBAL ZVOBJECT grabImg,colorImg
GLOBAL ZVOBJECT subImg,copy_subImg,colorSubImg, s_mod
GLOBAL ZVOBJECT modRe
'定义程序执行过程中颜色样本模板变量和颜色模板列表变量
GLOBAL ZVOBJECT grabImg,ColorMod,Clrmod_list
'设置创建模板的基准坐标
GLOBAL DIM d_match_base_rst(5)
'定义检测识别颜色的ROI区域
GLOBAL DIM d_reg_roi1(5),d_reg_roi2(5),d_reg_roi3(5)
'定义训练学习颜色样本的ROI区域
GLOBAL DIM d_learn_roi(4)
'定义选择颜色识别ROI的类型
GLOBAL DIM d_select_regROI
d_select_regROI=0
'定义排线颜色顺序检测结果状态
GLOBAL DIM d_rst_status
d_rst_status=0
'常用颜色变量
GLOBAL C_RED, C_GREEN, C_BLUE, C_YELLOW,C_WHITE
C_RED = RGB(255, 0, 0)
C_GREEN = RGB( 0,255, 0)
C_BLUE = RGB( 0, 0,255)
C_YELLOW= RGB(255,255, 0)
C_WHITE = RGB(255,255, 255)
'定义输入需要进行学习的颜色样本名称
GLOBAL DIM d_sample_name(128)
d_sample_name=""
'定义检测到的颜色结果
GLOBAL DIM d_color_rst1(32),d_color_rst2(32),d_color_rst3(32)
GLOBAL DIM d_detect_time '定义消耗的时间变量
d_detect_time = 0
'***********定义读取本地文件功能相关变量**************
''注意,该功能只在使用仿真器时有效
'定义是否使用本地图片标志
GLOBAL DIM d_use_imgfile
'定义本地图片索引
GLOBAL DIM d_index
'定义读取图片的路径
GLOBAL DIM File_Name(100)
'***********结束定义读取本地文件功能相关变量**********
'初始化全局变量完成后开启HMI文件
RUN"Hmi1.hmi",1
4.在“InitLocator.bas”文件中初始化测量参数。
end
GLOBAL SUB init_meas_param() '初始化测量参数
'初始化定位器roi参数
d_locator_roi(0) = 240 '左上角x
d_locator_roi(1) = 180 '左上角y
d_locator_roi(2) = 400 '右下角x
d_locator_roi(3) = 300 '右下角y
'初始化模板参数
d_mod_param(0) = -180 '起始角度
d_mod_param(1) = 180 '终止角度
d_mod_param(2) = 1 '最小缩放
d_mod_param(3) = 1 '最大缩放
d_mod_param(4) = 80 '阈值
d_mod_param(5) = 0 '默认金字塔层数
d_mod_param(6) = 0 '默认约简特征点
d_mod_param(7) = 0 '默认角度步长
d_mod_param(8) = 0 '默认缩放步长
'初始化匹配测量参数
d_match_param(0) = 50 '最小分数
d_match_param(1) = 1 '匹配个数
d_match_param(2) = 10 '默认最小间距
d_match_param(3) = 40 '最小阈值
d_match_param(4) = 0 '精度
d_match_param(5) = 9 '速度
d_match_param(6) = 0 '极性
'初始化匹配定位结果
d_match_rst(0) = 0 '分数
d_match_rst(1) = 0 '位置X
d_match_rst(2) = 0 '位置Y
d_match_rst(3) = 0 '角度
d_match_rst(4) = 0 '比例
d_reg_roi1(0)=160 '识别颜色ROI1
d_reg_roi1(1)=110
d_reg_roi1(2)=40
d_reg_roi1(3)=40
d_reg_roi1(4)=0
d_reg_roi2(0)=260 '识别颜色ROI1
d_reg_roi2(1)=110
d_reg_roi2(2)=40
d_reg_roi2(3)=40
d_reg_roi2(4)=0
d_reg_roi3(0)=360 '识别颜色ROI1
d_reg_roi3(1)=110
d_reg_roi3(2)=40
d_reg_roi3(3)=40
d_reg_roi3(4)=0
d_learn_roi(0)=360
d_learn_roi(1)=190
d_learn_roi(2)=400
d_learn_roi(3)=230
TABLE(160) = 60
'初始化匹配定位消耗时间
d_match_time = 0
d_use_imgfile = 1 '默认使用本地图片
d_index = 0
END SUB
5.关联HMI界面控件变量。
6.在“main.bas”文件中添加HMI界面初始化函数并在Hmi系统设置中关联初始化函数。
end
'HMI界面初始化函数,上电执行一次
GLOBAL SUB hmi_init()
ZV_ENVINIT()
DMSET table(50,96,0)
ZV_SETSYSSTR("DataDir","") '设置默认数据目录
ZV_SETSYSINT("LineWidth",6) '设置线宽为 10
ZV_RESETCLIPSIZE(1280, 1024) '根据图像分辨率设置图像区域的裁剪尺寸,此处图像分辨率为1280x1024
ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(10, 2), HMI_CONTROLSIZEY(10, 2)) '设置锁存的大小
init_meas_param() '初始化测量参数
ZV_IMGGENCONST(subImg,40,30,1,0,0) '初始化模板子图像
'初始化匹配使用到的中间变量
ZVOBJECT contlist1, tsContlist1, mat_rigid1
ZVOBJECT contlist2, tsContlist2, mat_rigid2
ZV_IMGREAD(colorImg,"颜色排序/0.bmp",0)
ZV_LATCH(colorImg, 0)
if VR(0)=1 then '如果已经保存过模板
ZV_READSHAPEMOD(s_mod,"颜色排序/shape.zvb") '读取当前路径下的形状模板
?"读取模板成功!"
d_is_creModel = 1
ZV_READIMAGE(subImg,"颜色排序/subimg.bmp",0) '读取模板子图像
ZV_SHAPECONTOURS(s_mod, contlist1, 0) '将模板轮廓绘制在子图像上并显示在锁存通道2中
ZV_GRAYTORGB(subImg, colorSubImg)
ZV_IMGINFO(colorSubImg, 0)
ZV_GETRIGIDVECTOR(mat_rigid1, 0, 0, 0, TABLE(0)/2, TABLE(1)/2, 0)
ZV_CONTAFFINE(contlist1, mat_rigid1, tsContlist1)
ZV_CONTLIST(colorSubImg, tsContlist1, ZV_COLOR(0, 255, 0), 0)
ZV_LATCHCLEAR(2)
ZV_LATCH(colorSubImg, 2)
endif
if VR(1)=1 then '如果已经保存过模板匹配参数
for i=0 to 8
d_mod_param(i)=VR(10+i)
next
for i=0 to 6
d_match_param(i)=VR(20+i)
next
for i=0 to 4
d_reg_roi1(i)=VR(30+i)
d_reg_roi2(i)=VR(40+i)
d_reg_roi3(i)=VR(50+i)
d_match_base_rst(i)=VR(70+i)
next
for i=0 to 3
d_learn_roi(i)=VR(60+i)
next
TABLE(160)=VR(76)
endif
'将ROI1的中心坐标x,y,宽,高,角度等图像坐标数据转换到控件坐标数据
TABLE(231,d_reg_roi1(0),d_reg_roi1(1))
ZV_POSFROMIMG(0, 1, 231, 231)
TABLE(233) = ZV_LENFROMIMG(0, d_reg_roi1(2))
TABLE(234) = ZV_LENFROMIMG(0, d_reg_roi1(3))
TABLE(235) = d_reg_roi1(4)
'将ROI2的中心坐标x,y,宽,高,角度等图像坐标数据转换到控件坐标数据
TABLE(331,d_reg_roi2(0),d_reg_roi2(1))
ZV_POSFROMIMG(0, 1, 331, 331)
TABLE(333) = ZV_LENFROMIMG(0, d_reg_roi2(2))
TABLE(334) = ZV_LENFROMIMG(0, d_reg_roi2(3))
TABLE(335) = d_reg_roi2(4)
'将ROI3的中心坐标x,y,宽,高,角度等图像坐标数据转换到控件坐标数据
TABLE(431,d_reg_roi3(0),d_reg_roi3(1))
ZV_POSFROMIMG(0, 1, 431, 431)
TABLE(433) = ZV_LENFROMIMG(0, d_reg_roi3(2))
TABLE(434) = ZV_LENFROMIMG(0, d_reg_roi3(3))
TABLE(435) = d_reg_roi3(4)
ZV_LATCHCLEAR(0) '清空锁存通道
END SUB
7.在“camera.bas”文件中添加HMI界面中采集相关按钮响应的函数并关联动作函数。( 说明:具体实现函数前面两篇课程内容已经有操作演示,此处不做赘述。)
8.点击[元件]→[新建窗口],新建学习颜色样本窗口,设计窗口布局,并关联变量和设置软键盘窗口号。
9.在“main.bas”文件中添加主界面【训练样本】按钮响应的函数并关联动作函数。
'HMI界面按下训练样本按钮时响应的函数
GLOBAL SUB btn_OpenLearning()
ZV_LATCHCLEAR(0)
ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(13, 1), HMI_CONTROLSIZEY(13, 1)) '设置创建模板窗口锁存通道0的锁存大小
ZV_LATCH(colorImg,0)
'将训练学习ROI的中心坐标x,y,宽,高,角度等图像坐标数据转换到控件坐标数据
TABLE(225,d_learn_roi(0),d_learn_roi(1),d_learn_roi(2),d_learn_roi(3))
ZV_POSFROMIMG(0,2, 225, 225)
HMI_SHOWWINDOW(13)
END SUB
10.在“main.bas”文件中添加学习颜色样本界面【学习样本】按钮响应的函数并关联动作函数。
'定义训练颜色样本界面按下学习样本按钮时响应的函数
GLOBAL SUB btn_Learning()
ZVOBJECT region
ZV_REGENRECT(region,d_learn_roi(0),d_learn_roi(1),d_learn_roi(2)-d_learn_roi(0)+1,d_learn_roi(3)-d_learn_roi(1)+1) '生成矩形区域
if (STRCOMP(d_sample_name, "")=0) then
?"请先输入需要学习的颜色样本名称!"
return
else
ZV_CLRGENMODELRE(colorImg,region,ColorMod,d_sample_name,0)'在 RGB 颜色空间生成颜色模型
ZV_LISTINSERT(ColorMod,Clrmod_list,-1) '将颜色模型插入到列表
?"学习"d_sample_name"样本成功!"
endif
END SUB
11.在“main.bas”文件中添加学习颜色样本界面【清空样本】按钮响应的函数并关联动作函数。
'定义训练颜色样本界面按下清空样本按钮时响应的函数
GLOBAL SUB btn_Clear()
if(ZV_ISEMPTY(Clrmod_list)=0) then '如果训练样本库不为空
ZV_CLEAR(Clrmod_list)
?"已清空样本列表!"
endif
END SUB
12.在“main.bas”文件中添加学习颜色样本界面【确定】按钮响应的函数并关联动作函数。
'定义训练颜色样本界面按下确定按钮时响应的函数
GLOBAL SUB btn_Confirm()
HMI_CLOSEWINDOW(13)
ZV_LATCHCLEAR(0)
ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(10, 2), HMI_CONTROLSIZEY(10, 2))
ZV_LATCH(colorImg,0)
END SUB
13.在“draw.bas”文件中添加学习样本区域更新绘制函数,并在学习颜色样本界面的自定义控件上关联刷新函数名和绘图函数名。
'根据鼠标操作更新训练颜色样本的有效区域
GLOBAL SUB update_learnroi()
if mouse_scan(11) = 1 then '扫描鼠标按下操作
is_set_roi_m_down = 1 '鼠标按下标志置1
sr_mpos_x = table(11) '将当前鼠标按下位置的坐标赋值给变量
sr_mpos_y = table(12)
'只有按下时可以改变击中位置,获取鼠标点击位置对应的击中区域编号
hit_pos = ZV_HMIADJRECT(sr_mpos_x, sr_mpos_y, 225, -1)
is_redraw = 1 '绘图标志置1
endif
if mouse_scan(11) = -1 then '扫描鼠标松开操作
is_set_roi_m_down = 0 '鼠标按下标志置0
sr_mpos_x = table(11) '将当前鼠标松开位置的坐标赋值给变量
sr_mpos_y = table(12)
'根据区域编号调整定位器区域位置
ZV_HMIADJRECT(sr_mpos_x, sr_mpos_y, 225, hit_pos)
is_redraw = 1 '绘图标志置1
endif
'如果鼠标按下时
if (is_set_roi_m_down and MOUSE_state(11)) then
sr_mpos_x = table(11) '将当前鼠标按下位置的坐标赋值给变量
sr_mpos_y = table(12)
'根据区域编号调整定位器区域位置
ZV_HMIADJRECT(sr_mpos_x, sr_mpos_y, 225, hit_pos)
is_redraw = 1 '绘图标志置1
endif
if (1 = is_redraw) then '如果绘制标志=1
is_redraw = 0 '将绘制标志置0
'控件roi坐标转图像roi坐标,控件坐标存放在起始地址为25的数组,图像坐标存放在起始地址为15的数组
ZV_POSTOIMG(0, 2, 225, 15)
'将图像坐标的数据赋值给ROI变量中
d_learn_roi(0) = TABLE(15)
d_learn_roi(1) = TABLE(16)
d_learn_roi(2) = TABLE(17)
d_learn_roi(3) = TABLE(18)
SET_REDRAW '重新绘制全部区域
endif
END SUB
'根据更新的鼠标位置坐标绘制训练颜色样本区域
GLOBAL SUB draw_learnroi()
'根据控件坐标数据绘制矩形
DRAWRECT(TABLE(225), TABLE(226), TABLE(227), TABLE(228))
local cx,cy '定义局部变量
cx = (TABLE(225) + TABLE(227)) / 2 '计算矩形的中心坐标x、y
cy = (TABLE(226) + TABLE(228)) / 2
DRAWLINE(cx-5, cy, cx+5, cy) '绘制中心十字线
DRAWLINE(cx, cy-5, cx, cy+5)
END SUB
14.点击[元件]→[新建窗口],新建学习模板窗口,设计窗口布局,关联变量。
15.在“draw.bas”文件中添加主界面按下【学习模板】按钮响应的函数并关联动作函数。
'主界面按下学习模板按钮时响应的函数
GLOBAL SUB btn_sel_loc()
ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(11, 60), HMI_CONTROLSIZEY(11, 60)) '设置创建模板窗口锁存通道0的锁存大小
SET_COLOR(RGB(0,255,0)) '指定draw指令使用的颜色
ZV_LATCHCLEAR(0) '将锁存通道0清空
ZV_LATCH(grabImg, 0) '将采集图像显示到锁存通道0中
ZV_LATCH(colorSubImg, 1) '将模板图像显示到锁存通道1中
is_redraw = 0 '将绘图标志置0
d_is_rtn_loc = 0 '将返回界面标志置0
'将模板区域的图像坐标存放到起始地址为25的table数组中
TABLE(25, d_locator_roi(0), d_locator_roi(1),d_locator_roi(2),d_locator_roi(3))
ZV_POSFROMIMG(0, 2, 25, 25) '将图像坐标转换到HMI控件坐标
HMI_SHOWWINDOW(11) '弹出窗口号为11的创建模板窗口
END SUB
16.在“draw.bas”文件中添加模板区域更新绘制函数,并在学习模板界面的自定义控件上关联刷新函数名和绘图函数名。
'根据鼠标操作更新定位器的区域即学习模板的有效区域
GLOBAL SUB update_locator()
if mouse_scan(11) = 1 then '扫描鼠标按下操作
is_set_roi_m_down = 1 '鼠标按下标志置1
sr_mpos_x = table(11) '将当前鼠标按下位置的坐标赋值给变量
sr_mpos_y = table(12)
'只有按下时可以改变击中位置,获取鼠标点击位置对应的击中区域编号
hit_pos = ZV_HMIADJRECT(sr_mpos_x, sr_mpos_y, 25, -1)
is_redraw = 1 '绘图标志置1
endif
if mouse_scan(11) = -1 then '扫描鼠标松开操作
is_set_roi_m_down = 0 '鼠标按下标志置0
sr_mpos_x = table(11) '将当前鼠标松开位置的坐标赋值给变量
sr_mpos_y = table(12)
'根据区域编号调整定位器区域位置
ZV_HMIADJRECT(sr_mpos_x, sr_mpos_y, 25, hit_pos)
is_redraw = 1 '绘图标志置1
endif
'如果鼠标按下时
if (is_set_roi_m_down and MOUSE_state(11)) then
sr_mpos_x = table(11) '将当前鼠标按下位置的坐标赋值给变量
sr_mpos_y = table(12)
'根据区域编号调整定位器区域位置
ZV_HMIADJRECT(sr_mpos_x, sr_mpos_y, 25, hit_pos)
is_redraw = 1 '绘图标志置1
endif
if (1 = is_redraw) then '如果绘制标志=1
is_redraw = 0 '将绘制标志置0
'控件roi坐标转图像roi坐标,控件坐标存放在起始地址为25的数组,图像坐标存放在起始地址为15的数组
ZV_POSTOIMG(0, 2, 25, 15)
'将图像坐标的数据赋值给ROI变量中
d_locator_roi(0) = TABLE(15)
d_locator_roi(1) = TABLE(16)
d_locator_roi(2) = TABLE(17)
d_locator_roi(3) = TABLE(18)
SET_REDRAW '重新绘制全部区域
endif
END SUB
'根据更新的鼠标位置坐标绘制定位器roi
GLOBAL SUB draw_locator()
'根据控件坐标数据绘制矩形
DRAWRECT(TABLE(25), TABLE(26), TABLE(27), TABLE(28))
local cx,cy '定义局部变量
cx = (TABLE(25) + TABLE(27)) / 2 '计算矩形的中心坐标x、y
cy = (TABLE(26) + TABLE(28)) / 2
DRAWLINE(cx-5, cy, cx+5, cy) '绘制中心十字线
DRAWLINE(cx, cy-5, cx, cy+5)
END SUB
17.在“main.bas”文件中添加【截取模板】按钮响应的函数并关联动作函数。
'创建模板界面按下截取模板按钮后响应的函数
GLOBAL SUB btn_getSubImg()
LOCAL mod_w,mod_h
'根据ROI数据生成模板子图像
ZV_IMGGETSUB(grabImg, subImg, d_locator_roi(0), d_locator_roi(1), d_locator_roi(2)-d_locator_roi(0)+1, d_locator_roi(3)-d_locator_roi(1)+1)
'获取图像信息,存放到起始地址为0的table数组中
ZV_IMGINFO(subImg,0)
mod_w = TABLE(0)
mod_h = TABLE(1)
'根据图像信息生成模板区域
ZV_REGENRECT(modRe,0,0,mod_w, mod_h)
'清空锁存通道1
ZV_LATCHCLEAR(1)
'将模板子图像显示到锁存通道1中
ZV_LATCH(subImg, 1)
END SUB
18.点击[元件]→[新建窗口],新建编辑模板窗口,设计窗口布局,并关联变量。
19.在“draw.bas”文件中添加创建模板界面【橡皮擦】按钮响应的函数并关联动作函数。
'创建模板界面按下橡皮擦按钮时响应的函数
GLOBAL SUB btn_sel_erase()
ZV_LATCHSETSIZE(1, HMI_CONTROLSIZEX(12, 1), HMI_CONTROLSIZEY(12, 1)) '设置锁存通道1的大小
SET_COLOR(RGB(0,255,0)) '设置绘制时画笔使用的颜色
ZV_LATCHCLEAR(1) '清空锁存通道1
ZV_IMGCOPY(subImg, copy_subImg) '复制模板子图像到copy_subImg图像变量中
ZV_REGION(copy_subImg, modRe, 1, 0) '在模板图像上绘制modRe图像的非有效区域,绘制颜色为黑色,用于掩模
ZV_LATCH(copy_subImg, 1) '显示复制的模板图
HMI_SHOWWINDOW(12) '打开编辑模板窗口
END SUB
20.在“draw.bas”文件中添加橡皮擦更新绘制函数,并在编辑模板界面的自定义控件上关联刷新函数名和绘图函数名。
'根据鼠标操作更新橡皮擦擦除/恢复区域的位置
GLOBAL SUB update_eraser()
DIM c_size_eraser '橡皮擦在控件上对应的尺寸
DIM eraser_pos_x,eraser_pos_y
d_mouse_s = MOUSE_STATE(11) '鼠标处于按下状态时
eraser_pos_x = TABLE(11) '将当前鼠标按下位置的坐标赋值给橡皮擦控件坐标变量
eraser_pos_y = TABLE(12)
c_size_eraser = ZV_LENFROMIMG(0, d_eraser_size) '将橡皮擦的图像尺寸转换成控件尺寸
'生成以(eraser_pos_x,eraser_pos_y)为中心,2*c_size_eraser为边长的正方形橡皮擦区域
c_rect(0, eraser_pos_x - c_size_eraser, eraser_pos_y - c_size_eraser, eraser_pos_x + c_size_eraser, eraser_pos_y + c_size_eraser)
DIM hmi_w,hmi_h
'限制橡皮擦坐标在图片元件区域内
if (eraser_pos_x >= c_size_eraser) and (eraser_pos_y >= c_size_eraser) and (eraser_pos_x <= HMI_CONTROLSIZEX(12, 1) - c_size_eraser)and (eraser_pos_y <= HMI_CONTROLSIZEy(12, 1) - c_size_eraser) THEN
'重新绘制编辑模板窗口上的锁存通道0区域
SET_REDRAW(0,0, HMI_CONTROLSIZEX(12, 1), HMI_CONTROLSIZEY(12, 1))
endif
if d_mouse_s = 1 and d_edit_m = 1 then '如果鼠标处于按下状态且编辑模板标志=1时
btn_pro_eraser() '执行处理橡皮擦函数
endif
END SUB
'处理橡皮擦函数
GLOBAL SUB btn_pro_eraser()
ZVOBJECT tmp_re
'将橡皮擦区域的左上角坐标x,y存放到起始地址为30的数组中
TABLE(30, c_rect(0), c_rect(1))
'将控件坐标转换到图像坐标中
ZV_POSTOIMG(1, 1, 30, 30)
'根据图像坐标系下的数据生成正方形橡皮擦区域,并存放到tmp_re变量中
ZV_REGENRECT(tmp_re, TABLE(30), TABLE(31), 2 * d_eraser_size + 1, 2 * d_eraser_size + 1)
if (d_isMask_m = 1) then '如果选择屏蔽功能
ZV_REDIFF(modRe, tmp_re, modRe) '计算modRe和tmp_re的差集并存放到modRe中,即取橡皮擦区域以外的模板子图像区域
else '如果选择恢复功能
ZV_REUNION(modRe, tmp_re, modRe) '计算modRe和tmp_re的并集并存放到modRe中,即取当前模板子图像区域
endif
ZV_IMGCOPY(subImg, copy_subImg) '复制模板子图像到copy_subImg图像变量中
ZV_REGION(copy_subImg, modRe, 1, 0) '在模板图像上绘制modRe图像的非有效区域,绘制颜色为黑色,用于掩模
ZV_LATCH(copy_subImg, 1) '显示复制的模板图
END SUB
'更新绘制橡皮擦区域
GLOBAL SUB draw_eraser()
if d_edit_m = 0 then '如果编辑模板标志为0
return '返回子函数,不继续往下执行
endif
'绘制正方形橡皮擦区域
DRAWRECT(c_rect(0), c_rect(1), c_rect(2), c_rect(3))
END SUB
21.在“main.bas”文件中添加编辑模板界面【创建模板】按钮响应的函数并关联动作函数。
'编辑模板界面按下创建模板按钮时响应的函数
GLOBAL SUB btn_loc_creModel()
d_is_creModel = 1 '创建模板标志置1
'根据模板参数和模板子图像创建模板,并将模板结果存放到s_mod变量中
ZV_SHAPECREATERE(subImg, modRe,s_mod, d_mod_param(0), d_mod_param(1), d_mod_param(2), d_mod_param(3), d_mod_param(4), d_mod_param(5), d_mod_param(6), d_mod_param(7), d_mod_param(8))
ZV_SHAPECONTOURS(s_mod, contlist1, 0) '获取第0层金字塔上的模板轮廓
ZV_GRAYTORGB(subImg, colorSubImg) '灰度图转换成RGB图
ZV_IMGINFO(colorSubImg, 0) '获取colorSubImg图像信息,并存放到table0中
ZV_GETRIGIDVECTOR(mat_rigid1, 0, 0, 0, TABLE(0)/2, TABLE(1)/2, 0)'计算刚性变换矩阵
ZV_CONTAFFINE(contlist1, mat_rigid1, tsContlist1)'对轮廓或轮廓序列进行仿射变换
ZV_CONTLIST(colorSubImg, tsContlist1, ZV_COLOR(0, 255, 0), 0)'在colorSubImg图像上绘制绿色的轮廓序列
ZV_LATCHCLEAR(2) '清空锁存通道2
ZV_LATCH(colorSubImg, 2) '显示图像结果到锁存通道2中
btn_loc_test()
d_match_base_rst(0) = d_match_rst(0)
d_match_base_rst(1) = d_match_rst(1)
d_match_base_rst(2) = d_match_rst(2)
d_match_base_rst(3) = d_match_rst(3)
d_match_base_rst(4) = d_match_rst(4)
END SUB
22.在“main.bas”文件中添加编辑模板界面【保存模板】按钮响应的函数并关联动作函数。
'编辑模板界面按下保存模板按钮时响应的函数
GLOBAL SUB btn_loc_savModel()
if d_is_creModel = 1 then
ZV_WRITESHAPEMOD(s_mod,"颜色排序/shape.zvb")
ZV_WRITEIMAGE(subImg,"颜色排序/subimg.bmp",0)
VR(0)=1
?"保存模板成功!"
else
?"请先创建模板!"
return
endif
END SUB
23.在“main.bas”文件中添加编辑模板界面【读取模板】按钮响应的函数并关联动作函数。
'编辑模板界面按下读取模板按钮时响应的函数
GLOBAL SUB btn_loc_redModel()
if VR(0)=1 then
ZV_READSHAPEMOD(s_mod,"颜色排序/shape.zvb")
?"读取模板成功!"
else
?"请先保存模板!"
return
endif
END SUB
24.在“draw.bas” 文件中添加编辑模板界面【确定】按钮响应的函数并关联动作函数。
'创建模板界面按下确定按钮时响应的函数
GLOBAL SUB btn_loc_cfm()
grab_switch = 0 '关闭补正源的连续采集
d_is_rtn_loc = 1 '返回主界面标志置为1
'设置锁存通道0的大小
ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(10, 2), HMI_CONTROLSIZEY(10, 2))
ZV_LATCHCLEAR(0) '清空锁存通道0
ZV_LATCH(colorImg, 0) '显示图像在锁存通道0上
HMI_CLOSEWINDOW(11) '关闭创建模板窗口
END SUB
25.在“main.bas”文件中添加创建模板界面【测试】按钮响应的函数并关联动作函数。
'创建模板界面按下测试按钮时响应的函数
GLOBAL SUB btn_loc_test()
if (d_is_creModel = 0) then '如果创建模板标志=0
?"未创建模板!" '提示未创建模板毛病返回子函数不往下执行
return
endif
'开始匹配
TICKS = 0 '开始计时
ZVOBJECT match_rst, sImg, showImg
'对图像进行3*3高斯平滑处理,处理后的图像输出到sImg变量中
ZV_GAUSSBLUR(grabImg, sImg, 3)
'根据模板子图像和搜索参数进行目标匹配,并将匹配结果存放到match_rst矩阵中
ZV_SHAPEFIND(s_mod, sImg, match_rst, d_match_param(0), d_match_param(1), d_match_param(2), d_match_param(3), d_match_param(4), d_match_param(5), d_match_param(6))
ZV_MATINFO(match_rst, 0) '获取矩阵结果信息。并存放到起始地址为0的table数组中
' ZV_GRAYTORGB(sImg, showImg) '灰度图转换到RGB图,作为匹配结果图像
if TABLE(0) > 0 then '如果匹配到目标
local rowr
for rowr = 0 to TABLE(0)-1
'获取match_rst矩阵中第rowr行的数据存放到起始地址为3的table数组中,table最大长度5
ZV_MATGETROW(match_rst, rowr, 5, 3)
if(rowr = 0) then '取第一行的匹配结果信息即第一个匹配目标的结果
d_match_rst(0) = TABLE(3) '将匹配结果赋值给定义的结果变量,显示到界面
d_match_rst(1) = TABLE(4)
d_match_rst(2) = TABLE(5)
d_match_rst(3) = TABLE(6)
d_match_rst(4) = TABLE(7)
'计算刚性变换矩阵
ZV_GETRIGIDVECTOR(mat_rigid1, 0, 0, 0, TABLE(4), TABLE(5), TABLE(6))
'对轮廓或轮廓序列进行仿射变换
ZV_CONTAFFINE(contlist1, mat_rigid1, tsContlist1)
'在colorSubImg图像上绘制绿色的轮廓序列
ZV_CONTLIST(colorImg, tsContlist1, ZV_COLOR(0, 255, 0), 0)
endif
next
else '未匹配到目标时,将结果赋值为-1
d_match_rst(0) = -1
d_match_rst(1) = -1
d_match_rst(2) = -1
d_match_rst(3) = -1
d_match_rst(4) = -1
endif
d_match_time = abs(TICKS) '计算匹配消耗时间
ZV_LATCH(colorImg, 0) '显示匹配结果图像
END SUB
26.在“draw.bas”文件中添加创建模板界面【确定】按钮响应的函数并关联动作函数。
'创建模板界面按下确定按钮时响应的函数
GLOBAL SUB btn_loc_cfm()
grab_switch = 0 '关闭补正源的连续采集
d_is_rtn_loc = 1 '返回主界面标志置为1
'设置锁存通道0的大小
ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(10, 2), HMI_CONTROLSIZEY(10, 2))
ZV_LATCHCLEAR(0) '清空锁存通道0
ZV_LATCH(colorImg, 0) '显示图像在锁存通道0上
HMI_CLOSEWINDOW(11) '关闭创建模板窗口
END SUB
27.在main.bas文件中添加主界面【测试】按钮响应的函数并关联动作函数。
'主界面按下测试按钮时响应的函数
GLOBAL SUB btn_test()
TICKS=0
DMSET d_color_rst1(0,4,0)
DMSET d_color_rst2(0,4,0)
DMSET d_color_rst3(0,4,0)
d_rst_status=0
ZVOBJECT regionMask1,regionMask2,regionMask3
'先进行匹配定位,补正ROI位置
if (d_is_creModel = 0) then '如果创建模板标志=0
?"未创建模板!" '提示未创建模板毛病返回子函数不往下执行
return
endif
ZVOBJECT match_rst, sImg, showImg
'对图像进行3*3高斯平滑处理,处理后的图像输出到sImg变量中
ZV_GAUSSBLUR(grabImg, sImg, 3)
'根据模板子图像和搜索参数进行目标匹配,并将匹配结果存放到match_rst矩阵中
ZV_SHAPEFIND(s_mod, sImg, match_rst, d_match_param(0), d_match_param(1), d_match_param(2), d_match_param(3), d_match_param(4), d_match_param(5), d_match_param(6))
ZV_MATINFO(match_rst, 0) '获取矩阵结果信息。并存放到起始地址为0的table数组中
ZV_IMGCOPY(colorImg,showImg)
if TABLE(0) > 0 then '如果匹配到目标
local rowr
for rowr = 0 to TABLE(0)-1
'获取match_rst矩阵中第rowr行的数据存放到起始地址为3的table数组中,table最大长度5
ZV_MATGETROW(match_rst, rowr, 5, 3)
if(rowr = 0) then '取第一行的匹配结果信息即第一个匹配目标的结果
d_match_rst(0) = TABLE(3) '将匹配结果赋值给定义的结果变量,显示到界面
d_match_rst(1) = TABLE(4)
d_match_rst(2) = TABLE(5)
d_match_rst(3) = TABLE(6)
d_match_rst(4) = TABLE(7)
'计算刚性变换矩阵
ZV_GETRIGIDVECTOR(mat_rigid1, 0, 0, 0, TABLE(4), TABLE(5), TABLE(6))
'对轮廓或轮廓序列进行仿射变换
ZV_CONTAFFINE(contlist1, mat_rigid1, tsContlist1)
'在colorSubImg图像上绘制绿色的轮廓序列
ZV_CONTLIST(showImg, tsContlist1, ZV_COLOR(0, 255, 0), 0)
endif
next
else '未匹配到目标时,将结果赋值为-1
d_match_rst(0) = -1
d_match_rst(1) = -1
d_match_rst(2) = -1
d_match_rst(3) = -1
d_match_rst(4) = -1
endif
'计算变换矩阵
ZV_GETRIGIDVECTOR(mat_rigid2, d_match_base_rst(1), d_match_base_rst(2), d_match_base_rst(3),TABLE(4),TABLE(5), d_match_rst(3))
'初始化颜色识别区域
ZV_REGENRECT2(regionMask1, d_reg_roi1(0), d_reg_roi1(1), d_reg_roi1(2), d_reg_roi1(3), d_reg_roi1(4))
ZV_REGENRECT2(regionMask2, d_reg_roi2(0), d_reg_roi2(1), d_reg_roi2(2), d_reg_roi2(3), d_reg_roi2(4))
ZV_REGENRECT2(regionMask3, d_reg_roi3(0), d_reg_roi3(1), d_reg_roi3(2), d_reg_roi3(3), d_reg_roi3(4))
'变换识别区域
ZV_REAFFINE(regionMask1,mat_rigid2,regionMask1)
ZV_REAFFINE(regionMask2,mat_rigid2,regionMask2)
ZV_REAFFINE(regionMask3,mat_rigid2,regionMask3)
if(ZV_ISEMPTY(Clrmod_list)=1) then '如果训练样本库为空
?"颜色模型库为空!"
return
else
DMSET table(50,96,0)
ZV_CLRMODELCLASSIFY(Clrmod_list,colorImg,regionMask1,32,50,150,table(160))'颜色识别
ZV_CLRMODELCLASSIFY(Clrmod_list,colorImg,regionMask2,32,82,151,table(160))'颜色识别
ZV_CLRMODELCLASSIFY(Clrmod_list,colorImg,regionMask3,32,114,152,table(160))'颜色识别
DMCPY d_color_rst1(0), TABLE(50), 32'将识别的颜色结果复制到数组变量中
DMCPY d_color_rst2(0), TABLE(82), 32
DMCPY d_color_rst3(0), TABLE(114), 32
if STRCOMP(d_color_rst1, "red")=0 AND STRCOMP(d_color_rst2, "black")=0 AND STRCOMP(d_color_rst3, "yellow")=0 then
d_rst_status=1
endif
ZV_REAREACENTER(regionMask1,170)'计算识别区域的面积和重心位置XY
ZV_REAREACENTER(regionMask2,173)
ZV_REAREACENTER(regionMask3,176)
ZV_TEXT(showImg,d_color_rst1,TABLE(171),TABLE(172),50,ZV_COLOR(0,255,0))'显示识别样本名称
ZV_TEXT(showImg,d_color_rst2,TABLE(174),TABLE(175),50,ZV_COLOR(0,255,0))
ZV_TEXT(showImg,d_color_rst3,TABLE(177),TABLE(178),50,ZV_COLOR(0,255,0))
endif
ZV_LATCH(showImg,0)
d_detect_time=abs(TICKS)
END SUB
28.在“main.bas”文件中添加主界面【连续运行】按钮响应的函数并关联动作函数。
'主界面点击连续运行按钮时响应的函数
GLOBAL SUB btn_run()
if(run_switch = 1) then '如果已经开启连续运行
?"已开启连续运行,请勿重复操作!" '提示信息并退出子函数,不往下执行
return
endif
run_switch = 1 '主任务开关置1
if (1 = run_switch) then '如果主任务开关=1
if (0 = PROC_STATUS(main_task_id)) then '如果main_task_id任务未开启
RUNTASK main_task_id, main_task '开启main_task任务
endif
endif
END SUB
'主任务执行的内容
main_task:
while(1)
if (0 = run_switch) then '如果主任务开关=0即停止运行按钮按下时
exit while '退出循环
endif
'否则重复执行以下操作
if (d_use_imgfile=1) then '如果d_use_imgfile=1时使用读取本地图片功能
if(d_index=3) then
d_index=0
endif
File_Name="颜色排序/"+TOSTR(d_index,1,0)+".bmp" '读取本地图片时图片所在的路径名称
ZV_IMGREAD(grabImg,File_Name,1)
ZV_IMGREAD(colorImg,File_Name,0)
d_index=d_index+1
else
'如果相机数量为0,提示先扫描相机,并退出子函数不往下执行
if cam_num = 0 then
?"请先扫描相机!"
return
endif
CAM_SETPARAM("TriggerSoftware", 0) '发送触发指令
CAM_GET(grabImg, 0)
endif
'执行测试按钮响应函数进行匹配定位检测
btn_test()
wend
END
29.在“main.bas”文件中添加主界面【停止运行】按钮响应的函数并关联动作函数。
'主界面点击停止执行按钮时响应的函数
GLOBAL SUB btn_stop()
if(run_switch = 0) then '如果主任务开关=0
?"未开启连续运行!" '提示未开启循环任务,并退出子函数不往下执行
return
endif
run_switch = 0 '主任务开关置0,退出循环
END SUB
30.在“main.bas”文件添加主界面按下【保存参数】按钮时响应的函数,并关联动作函数。
'主界面按下保存匹配参数按钮时响应的函数
GLOBAL SUB btn_loc_saveParam()
VR(1)=1 '匹配参数保存标志置1
for i=0 to 8
VR(10+i)=d_mod_param(i)
next
for i=0 to 6
VR(20+i)=d_match_param(i)
next
for i=0 to 4
VR(30+i)=d_reg_roi1(i)
VR(40+i)=d_reg_roi2(i)
VR(50+i)=d_reg_roi3(i)
VR(70+i)=d_match_base_rst(i)
next
for i=0 to 3
VR(60+i)=d_learn_roi(i)
next
VR(76)=TABLE(160)
?"已保存检测参数!"
END SUB
31.在“draw.bas”文件中ROI区域更新绘制函数,并在主界面的自定义控件上关联刷新函数名和绘图函数名。
'根据鼠标操作更新ROI位置区域函数
GLOBAL SUB update_roi()
if d_select_regROI=1 then
SET_REDRAW
if mouse_scan(11) = 1 then '扫描鼠标按下操作
'只有按下时可以改变击中位置,获取调整区域标志
hit_pos = ZV_HMIADJRECT2(table(11), table(12), 231, -1)
is_redraw = 1 '将绘图标志置1
endif
if mouse_scan(11) = -1 then '扫描鼠标松开操作
'调整ROI的位置
ZV_HMIADJRECT2(table(11), table(12), 231, hit_pos)
is_redraw = 1 '将绘图标志置1
endif
if (MOUSE_state(11)) then
'调整ROI的位置
ZV_HMIADJRECT2(table(11), table(12), 231, hit_pos)
is_redraw = 1 '将绘图标志置1
endif
if (1 = is_redraw) then '绘制
is_redraw = 0 '将绘图标志置0
ZV_POSTOIMG(0, 1, 231, 241)'将ROI的控件坐标数据转到图像坐标数据
d_reg_roi1(0) = TABLE(241)'将ROI的图像坐标数据赋值给定义的变量
d_reg_roi1(1) = TABLE(242)
'将ROI在控件坐标系下的宽度、高度转到像素宽度,并赋值给定义的变量
d_reg_roi1(2) = ZV_LENTOIMG(0, TABLE(233))
d_reg_roi1(3) = ZV_LENTOIMG(0, TABLE(234))
d_reg_roi1(4) = TABLE(235)
SET_REDRAW '全局绘制
endif
endif
if d_select_regROI=2 then
SET_REDRAW
if mouse_scan(11) = 1 then '扫描鼠标按下操作
'只有按下时可以改变击中位置,获取调整区域标志
hit_pos = ZV_HMIADJRECT2(table(11), table(12), 331, -1)
is_redraw = 1 '将绘图标志置1
endif
if mouse_scan(11) = -1 then '扫描鼠标松开操作
'调整ROI的位置
ZV_HMIADJRECT2(table(11), table(12), 331, hit_pos)
is_redraw = 1 '将绘图标志置1
endif
if (MOUSE_state(11)) then
'调整ROI的位置
ZV_HMIADJRECT2(table(11), table(12), 331, hit_pos)
is_redraw = 1 '将绘图标志置1
endif
if (1 = is_redraw) then '绘制
is_redraw = 0 '将绘图标志置0
ZV_POSTOIMG(0, 1, 331, 241)'将ROI的控件坐标数据转到图像坐标数据
d_reg_roi2(0) = TABLE(241)'将ROI的图像坐标数据赋值给定义的变量
d_reg_roi2(1) = TABLE(242)
'将ROI在控件坐标系下的宽度、高度转到像素宽度,并赋值给定义的变量
d_reg_roi2(2) = ZV_LENTOIMG(0, TABLE(233))
d_reg_roi2(3) = ZV_LENTOIMG(0, TABLE(234))
d_reg_roi2(4) = TABLE(235)
SET_REDRAW '全局绘制
endif
endif
if d_select_regROI=3 then
SET_REDRAW
if mouse_scan(11) = 1 then '扫描鼠标按下操作
'只有按下时可以改变击中位置,获取调整区域标志
hit_pos = ZV_HMIADJRECT2(table(11), table(12), 431, -1)
is_redraw = 1 '将绘图标志置1
endif
if mouse_scan(11) = -1 then '扫描鼠标松开操作
'调整ROI的位置
ZV_HMIADJRECT2(table(11), table(12), 431, hit_pos)
is_redraw = 1 '将绘图标志置1
endif
if (MOUSE_state(11)) then
'调整ROI的位置
ZV_HMIADJRECT2(table(11), table(12), 431, hit_pos)
is_redraw = 1 '将绘图标志置1
endif
if (1 = is_redraw) then '绘制
is_redraw = 0 '将绘图标志置0
ZV_POSTOIMG(0, 1, 431, 241)'将ROI的控件坐标数据转到图像坐标数据
d_reg_roi3(0) = TABLE(241)'将ROI的图像坐标数据赋值给定义的变量
d_reg_roi3(1) = TABLE(242)
'将ROI在控件坐标系下的宽度、高度转到像素宽度,并赋值给定义的变量
d_reg_roi3(2) = ZV_LENTOIMG(0, TABLE(233))
d_reg_roi3(3) = ZV_LENTOIMG(0, TABLE(234))
d_reg_roi3(4) = TABLE(235)
SET_REDRAW '全局绘制
endif
endif
SET_REDRAW '全局绘制
END SUB
'ROI区域更新后实时绘制ROI区域
GLOBAL SUB draw_roi()
SET_COLOR(C_GREEN) '设置绘制时画笔的颜色为蓝色
if d_select_regROI=1 then
ZV_HMIRECT2(231, 70) '将旋转矩形roi分解为HMI支持的绘图图元并添加控制参数,便于HMI绘图显示
DRAWLINE(TABLE(70), TABLE(71), TABLE(72), TABLE(73)) '绘制外矩形
DRAWLINE(TABLE(72), TABLE(73), TABLE(74), TABLE(75))
DRAWLINE(TABLE(74), TABLE(75), TABLE(76), TABLE(77))
DRAWLINE(TABLE(76), TABLE(77), TABLE(70), TABLE(71))
'绘制矩形中心到右边线中心的箭头
DRAWLINE(TABLE(78), TABLE(79), TABLE(80), TABLE(81))
DRAWLINE(TABLE(82), TABLE(83), TABLE(80), TABLE(81))
DRAWLINE(TABLE(84), TABLE(85), TABLE(80), TABLE(81))
endif
if d_select_regROI=2 then
ZV_HMIRECT2(331, 70) '将旋转矩形roi分解为HMI支持的绘图图元并添加控制参数,便于HMI绘图显示
DRAWLINE(TABLE(70), TABLE(71), TABLE(72), TABLE(73)) '绘制外矩形
DRAWLINE(TABLE(72), TABLE(73), TABLE(74), TABLE(75))
DRAWLINE(TABLE(74), TABLE(75), TABLE(76), TABLE(77))
DRAWLINE(TABLE(76), TABLE(77), TABLE(70), TABLE(71))
'绘制矩形中心到右边线中心的箭头
DRAWLINE(TABLE(78), TABLE(79), TABLE(80), TABLE(81))
DRAWLINE(TABLE(82), TABLE(83), TABLE(80), TABLE(81))
DRAWLINE(TABLE(84), TABLE(85), TABLE(80), TABLE(81))
endif
if d_select_regROI=3 then
ZV_HMIRECT2(431, 70) '将旋转矩形roi分解为HMI支持的绘图图元并添加控制参数,便于HMI绘图显示
DRAWLINE(TABLE(70), TABLE(71), TABLE(72), TABLE(73)) '绘制外矩形
DRAWLINE(TABLE(72), TABLE(73), TABLE(74), TABLE(75))
DRAWLINE(TABLE(74), TABLE(75), TABLE(76), TABLE(77))
DRAWLINE(TABLE(76), TABLE(77), TABLE(70), TABLE(71))
'绘制矩形中心到右边线中心的箭头
DRAWLINE(TABLE(78), TABLE(79), TABLE(80), TABLE(81))
DRAWLINE(TABLE(82), TABLE(83), TABLE(80), TABLE(81))
DRAWLINE(TABLE(84), TABLE(85), TABLE(80), TABLE(81))
endif
END SUB
三、 操作演示
(一)操作步骤
查看运行效果:将项目下载到仿真器中→使用本地图片→单次采集→训练样本,依次学习“red”“black”“yellow”的颜色模板→学习模板,作为识别颜色区域的补正源→依次拖拽3个颜色识别ROI区域→点击测试查看效果图→点击连续运行,查看运行效果→结束。
(二)效果演示
本次,正运动技术机器视觉运动控制一体机应用例程(九)线束颜色排序识别,就分享到这里。
更多精彩内容请关注“正运动小助手”公众号,需要相关开发环境与例程代码,请咨询正运动技术销售工程师。
本文由正运动技术原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。