一维码检测

HALCON在使用默认参数检测一维码时有时会出现只检测到部分,或者没检测到的情况,我们除了调整参数,还可以通过减少检测区域来解决,根据二维码的特征筛选出二维码区域

 

dev_get_window (WindowHandle)
 list_files ('F:/一维码/一维码', ['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])
    median_image (Image, Image, 'circle', 2, 'mirrored')
laplace_of_gauss(Image, ImageLaplace, 2)//提取边缘轮廓
threshold(ImageLaplace, Region3, 2, 111)//阈值分割
skeleton(Region3, Skeleton3)//计算区域骨架
connection (Skeleton3, ConnectedRegions)//连通性分析
select_shape (ConnectedRegions, SelectedRegions1, 'area', 'and', 60, 1500)//通过面积筛选
select_shape_std (SelectedRegions1, SelectedRegions, 'rectangle2', 30)//通过矩形度筛选
union1 (SelectedRegions, RegionUnion)//合并

gen_contours_skeleton_xld (RegionUnion, Contours1, 1, 'filter')//骨架转化为xld轮廓
*通过轮廓长度再次筛选
select_contours_xld (Contours1, SelectedContours, 'contour_length', 30, 400, -0.5, 0.5)
*根据XLD轮廓拟合直线
fit_line_contour_xld (SelectedContours, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist1)
*将拟合的直线显示为区域
gen_region_line (RegionLines1, RowBegin, ColBegin, RowEnd, ColEnd)

*在-180~180°里每30°查找一次条码
for i:=180 to -170 by -30
    *筛选角度差30°的拟合线//根据角度筛选区域
    select_shape (RegionLines1, SelectedRegions2, 'orientation', 'and', rad(i-30),  rad(i))
    *获取筛选到的区域
    count_obj (SelectedRegions2, Number)
    *少于12条说明不是条码//区域数量大于12
    if(Number>=12)
        *将所有拟合线联合为一个区域
        union1 (SelectedRegions2, RegionUnion1)
        *求坐标和角度
        area_center (RegionUnion1, Area1, Row, Column)
        orientation_region (RegionUnion1, Phi)
        *如果角度不在-90°~90°之间,说明求角度的凸性反向错了,因为我们都要转至0°的反向
        if(Phi>rad(90))
            Phi:=Phi-rad(180)
        endif
        if(Phi<-rad(90))
            Phi:=rad(180)+Phi
        endif
        *旋转句柄
        vector_angle_to_rigid (Row, Column, Phi, Row, Column,rad(0), HomMat2D)
        *旋转区域和图像,即将条码转至水平位置(与y轴平行)
        affine_trans_region (RegionUnion1, RegionAffineTrans1, HomMat2D, 'nearest_neighbor')
        affine_trans_image (Image, ImageAffineTrans1, HomMat2D, 'constant', 'false')
        *宽度200高度2的结构元素用于膨胀水平方向,连接条码为一个区域
        closing_rectangle1 (RegionAffineTrans1, RegionClosing, 200, 2)
        *有些线段与条码的角度相同,此时通过面积过滤
        connection (RegionClosing, ConnectedRegions1)//连通性分析
       *选择面积最大的区域
        select_shape_std (ConnectedRegions1, SelectedRegions4, 'max_area', 70)
        *将区域转换成矩形
        shape_trans (SelectedRegions4, RegionTrans, 'rectangle2')
        *为了保证提取的区域是条码区域,可以通过一些条件进一步判断是否条码区域 
        *通过颜色特征(条码区域黑白相间,面积应该差不多)
         reduce_domain (ImageAffineTrans1, RegionTrans, ImageReduced1)
        *白色区域
         threshold (ImageReduced1, Regions1, 89, 255)
         area_center (Regions1, Area, Row1, Column1)
        *黑色区域
       threshold (ImageReduced1, Regions2, 0, 89)
       area_center (Regions2, Area2, Row2, Column2)
         if(Area>Area2*2 or Area2>Area*2 )//如果白色面积大与黑色一倍或白色比黑色大一倍
                continue//停止当前循环,进行下一次循环
       else
         break//退出循环  
        endif
        break//退出循环
    endif
endfor
    *膨胀,防止条码区域太小
    dilation_circle (RegionTrans, RegionDilation, 50)
    *减少定义域
    reduce_domain (ImageAffineTrans1, RegionDilation, ImageReduced)  
    create_bar_code_model ([], [], BarCodeHandle)//创建一维码模型,输入模型的参数,输出一个模型的句柄
    *set_bar_code_param (BarCodeHandle, 'timeout', 1020)//设置延迟
    dev_display (Image)
    dev_display (ImageAffineTrans1)
    find_bar_code (ImageReduced, SymbolRegions, BarCodeHandle, 'auto', DecodedDataStrings)//检测一维码
*Image:查找的图像;BarCodeHandle:一维码模型句柄;CodeType:一维码的类型;DecodedDataStrings:解码的一维码数据字符串
    count_obj (SymbolRegions, Number)
if (Number<1)//判断是否检测到
    disp_message (WindowHandle, '未检测到条码', 'ImageAffineTrans1', 12, 12, 'black', 'true')
    stop ()
endif
    area_center (SymbolRegions, Area, Row, Column)//获取区域信息
    disp_message (WindowHandle, DecodedDataStrings, 'ImageAffineTrans1', Row, Column-200, 'black', 'false')//显示结果
    clear_bar_code_model (BarCodeHandle)//清除模板
stop ()
endfor 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值