【机器视觉】HALCON目标图像检测实践(零基础版非常有用!)

开发环境:

在这里插入图片描述

基本思路:

灰度阈值处理+特征提取
ps:思考:如何通过阈值处理后,后续缩小检测目标范围?
二值化、梯度阈值、自适应阈值等方法来增强图像的对比度,从而突出目标特征,进一步缩小检测目标范围。

实例

检测红色圆片的个数

请添加图片描述
代码实现:

read_image (Image1, 'D:/视觉图片/1.圆片.jpg')

decompose3 (Image1, Image11, Image2, Image3)

threshold (Image11, Regions, 223, 255)

fill_up (Regions, RegionFillUp)

connection (RegionFillUp, ConnectedRegions)

select_shape (ConnectedRegions,SelectedRegions, 'area', 'and', 5000, 200000)

count_obj (SelectedRegions, Number1)

area_center (SelectedRegions, Area, Row, Column)

dev_set_color ('green')
gen_cross_contour_xld (Cross, Row, Column, 100, 0)

smallest_circle (SelectedRegions, Row1, Column1, Radius)
gen_circle_contour_xld (circle, Row1, Column1, Radius, 0, 6.28318, 'positive', 1)
dev_display (Image1)
dev_set_line_width (2)
dev_set_color ('green')
dev_display (Cross)
dev_display (circle)

count_obj (circle, Number)
dev_get_window (WindowHandle)
msg:='红色目标数量: '+Number
disp_message (WindowHandle, msg, 'image', 12, 12, 'black', 'true')

disp_message (WindowHandle, '智能制造-蒋达', 'window', 50, 50, 'black', 'true')

运行结果:
在这里插入图片描述

单骰子点数

请添加图片描述
方法一:
基本思路:通过阈值处理操作(0-40)将点数和背景检测出,再通过特征处理将“圆形”的点数筛选出,然后计数即可。

代码实现:

read_image (Image1, 'D:/视觉图片/2.筛子.jpg')

decompose3 (Image1, Image11, Image2, Image3)

threshold (Image11, Regions, 0, 40)
connection (Regions, Connection)
select_shape (Connection, SelectedRegions, 'circularity', 'and', 0.47685, 0.94722)

count_obj (SelectedRegions, Number1)
area_center (SelectedRegions, Area, Row, Column)

dev_set_color ('green')
gen_cross_contour_xld (Cross, Row, Column, 20, 0.785398)

smallest_circle (SelectedRegions, Row1, Column1, Radius)
gen_circle_contour_xld (circle, Row1, Column1, Radius, 0, 6.28318, 'positive', 1)

dev_display (Image1)
dev_set_line_width (2)
dev_set_color ('green')
dev_display (Cross)
dev_display (circle)

count_obj (circle, Number)
dev_get_window (WindowHandle)
msg:='筛子点数为: '+Number
disp_message (WindowHandle, msg, 'image', 12, 12, 'black', 'true')

disp_message (WindowHandle, '智能制造-蒋达', 'window', 50, 50, 'black', 'true')

运行结果:
在这里插入图片描述

方法二:
基础思路:通过阈值处理等操作将整个骰子筛选出来,再通过定位和缩小范围将点数筛选出来,再计数即可。

代码实现:

read_image (Image2, 'D:/视觉图片/2.筛子.jpg')
decompose3 (Image2, ImageR, ImageG, ImageB)

threshold (ImageG, Regions, 87, 167)

*填充孔洞
fill_up (Regions, RegionFillUp)

*特征筛选,使用面积过滤小的干扰
select_shape (RegionFillUp, SelectedRegions, 'area', 'and', 30000, 34000)

count_obj (SelectedRegions, Number1)

* 求中心
area_center (SelectedRegions, Area, Row, Column)

*生成十字
gen_cross_contour_xld (Cross, Row, Column, 30, 0.785398)

*包围框
smallest_rectangle2 (SelectedRegions, Row1, Column1, Phi, Length1, Length2)
gen_rectangle2_contour_xld (Rectangle, Row1, Column1, Phi, Length1, Length2)

dev_display (Image2)
dev_set_line_width (2)
dev_display (Cross)
dev_display (Rectangle)
stop ()

