• halcon脚本-机器学习【OCR】【附源码】



    前言

    本文主要实现基于halcon的机器学习的多层感知机分类器实现OCR,从数据集训练到数据检测,训练符合自己的OCR模型。


    一、数据集介绍

    本次数据集为喷枪打码的工件图像
    在这里插入图片描述
    在这里插入图片描述
    需要实现的功能是计算机识别得到:G37657183P的字符串。


    二、halcon实现思路

    • 因为工件在相机中的位置是固定的,所以首先可设置ROI,对图像进行截取,把不必要的区域直接去掉
    • 然后阈值处理,得到每个字符的region,这样每一个字符就代表一个region,可以单独取出region内容
    • 对每个region进行标注
    • 对标注好的数据输送到OCR的MLP训练器中进行训练。
    • 得到模型后即可完成检测

    三、halcon脚本-标注训练

    1.理解训练OCR得到的是什么

    TrainFile:='MyTrainocr.trf'
    FontFile:='MyTrainOCR.omc'
    
    • 1
    • 2

    这两个文件分别是训练数据集和保存训练完的模型

    2.对原始图像进行处理,获得训练数据集

    1.首先绘制ROI获得感兴趣区域

    这里使用算子:

    draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
    gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
    
    • 1
    • 2

    在这里插入图片描述

    2.对截图图像进行区域处理

    先二值化获得区域,分割区域后进行按行排序,确保顺序
    主要用到算子:

    threshold (ImageReduced, Region, 0, 130)
    connection (RegionDilation, ConnectedRegions)
    select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5000, 99999)
    sort_region (SelectedRegions, SortedRegions, 'character', 'true', 'row')
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    3.分别对每个区域进行标注

    这里使用循环区域的方法加上人工输入进行标注,并把标注好的region及字符保存到’MyTrainocr.trf’
    主要用到算子:

    select_obj (SortedRegions, ObjectSelected, Index1)
    dev_display (ObjectSelected)
    read_char (WindowHandle, Char, Code)
    if(Char==' ')
        continue
    endif
    append_ocr_trainf (ObjectSelected, Image, Char, TrainFile)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    3.训练OCR模型

    这里使用MLP分类器对模型进行训练
    主要算子:

    create_ocr_class_mlp (8, 10, 'constant', 'default', CharacterNames, 80, 'none', 10, 42, OCRHandle)
    trainf_ocr_class_mlp (OCRHandle, TrainFile, 2000, 1, 0.00001, Error, ErrorLog)
    
    • 1
    • 2

    4.完整标注/训练代码

    这里完整代码+注释

    dev_set_check('~give_error')
    * 删除原本已有的OCR训练数据
    delete_file(TrainFile)
    dev_set_check('give_error')
    * 获取图像列表
    list_image_files ('./202009011', 'default', [], ImageFiles)
    for Index := 0 to |ImageFiles|-1 by 1
        * 读取图像
        read_image (Image, ImageFiles[Index])
        * 这里是如果是rgb图像则转灰度图像
        rgb1_to_gray (Image, Image)
        * 图像像素的标准化,为了做图像拉申
        Min_Gray:=0
        Max_Gray:=160
        Mult := 255.0 / (Max_Gray - Min_Gray)
        Add := -Mult * Min_Gray
        scale_image (Image, ImageScaleMax, Mult, Add)
        * 图像锐化处理,让特征更加明显
        emphasize (ImageScaleMax, Image, 5, 5, 3)
        * 拉申
        scale_image_max (Image, ImageScaleMax)
        * 获取矩形的面积及中心位置
        area_center (Rectangle, Area, Row, Column)
        dev_display (Image)
        * 如果矩形面积为0,所以一开始就没有设置ROI区域,然后设置ROI
        if(Area==0)
            draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
            gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
        endif
        * 根据区域在原图中进行裁剪
        reduce_domain (Image, Rectangle, ImageReduced)
        * 区域显示效果,内部填充
        dev_set_draw ('fill')
        * 区域二值化
        threshold (ImageReduced, Region, 0, 130)
        * 图像膨胀,其实是对区域膨胀,为了消除区域叛变的噪点
        dilation_circle (Region, RegionDilation, 5.5)
        * 图像腐蚀,其实是对区域腐蚀,让区域变细
        erosion_circle (RegionDilation, RegionErosion, 1.5)
        * 区域分割成单个对象
        connection (RegionDilation, ConnectedRegions)
        * 区域选择,去除噪点,为了只取图像上属于字符的区域
        select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5000, 99999)
        * 区域按行排序
        sort_region (SelectedRegions, SortedRegions, 'character', 'true', 'row')
        * 获取数量
        count_obj (SortedRegions, Number)
        * 如果区域数量<10,说明上边的算法对某图不适应,因为本次数据本来就有不一样的图片环境
        if(Number < 10)
            threshold (ImageReduced, Region, 0, 130)
            erosion_circle (Region, RegionErosion, 1.5)
            dilation_circle (RegionErosion, RegionDilation, 3.5)
            connection (RegionDilation, ConnectedRegions)
            select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5000, 99999)
            sort_region (SelectedRegions, SortedRegions, 'character', 'true', 'row')
            count_obj (SortedRegions, Number)
        endif
        * 循环开始标注
        for Index1 := 1 to Number by 1
            * 选择区域
            select_obj (SortedRegions, ObjectSelected, Index1)
            dev_display (ObjectSelected)
            * 键盘根据显示的区域进行键盘输入达到标注效果
            read_char (WindowHandle, Char, Code)
            if(Char==' ')
                continue
            endif
            * 标注内容和区域写入到训练文件中
            append_ocr_trainf (ObjectSelected, Image, Char, TrainFile)
        endfor
    endfor
    
    * 读取训练文件
    read_ocr_trainf_names (TrainFile, CharacterNames, CharacterCount)
    * 创建基于ocr的mlp分类模型
    create_ocr_class_mlp (8, 10, 'constant', 'default', CharacterNames, 80, 'none', 10, 42, OCRHandle)
    * 开始训练,2000代表训练次数
    trainf_ocr_class_mlp (OCRHandle, TrainFile, 2000, 1, 0.00001, Error, ErrorLog)
    * 保存模型
    write_ocr_class_mlp (OCRHandle, FontFile)
    * 清除内存
    clear_ocr_class_mlp (OCRHandle)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    四、halcon脚本-测试

    这里测试代码比较简单,这里直接上halcon脚本

    ************test****************
    dev_get_window (WindowHandle)
    FontFile:='MyTrainOCR.omc'
    MinScore:=0.99
    read_ocr_class_mlp (FontFile, OCRHandle1)
    
    read_image (Image1, './202009011/NG 145640.bmp')
    draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
    gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
    reduce_domain (Image1, Rectangle, ImageReduced)
    dev_set_draw ('fill')
    threshold (ImageReduced, Region, 0, 130)
    dilation_circle (Region, RegionDilation, 5.5)
    erosion_circle (RegionDilation, RegionErosion, 1.5)
    connection (RegionDilation, ConnectedRegions)
    select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5000, 99999)
    sort_region (SelectedRegions, SortedRegions, 'character', 'true', 'row')
    do_ocr_multi_class_mlp (SortedRegions, Image1, OCRHandle1, RecNum, Confidence)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    效果如图
    在这里插入图片描述
    在这里插入图片描述
    这里分别获得分数和类别,直接把RecNum拼接即可。


    总结

    对本次OCR的脚本有疑问可直接私聊,源码在文章中已全部展示,如果搭建时有问题可进行询问

  • 相关阅读:
    [技术发展-22]:网络与通信技术的应用与发展快速概览-2- 通信技术
    TFX发展简史/《Towards ML Engineering: A Brief History Of TensorFlow Extended (TFX)》
    总有一天,你一定会很棒
    【云原生之Docker实战】使用Docker部署ROS软路由系统
    借助第三方工具网站完成消息自动推送
    2022-08-07 集合拓展---遍历
    设计模式解析之模板方法模式:设计灵活可扩展的算法框架
    01-C语言练习题
    四-(4-醛基-(1,1-联苯))乙烯;TPE-Ph-CHO; ETBC;AIE聚集诱导发光材料
    Spring Boot插件化开发概念原理及实现
  • 原文地址:https://blog.csdn.net/ctu_sue/article/details/127420811