The value of Zmotion is to bring customers more success!
前面课程讲述的所有的机器视觉功能如形状匹配、BLOB检测、数据码识别以及OCR等功能,我们都是对单通道的灰度图像进行处理。
本次课程我们将和大家一起分享使用ZDevelop软件对采集到的彩色图像进行颜色识别的实现方法。
一 检测原理
颜色是我们人眼能接收到的最直接的信息。在工业机器视觉的应用中,我们也可以根据提取到的颜色信息对待测特征进行判断处理。
工业应用中使用到的颜色信息一般是3通道的颜色信息,每一个通道都由8bit的数据信息进行描述,因此机器视觉中通常处理的彩色图像是24bit的图像。
根据不同的颜色特征,采用不同的颜色空间模型对颜色通道进行描述,包括RGB模型、HSV模型、HSI模型。
(一)RGB模型
RGB模型是常用的颜色空间描述方式,它是通过对三色原红(Red)、绿(Green)、蓝(Blue)3中颜色的变化以及三种颜色不同的叠加情况呈现出不同的颜色效果。
如下图所示,红、绿、蓝每个颜色通道都由8bit图像数据来描述,数值范围(0~255)。每一种颜色都由三个颜色通道的数值来显示。如(255,0,0)表示红色,(0,255,0)表示绿色,(0,0,255)表示蓝色,(255,255,255)表示白色,红色和绿色的叠加表示黄色(255,255,0)。
(二)HSV模型
HSV模型包括了色调(Hue)、饱和度(Saturation)、纯度(Value)。它对颜色的描述比RGB更接近人眼对色彩的感知。
HSV模型常用倒立的圆锥体来表示,如下图所示。色调决定颜色的本质,它反映出人眼所看到的颜色如红色或是蓝色;饱和度表示颜色的深浅程度,它也是指含白色的数量程度,白色越多饱和度越低,颜色越浅;纯度反映的是光对颜色的影响程度,从上往下看是一个由白到黑的一个变化过程。
(三)HSI模型
HSI模型使用了颜色三要素色调(Hue)、饱和度(Saturation)、亮度(Intensity)来描述颜色。
HSI模型常用上下对称的圆锥体来表示,如下图所示。色调决定颜色的本质,它反映出人眼所看到的颜色如红色或是蓝色;饱和度表示颜色的深浅程度;亮度反映的是颜色的亮暗程度,从上往下看,它是一个由亮变暗的一个变化过程。
(四)颜色识别
ZVision视觉指令中颜色识别的原理是先通过预先设置的RGB颜色通道的高低阈值范围或者通过学习图像上某一区域内的颜色特征生成颜色模型库,然后在输入图像的指定区域选取某个检测特征,将检测特征和颜色模型库中的颜色进行对比,输出分数最高的颜色模型名称。
二 应用场景
1.分类计数
可以训练学习所有不同颜色的产品,通过颜色识别对不同颜色的产品进行分类并进行计数。
2.提取待测目标特征
如果待测目标特征具有特定的颜色如红色,可以通过提取红色通道的颜色信息将彩色图像进行二值化,突出待测目标特征。
3.输出颜色信息
可以输出待测产品目标的具体颜色信息。
三 软件演示
(一)实例演示
1.打开ZDevelop软件:新建项目→新建HMI文件→新建main.bas文件,用于编写界面响应函数→新建global_variable.bas文件用于定义和初始化全局变量并开启HMI自动运行任务→新建camera.bas文件用于实现相机采集功能→新建draw.bas文件用于更新绘制图形刷新界面→文件添加到项目。
2.设计HMI启动界面。
3.在global_variable.bas文件中定义全局变量,定义完成后运行Hmi.hmi文件。
'''''全局变量大部分使用数组结构'''''
''注:basic编程中很多函数会以TABLE(系统的数据结构)做为参数
''table 说明 table 说明
''11~12 鼠标操作时获取的坐标 15~18 训练学习ROI图像坐标数据
''31~35 识别颜色ROI控件坐标数据 50 识别的颜色名称
''41~42 识别颜色ROI中心图像坐标数据 104 识别的颜色id
''70~85 识别颜色ROI绘制数据 98 输入的识别分数
''25~28 训练学习ROI控件坐标数据
'***********定义程序任务相关变量**********************
'主任务状态
'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
'***********结束定义相机采集相关变量******************
'定义使用ROI标志,1-使用ROI,0-使用全图像区域
GLOBAL DIM d_roi_arc_flag
d_roi_arc_flag = 0
'定义鼠标按下标志位,1-已按下,0-未按下
GLOBAL DIM is_set_roi_m_down
is_set_roi_m_down = 0
GLOBAL DIM d_detect_time '定义消耗的时间变量
d_detect_time = 0
'定义程序执行过程中采集的图像变量、颜色样本模板变量和模板列表变量
GLOBAL ZVOBJECT grabImg,ColorMod,mod_list
'定义检测识别颜色的ROI区域
GLOBAL DIM d_reg_roi(5)
d_reg_roi(0)=260
d_reg_roi(1)=210
d_reg_roi(2)=300
d_reg_roi(3)=225
d_reg_roi(4)=0
TABLE(31) = d_reg_roi(0) '将矩形ROI数据存放到起始地址为31的table数组中
TABLE(32) = d_reg_roi(1)
TABLE(33) = d_reg_roi(2)
TABLE(34) = d_reg_roi(3)
TABLE(35) = d_reg_roi(4)
'定义训练学习颜色样本的ROI区域
GLOBAL DIM d_learn_roi(4)
d_learn_roi(0)=260
d_learn_roi(1)=190
d_learn_roi(2)=300
d_learn_roi(3)=230
TABLE(25) = d_learn_roi(0) '将矩形ROI数据存放到起始地址为25的table数组中
TABLE(26) = d_learn_roi(1)
TABLE(27) = d_learn_roi(2)
TABLE(28) = d_learn_roi(3)
'定义输入需要进行学习的颜色样本名称
GLOBAL DIM d_sample_name(128)
d_sample_name=""
'常用颜色变量
GLOBAL C_RED, C_GREEN, C_BLUE, C_YELLOW
C_RED = RGB(255, 0, 0)
C_GREEN = RGB( 0,255, 0)
C_BLUE = RGB( 0, 0,255)
C_YELLOW= RGB(255,255, 0)
'***********定义读取本地文件功能相关变量**************
''注意,该功能只在使用仿真器时有效
'定义是否使用本地图片标志
GLOBAL DIM d_use_imgfile
d_use_imgfile=1
'定义本地图片索引
GLOBAL DIM d_index
'定义读取图片的路径
GLOBAL DIM File_Name(100)
'***********结束定义读取本地文件功能相关变量**********
'初始化全局变量完成后开启HMI文件
RUN"Hmi1.hmi",1
4.关联HMI启动界面值控件变量。
5.在main.bas文件中添加HMI界面初始化函数并在Hmi系统设置中关联初始化函数。
end
'注:
'凡是要使用Region有关的算子在系统初始化时都要调用ZV_RESETCLIPSIZE(width, height)这个算子设置下图像尺寸,以满足相机分辨率,因为默认的是640*480尺寸
'HMI界面初始化函数
GLOBAL SUB hmi_init()
grab_switch = 0 '停止采集
main_task_state = 1 '主任务停止运行
ZV_RESETCLIPSIZE(640, 480) '初始化时依据图像分辨率设置区域的裁剪尺寸,此处图像分辨率为640x480
ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(10, 1), HMI_CONTROLSIZEY(10, 1)) '设置锁存的大小
TABLE(98)=60 '设置识别分数为60
TABLE(50)=0
ZV_SETSYSDBL("CamGetTimeout", 1000) '设置采集超时
ZV_LATCHCLEAR(0) '清空锁存通道0
END SUB
6.在camera.bas文件中添加HMI启动界面中采集相关按钮响应的函数并关联动作函数。
说明:具体实现函数前面课程内容已经有操作演示,此处不做赘述。
7.在draw.bas文件中添加检测识别ROI更新绘制函数,并在自定义元件属性窗口中关联刷新函数和绘制函数。
end
'和绘制(即选择ROI)有关的界面的刷新绘制函数放在这个bas文件里
DIM is_redraw
is_redraw = 0
DIM hit_pos,sr_mpos_x ,sr_mpos_y
'根据鼠标操作更新ROI位置区域函数
GLOBAL SUB update_roi()
if d_roi_arc_flag = 1 then '如果选择ROI类型为矩形
SET_REDRAW
if mouse_scan(11) = 1 then '扫描鼠标按下操作
'只有按下时可以改变击中位置,获取调整区域标志
hit_pos = ZV_HMIADJRECT2(table(11), table(12), 31, -1)
is_redraw = 1 '将绘图标志置1
endif
if mouse_scan(11) = -1 then '扫描鼠标松开操作
'调整ROI的位置
ZV_HMIADJRECT2(table(11), table(12), 31, hit_pos)
is_redraw = 1 '将绘图标志置1
endif
if (MOUSE_state(11)) then
'调整ROI的位置
ZV_HMIADJRECT2(table(11), table(12), 31, hit_pos)
is_redraw = 1 '将绘图标志置1
endif
if (1 = is_redraw) then '绘制
is_redraw = 0 '将绘图标志置0
ZV_POSTOIMG(0, 1, 31, 41)'将ROI的控件坐标数据转到图像坐标数据
d_reg_roi(0) = TABLE(41)'将ROI的图像坐标数据赋值给定义的变量
d_reg_roi(1) = TABLE(42)
'将ROI在控件坐标系下的宽度、高度转到像素宽度,并赋值给定义的变量
d_reg_roi(2) = ZV_LENTOIMG(0, TABLE(33))
d_reg_roi(3) = ZV_LENTOIMG(0, TABLE(34))
d_reg_roi(4) = TABLE(35)
SET_REDRAW '全局绘制
endif
else
SET_REDRAW
endif
END SUB
'ROI区域更新后实时绘制ROI区域
GLOBAL SUB draw_roi()
if d_roi_arc_flag = 1 then '如果ROI类型为矩形
SET_COLOR(C_BLUE) '设置绘制时画笔的颜色为蓝色
ZV_HMIRECT2(31, 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
8.点击“元件”→“新建窗口”,新建训练学习颜色模型窗口界面,并设计界面布局。
9.在main.bas文件中添加训练学习颜色模型界面按下【训练样本】按钮时响应的函数并关联动作函数名。
'HMI界面按下训练样本按钮时响应的函数
GLOBAL SUB btn_OpenLearning()
ZV_LATCH(grabImg,0)
HMI_SHOWWINDOW(11)
END SUB
10.在draw.bas文件中添加训练学习颜色ROI更新绘制函数,并在自定义元件属性窗口中关联刷新函数和绘制函数。
'根据鼠标操作更新训练颜色样本的有效区域
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, 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_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(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
11.在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_(grabImg,region,ColorMod,d_sample_name,0)'在 RGB 颜色空间生成颜色模型
ZV_LISTINSERT(ColorMod,mod_list,-1) '将颜色模型插入到列表
?"学习"d_sample_name"样本成功!"
endif
END SUB
12.在main.bas文件中添加训练学习颜色模型界面按下【清空样本】按钮时响应的函数并关联动作函数名。
'定义训练颜色样本界面按下清空样本按钮时响应的函数
GLOBAL SUB btn_Clear()
if(ZV_ISEMPTY(mod_list)=0) then '如果训练样本库不为空
ZV_CLEAR(mod_list)
?"已清空样本列表!"
endif
END SUB
13.在main.bas文件中添加训练学习颜色模型界面按下【确定】按钮时响应的函数并关联动作函数名。
'定义训练颜色样本界面按下确定按钮时响应的函数
GLOBAL SUB btn_Confirm()
HMI_CLOSEWINDOW(11)
END SUB
14.在main.bas文件中添加HMI启动界面按下【测试】按钮响应的函数并关联动作函数。
'定义HMI界面按下测试按钮时响应的函数
GLOBAL SUB btn_test()
TICKS=0
ZVOBJECT regionMask
TABLE(50)=0
'
if d_roi_arc_flag = 1 then '如果选择的ROI类型是矩形
'根据ROI数据生成旋转矩形区域
ZV_REGENRECT2(regionMask, d_reg_roi(0), d_reg_roi(1), d_reg_roi(2), d_reg_roi(3), d_reg_roi(4))
else
'生成全图像区域
ZV_REGENFULLIMG(grabImg,regionMask)
endif
if(ZV_ISEMPTY(mod_list)=1) then '如果训练样本库为空
?"颜色模型库为空!"
return
else
ZV_CLRMODELCLASSIFY_(mod_list,grabImg,regionMask,128,50,104,98)'颜色识别
endif
d_detect_time=abs(TICKS)
END SUB
15.在main.bas文件中添加HMI启动界面按下【运行】按钮响应的函数并关联动作函数。
'主界面点击运行按钮时响应的函数
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
'否则重复执行以下操作
'执行单次采集响应函数获取一帧图像
btn_grab()
'执行检测识别颜色子程序
btn_test()
wend
END
16.在main.bas文件中添加HMI启动界面按下【停止】按钮响应的函数并关联动作函数。
'主界面点击停止按钮时响应的函数
GLOBAL SUB btn_stop()
if(run_switch = 0) then '如果主任务开关=0
?"未开启连续运行!" '提示未开启循环任务,并退出子函数不往下执行
return
endif
run_switch = 0 '主任务开关置0,退出循环
END SUB
(二)仿真演示
本次,正运动技术机器视觉运动控制一体机应用例程(二)——颜色识别,就分享到这里。
更多精彩内容请关注“正运动小助手”公众号,需要相关开发环境与例程代码,请咨询正运动技术销售工程师:400-089-8936。
本文由正运动技术原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。