* 定位到的筛子区域也就是点的ROI
* 缩小检测范围到ROI
reduce_domain (ImageG, SelectedRegions, ImageReduced)
threshold (ImageReduced, Regions1, 0, 90)
connection (Regions1, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions1, 'area', 'and', 1211.06, 1410.05)
* 计数
count_obj (SelectedRegions1, Number)
dev_display (Image2)
dev_set_line_width (2)
dev_display (Cross)
dev_display (Rectangle)

msg:='筛子点数为: '+Number
dev_get_window (WindowHandle)

disp_message (WindowHandle, msg, 'image', 12, 12, 'black', 'true')

disp_message (WindowHandle, '智能制造-蒋达', 'window', 50, 50, 'black', 'true')

运行结果:
在这里插入图片描述

多骰子点数

在这里插入图片描述
基本思路:将各个骰子筛选(除背景)出来,通过循环遍历对每个单骰子进行处理和计数,即在循环中用上述单骰子的操作。

代码实现:

* 获取窗口标识符
dev_get_window (WindowHandle)
read_image (Image3, 'D:/视觉图片/3.多筛子.bmp')
decompose3 (Image3, Image1, Image2, Image31)

*分割筛子
threshold (Image2, Regions, 70, 167)

*填充孔洞,避免丢掉点
fill_up (Regions, RegionFillUp)
connection (RegionFillUp, ConnectedRegions)

*特征筛选
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 20528.7, 23394.3)

*画框
smallest_rectangle2 (SelectedRegions, Row, Column, Phi, Length1, Length2)
gen_rectangle2_contour_xld (Rectangle, Row, Column, Phi, Length1, Length2)

*计算共有几个筛子
count_obj (SelectedRegions, Number)
dev_update_window ('off') //关闭窗口自动刷新
dev_display (Image3)
dev_set_line_width (2)
dev_display (Rectangle)

for Index1 := 1 to Number by 1
    select_obj (SelectedRegions, Obj, Index1)
    reduce_domain (Image2, Obj, ImageReduced)
    
    
    threshold (ImageReduced, Regions1, 0, 74)
    fill_up (Regions1, RegionFillUp1)
    connection (RegionFillUp1, ConnectedRegions1)
    
    
    select_shape (ConnectedRegions1, SelectedRegions1, 'area', 'and', 700, 4440)
    
    count_obj (SelectedRegions1, Number1)
    area_center (Obj, Area, Row1, Column1)
    dev_set_window (WindowHandle)
    disp_message (WindowHandle, Number1, 'image', Row1, Column1, 'black', 'true')
    stop()
    
endfor

运行结果:
在这里插入图片描述

物块集正反面检测

物块集:
在这里插入图片描述

基本思路:其实就是遍历中增加了判断,对某一次循环的图片进行阈值处理和特征处理并计数,通过数量(0 or 1)来判断有无(正反面)。

代码实现:

* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('D:/物块', ['files','follow_links','recursive'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
    read_image (Image, ImageFiles[Index])
    * Image Acquisition 01: Do something
    
    
    decompose3 (Image, ImageR, ImageG, ImageB)
    threshold (ImageR, Regions, 79, 199)
    fill_up (Regions, RegionFillUp)
    
    * 打散
    connection (RegionFillUp, ConnectedRegions)
    
    select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 230406, 374929)
    
    count_obj (SelectedRegions, Number)
    
    dev_display (Image)
    if (Number==0)
        * 反面
        result:='NG'
        color:='red'
    else
        * 正面
        result:='OK'
        color:='green'
        dev_set_color (color)
        area_center (SelectedRegions, Area, Row, Column)
        gen_cross_contour_xld (Cross, Row, Column, 100, 0.785398)
        smallest_rectangle2 (SelectedRegions, Row1, Column1, Phi, Length1, Length2)
        gen_rectangle2_contour_xld (Rectangle, Row1, Column1, Phi, Length1, Length2)
        dev_display (Cross)
        dev_display (Rectangle)
    endif
    dev_get_window (WindowHandle)
    disp_message (WindowHandle, result, 'image', 60, 60, color, 'true')
    
    stop ()
endfor

运行结果:
正面
在这里插入图片描述
反面
在这里插入图片描述

铭牌字符识别(水平)

请添加图片描述
基本思路:先阈值操作,提取出铭牌(除背景,但还是有一些存在),再特征处理将字符都分割出来,因为字符识别需要“白纸黑字”,需要反色处理(黑白翻转),再识别。

代码实现:

read_image (Image1Gongjian, 'D:/视觉图片/1.gongjian.png')
decompose3 (Image1Gongjian, ImageR, ImageG, ImageB)

threshold (ImageR, Regions, 64, 165)
connection (Regions, ConnectedRegions)

* 多特征筛选 面积area 高度width 宽度height

select_shape (ConnectedRegions, SelectedRegions, ['area','width','height'], 'and', [0,34.74,50.14], [5014.33,63.4,120])

*HALCON识别字符要求特征:白纸黑字

count_obj (SelectedRegions, Number)

invert_image (ImageR, ImageInvert) //黑白翻转

*排序区域
sort_region (SelectedRegions, SortedRegions, 'character', 'true', 'row')

*矩形框 平行矩形
smallest_rectangle1 (SortedRegions, Row1, Column1, Row2, Column2)

cr:=(Row1+Row2)/2.0
cc:=(Column1+Column2)/2.0

len1:=abs(Row2-Row1)/2.0
len2:=abs(Column2-Column1)/2.0

phi:=gen_tuple_const(|len2|,0)

gen_rectangle2_contour_xld (box, cr, cc, phi, len2, len1)

*读取字符模型(人工神经网络)
read_ocr_class_mlp ('Document_0-9A-Z_NoRej.omc', OCRHandle)

* 识别字符 参数:字符region 图像 模型句柄
do_ocr_multi_class_mlp (SortedRegions, ImageInvert, OCRHandle, Class, Confidence)
dev_display (Image1Gongjian)
dev_display (box)
dev_get_window (WindowHandle)
set_display_font (WindowHandle, 18, '宋体', 'true', 'false')
disp_message (WindowHandle, '识别结果:'+sum(Class), 'image', 12, 12, 'black', 'true')
clear_ocr_class_mlp (OCRHandle)

运行结果:
在这里插入图片描述

铭牌字符识别(倾斜)

基本思路:转HSV颜色模型,矫正旋转(先求弧度再转角度),矫正后就可以开始识别字符(分割字符,特征选择,排序区域、神经网络模型)

代码实现:

dev_clear_window ()
read_image (Image, 'D:/视觉图片/2.jpg')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width/4, Height/4, 'black', WindowHandle1)
dev_display (Image)

decompose3 (Image, ImageR, ImageG, ImageB)

*转换HSV颜色模型 色调 饱和度 亮度 rgb->hsv
trans_from_rgb (ImageR, ImageG, ImageB, ImageH, ImageS, ImageV, 'hsv')

* 矫正旋转
threshold (ImageS, Regions, 170, 255)
fill_up (Regions, RegionFillUp)
connection (RegionFillUp, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 210000, 220000)

*求最小外接矩形
smallest_rectangle2 (SelectedRegions, Row, Column, Phi, Length1, Length2)
gen_rectangle2_contour_xld (Rectangle, Row, Column, Phi, Length1, Length2)

*弧度转角度
angle := deg(Phi)

*校正倾斜  角度大于0,逆时针转否则顺时针
rotate_image (ImageS, ImageRotate, 180-angle, 'constant')


*识别字符
*分割字符
threshold (ImageRotate, Regions1, 0, 100)
connection (Regions1, ConnectedRegions1)

*多特征筛选 面积高度宽度
select_shape (ConnectedRegions1, SelectedRegions1, ['area','width','height'], 'and', [0,0,31.48], [41666.7,245.37,105.56])

*排序区域
sort_region (SelectedRegions1, SortedRegions, 'character', 'true', 'column')

*读取字符模型(人工神经网络)
read_ocr_class_mlp ('Document_0-9A-Z_NoRej.omc', OCRHandle)

*识别字符 参数:字符region 图像 模型句柄
do_ocr_multi_class_mlp (SortedRegions, ImageRotate, OCRHandle, Class, Confidence)

dev_display (Image)
dev_get_window (WindowHandle)
set_display_font (WindowHandle, 18, 'mono', 'true', 'false')
disp_message (WindowHandle, '识别结果:'+ sum(Class), 'image', 12, 12, 'black', 'true')
clear_ocr_class_mlp (OCRHandle)

运行结果:
在这里插入图片描述

铭牌字符集识别(倾斜)

倾斜铭牌字符集:
在这里插入图片描述
基本思路:首先要会单个倾斜铭牌字符集的识别,再通过遍历循环和判断展示出来

代码实现:

* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('D:/铭牌字符图像集', ['files','follow_links','recursive'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
    read_image (Image, ImageFiles[Index])

    * Image Acquisition 01: Do something
    
    decompose3 (Image, ImageR, ImageG, ImageB)

*转正
    *转换HSV颜色模型 色调 饱和度 亮度 rgb->hsv
    trans_from_rgb (ImageR, ImageG, ImageB, ImageH, ImageS, ImageV, 'hsv')
 
    threshold (ImageS, Regions, 170, 255)
    fill_up (Regions, RegionFillUp)
    connection (RegionFillUp, ConnectedRegions)
    
    select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 200000, 220000)
    
    smallest_rectangle2 (SelectedRegions, Row, Column, Phi, Length1, Length2)
    gen_rectangle2_contour_xld (Rectangle, Row, Column, Phi, Length1, Length2)
    
    angle := deg(Phi)
    
    rotate_image (ImageS, ImageRotate, 180-angle, 'constant')
    
*识别和判断
    
    threshold (ImageRotate, Regions1, 0, 100)
    connection (Regions1, ConnectedRegions1)
    
    select_shape (ConnectedRegions1, SelectedRegions1, ['area','width','height'], 'and', [0,0,31.48], [41666.7,245.37,105.56])
    count_obj (SelectedRegions1, Number)
    sort_region (SelectedRegions1, SortedRegions, 'character', 'true', 'column')
    read_ocr_class_mlp ('Document_0-9A-Z_NoRej.omc', OCRHandle)
    do_ocr_multi_class_mlp (SortedRegions, ImageRotate, OCRHandle, Class, Confidence)
    dev_display (Image)
    if (Number==11)
        * 有
        result:='OK'
        color:='green'
        dev_set_color (color)
    else
        * 无
        result:='NG'
        color:='red'
    endif
    dev_display (Image)
    dev_get_window (WindowHandle)
    set_display_font (WindowHandle, 18, 'mono', 'true', 'false')
    disp_message (WindowHandle, result, 'image', 12, 12, color, 'true')
    disp_message (WindowHandle, '识别结果:'+ sum(Class), 'image', 120, 120, 'black', 'true')
    clear_ocr_class_mlp (OCRHandle)
    stop()
endfor

运行结果:
有,且输出结果:
在这里插入图片描述
无:
在这里插入图片描述

粘连目标分割计数(瓶盖)

请添加图片描述
基本思路:采集图像-分割图像-形态学处理-显示结果

代码实现:

dev_update_on ()
dev_get_window (WindowHandle)
read_image (Image, 'D:/视觉图片/瓶盖.jpg')
rgb1_to_gray (Image, GrayImage)
threshold (GrayImage, Regions, 50, 255)

*去除干扰,毛刺 孤立的小点
opening_circle (Regions, RegionOpening, 3.5)

*腐蚀断开连接
erosion_circle (RegionOpening, RegionErosion, 45.5)

*分割连通域
connection (RegionErosion, ConnectedRegions)

*注意:connection之后使用opening erosion,可能存在空区域,要谨慎(必要时使用select_shape选择)
* erosion_circle (ConnectedRegions, RegionErosion1, 60.5)

*膨胀瓶盖
dilation_circle (ConnectedRegions, RegionDilation, 4.5)


*计数
count_obj (RegionDilation, Number)

*确定中心
area_center (RegionDilation, Area, Row, Column)
*标记中心
dev_set_colored (12)
gen_cross_contour_xld (Cross, Row, Column, 15, 0)
dev_set_draw ('margin')
dev_set_line_width (2)

*设置窗口显示字体 窗口句柄 字号 字体 粗体 斜体
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_clear_window ()
dev_display (Image)
*dev_display (RegionIntersection)
dev_display (Cross)
disp_message (WindowHandle, '数量是:'+Number, 'image', 12, 12, 'black', 'true')

运行结果:
在这里插入图片描述

  • 8
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日 近 长 安 远

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值