OCR光学字符识别

流程:图像获取—图像预处理—图像分割—创建模型句柄—字符识别处理

案例一:使用halcon自带分类器识别

 

 参考代码
* -- OCR 光学字符识别

*读取图片
read_image (Audi2, 'D:/hoclan/audi2.png')

*1.定位 -->去掉干扰物

*获得窗口句柄
dev_get_window (WindowHandle)
*设置显示边缘模式,方便查看选中内容
dev_set_draw ('margin')

*绘制矩形1区域
draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
*创建矩形1区域
gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)

*把目标区域扣下来
reduce_domain (Audi2, Rectangle, ImageReduced)

*2.提取车牌字符的区域
*(因为OCR 识别的是区域)

*设置显示模式为填充模式,因为前面的边缘模式导致二值化区分不好看
dev_set_draw ('fill')

*blob 三步骤:1.threshold 2.connection 3.select_shape
*二值化
threshold (ImageReduced, Region, 30, 80)
*连通分割
connection (Region, ConnectedRegions)
*筛选 按区域和高度两个条件筛选 ['area','height']
* 800 <= area <= 1600
* 42 <= height <= 70
select_shape (ConnectedRegions, SelectedRegions, ['area','height'], 'and', [800,42], [1600,70])

*3.进行字符识别

*读取光学字符分类器
* Industrial_0-9A-Z_NoRej.omc 分类器路径
* OCRHandle 识别句柄
read_ocr_class_mlp ('Industrial_0-9A-Z_NoRej.omc', OCRHandle)
*开始分类
* SelectedRegions 输入 字体(笔记)区域
* ImageReduced 输入 区域所在的图像
* OCRHandle 输入 识别句柄
* Class 输出 识别返回结果
* Confidence 输出 置信度(得分)0.999不一定靠谱啊
do_ocr_multi_class_mlp (SelectedRegions, ImageReduced, OCRHandle, Class, Confidence)

*求显示信息的坐标
area_center (SelectedRegions, Area, Row, Column)

*显示信息
*disp_message (WindowHandle, Class, 'image', Row+40, Column, 'black', 'true')

*窗口显示文本信息
* 输入 显示的信息 Class
* 显示跟随的坐标系 'image' 'window'
* 显示的坐标 Row, Column
* 字体颜色 'black'
* 参数键 ['box','box_color']
* 参数值 ['true','white']
dev_disp_text (Class, 'image', Row+50, Column, 'black', ['box','box_color'], ['true','white'])
注意事项
*注意事项:
* 1.halcon 自带的分类器 识别过程字体角度不允许存在 太大的偏差
*旋转图像
* 10 指角度!!!
*rotate_image (ImageReduced, ImageRotate, 10, 'constant')

*2.仅允许在 白纸黑字 的状态下识别,需要使用invert_image 图像灰度值的反转(黑白互转)
*invert_image (ImageRotate, ImageInvert)

 

案例二:ORC训练模式(识别麻将)

场景:halcon自带的分类器不能满足所有场景,因此需要自己训练模型。

参考代码

这个案例以识别麻将为场景

OCR 训练模式 

*1.训练

*读取文件
read_image (Image, 'D:/hoclan/OCR/fb.bmp')


**--手动修改参数区域 begin--**
*要训练的文件类型
fileType := 'fb'
*要训练的数量
numbers := 2

*车牌号码字符范围
* 笔记与对应的中文关联起来
text:=['北','發']

*预训练文件路径 
ocrTrf:= 'D:/hoclan/001halcon/'+fileType+'_ocr'
*保存训练文件地址
ocrOmc:= 'D:/hoclan/001halcon/'+fileType+'_ocr.omc'

**--手动修改参数区域 end--**

*彩色图转灰度图
rgb1_to_gray (Image, Image)

*自己训练的文件 不需要指定白纸黑字

*非白纸黑字需要转
*图像灰度值反转 0>>255 1>>254
*invert_image (Image, Image)

*显示边缘模式
dev_set_draw ('margin')
*获得窗口句柄
dev_get_window (WindowHandle)

*使用一个容器,装 笔记(区域)
*创建空对象
gen_empty_obj (arrObj)

for Index := 0 to (numbers-1) by 1
    *显示图像类型变量
    *作用:覆盖下面的文字显示
    dev_display (Image)
    *设置光标位置
    set_tposition (WindowHandle, 20, 400)
    *往窗口写入信息
    write_string (WindowHandle, '绘制第'+(Index+1)+'个,左键按下绘制,右键结束')
    
    *绘制矩形1,得到坐标信息
    draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
    *创建矩形区域1
    gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
    *图像剪切
    reduce_domain (Image, Rectangle, ImageReduced)
    
    *二值化 --> 得到字体的笔记(区域)
    threshold (ImageReduced, Region, 30, 80)

    *对象拼接 arrObj + Region = arrObj
    concat_obj (arrObj, Region, arrObj)
    
endfor



*笔记与预训练文件关联起来
for Index1 := 1 to numbers by 1
    *选择对象 从arrObj 里选择
    *赋值给 ObjectSelected
    *索引 从1开始的,特殊!!!
    select_obj (arrObj, ObjectSelected, Index1)
    
    *追加训练模型到预训练文件
    * 笔记区域 ObjectSelected
    * 区域所在图像 ImageReduced
    * 区域对应的字符 text[Index-1]
    * 预训练文件全路径 'train_ocr'
    append_ocr_trainf (ObjectSelected, Image, text[Index1-1], ocrTrf)
    
    *append 追加的模式,优点:可以无限添加 缺点:训练错误没有办法单独删除错误的那一个
    
    *覆盖的形式写入 每次训练都是最新的文件
    *write_ocr_trainf (ObjectSelected, Image, text[Index1-1], ocrTrf)
    
endfor


*读取训练文件
* CharacterNames 库存在的关联字符串
* CharacterCount 每个字符串关联过的次数(训练次数)
read_ocr_trainf_names (ocrTrf, CharacterNames, CharacterCount)

*创建训练句柄
* 8, 10 字符宽,高
* 字符参数 'constant', 'default', 
* CharacterNames 库存的关联字符
* 80 因此的神经元个数 
* OCRHandle 输出 训练的句柄
create_ocr_class_mlp (8, 10, 'constant', 'default', CharacterNames, 80, 'none', 10, 42, OCRHandle)

*开始训练
* 200 训练次数 0.01 每次叠加的值
trainf_ocr_class_mlp (OCRHandle, ocrTrf, 200, 1, 0.01, Error, ErrorLog)


*保存训练文件
write_ocr_class_mlp (OCRHandle, ocrOmc)


*2.验证  
*清除 OCR 句柄 (方便验证,所以清除前面的)
clear_ocr_class_mlp (OCRHandle)
*从本地加载分离器
* ocrOmc 路径
read_ocr_class_mlp (ocrOmc, OCRHandle1)
*试验 庭 是否能识别出来(最好用中间的测试)
select_obj (arrObj, ObjectSelected1, 2)
*ocr识别
do_ocr_multi_class_mlp (ObjectSelected1, Image, OCRHandle1, Class, Confidence)
注意事项
*注意:常见问题
*1.放一个没有训练过的笔记,识别不会报错(只会误判),往往会识别成最后一个训练的笔记
*因此需要 Class(结果) + Confidence(置信度),其中置信度>0.98 才算识别成功

*2.完善训练样本——生成大批量复杂样本
* 助手 》 OCR助手 》 文件 》 加载训练文件
* OCR 》 浏览训练文件 》 生成样本变形 》 保存训练文件
识别麻将

要点解析

 代码

*OCR 识别作业2
* 识别麻将
read_image (Image1, 'D:/hoclan/OCR/fb.bmp')
*获得窗口句柄
dev_get_window (WindowHandle)
*设置显示边缘模式,方便查看选中内容
dev_set_draw ('margin')
rgb1_to_gray (Image1, Image1)
*绘制矩形1区域
draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
*创建矩形1区域
gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
*把目标区域扣下来
reduce_domain (Image1, Rectangle, ImageReduced)
*图像反转
*invert_image (ImageReduced, ImageReduced)

*设置显示模式为填充模式,因为前面的边缘模式导致二值化区分不好看
dev_set_draw ('fill')
*blob 三步骤:1.threshold 2.connection 3.select_shape
*二值化 136
threshold (ImageReduced, Region, 30, 136)
*连通分割
connection (Region, ConnectedRegions)

*筛选 按条件筛选
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 38650.8, 65000)

*3.进行字符识别
fbOcrOmc:= 'D:/hoclan/001halcon/fb_ocr.omc'
*读取光学字符分类器
read_ocr_class_mlp (fbOcrOmc, OCRHandle)
*开始分类
do_ocr_multi_class_mlp (SelectedRegions, ImageReduced, OCRHandle, Class, Confidence)
*求显示信息的坐标
area_center (SelectedRegions, Area, Row, Column)


dev_display (Image1)
*窗口显示文本信息
dev_disp_text (Class+Confidence, 'image', Row+150, Column, 'black', ['box','box_color'], ['true','white'])

 

案例三:ORC识别车牌号码(训练模式)

参考代码

其中用到的训练模式需要自己参考上面案例二训练后使用

 * OCR识别作业
 
 * 1.识别李老师车牌号码
 
 *读取图片
read_image (Car1, 'D:/hoclan/OCR/car1.jpg')
*转灰度图
rgb1_to_gray (Car1, Car1)

carOcrOmc:= 'D:/hoclan/001halcon/car_ocr.omc'

*获得窗口句柄
dev_get_window (WindowHandle)
*设置显示边缘模式,方便查看选中内容
dev_set_draw ('margin')

*绘制矩形1区域
draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
*创建矩形1区域
gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)

*把目标区域扣下来
reduce_domain (Car1, Rectangle, ImageReduced)

*转白纸黑字才能识别
invert_image (ImageReduced, ImageReduced)

*2.提取车牌字符的区域
*(因为OCR 识别的是区域)

*设置显示模式为填充模式,因为前面的边缘模式导致二值化区分不好看
dev_set_draw ('fill')

*blob 三步骤:1.threshold 2.connection 3.select_shape
*二值化
threshold (ImageReduced, Region, 0, 60)
*连通分割
connection (Region, ConnectedRegions)
*筛选 按区高度
select_shape (ConnectedRegions, SelectedRegions1, 'height', 'and', 100, 130)


*3.进行字符识别

*读取光学字符分类器
* Industrial_0-9A-Z_NoRej.omc 分类器路径
* OCRHandle 识别句柄
*read_ocr_class_mlp (carOcrOmc, OCRHandle)
read_ocr_class_mlp ('Industrial_0-9A-Z_NoRej.omc', OCRHandle)
*开始分类
* SelectedRegions 输入 字体(笔记)区域
* ImageReduced 输入 区域所在的图像
* OCRHandle 输入 识别句柄
* Class 输出 识别返回结果
* Confidence 输出 置信度(得分)0.999不一定靠谱啊
do_ocr_multi_class_mlp (SelectedRegions1, ImageReduced, OCRHandle, Class, Confidence)
* 车牌特殊字O和I的处理
for Index := 0 to |Class|-1 by 1
    if (Class[Index] == 'I')
        Class[Index] := '1'
    elseif (Class[Index] == 'O')
        Class[Index] := '0'
    endif
endfor

*求显示信息的坐标
area_center (SelectedRegions1, Area, Row, Column)


*处理汉字
*如果可信度小于0.98,则是识别不达标,转汉字处理
*先找到汉字的区域
for Index1 := 0 to |Class|-1 by 1
    if (Confidence[Index1] < 0.98)
        *绘制矩形1区域
        draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
        *创建矩形1区域
        gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)  
        *把目标区域扣下来
        reduce_domain (Car1, Rectangle, ImageReduced) 
        *转白纸黑字才能识别
        invert_image (ImageReduced, ImageReduced)
        *设置显示模式为填充模式,因为前面的边缘模式导致二值化区分不好看
        dev_set_draw ('fill')
        
        *blob 三步骤:1.threshold 2.connection 3.select_shape
        *二值化
        threshold (ImageReduced, Region, 0, 60)
        *连通分割
        connection (Region, ConnectedRegions)
        *筛选 按区高度
        select_shape (ConnectedRegions, SelectedRegions1, 'height', 'and', 100, 130) 
        *读取光学字符分类器
        read_ocr_class_mlp (carOcrOmc, OCRHandle)
        *开始分类
        do_ocr_multi_class_mlp (SelectedRegions1, ImageReduced, OCRHandle, Class1, Confidence1)
        *赋值
        Confidence[Index1] := Confidence1
        Class[Index1] := Class1
       break
    endif
endfor

*窗口显示文本信息
dev_disp_text (Class, 'image', Row+40, Column, 'black', ['box','box_color'], ['true','white'])

 

案例三:ORC识别+极坐标转换

参考代码
*3.扇形区域平铺
read_image (Cricle, 'D:/hoclan/OCR/cricle.png')

rgb1_to_gray (Cricle, GrayImage)
*得到圆心
threshold (Cricle, Region, 0, 50)
connection (Region, ConnectedRegions)
select_shape (Region, SelectedRegions, 'area', 'and', 50000, 53000)
area_center (SelectedRegions, Area, Row, Column)

* Row, Column 圆的中心点坐标
* 45, 135 起始、结束弧度 (注意这里位置反写)
* 0, 100 极坐标的开始和结束极长(注意这里位置反写)
* 512, 512 输出图片的宽高
polar_trans_image_ext (Cricle, PolarTransImage, \
                       Row, Column,\ 
                       rad(155), rad(25),\
                       Row-30,Row-150, \
                       900, 120, 'nearest_neighbor')

dev_get_window (WindowHandle)
*绘制矩形1区域
draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
*创建矩形1区域
gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
*把目标区域扣下来
reduce_domain (PolarTransImage, Rectangle, ImageReduced)

rgb1_to_gray (ImageReduced, ImageReduced)
*blob三步
threshold (ImageReduced, Region1, 0, 90)
connection (Region1, ConnectedRegions1)
select_shape (ConnectedRegions1, SelectedRegions2, 'area', 'and', 700, 1550)

area_center (SelectedRegions2, Area1, Row3, Column3)

*读取光学字符分类器
read_ocr_class_mlp ('Industrial_0-9A-Z_NoRej.omc', OCRHandle)

*开始分类
do_ocr_multi_class_mlp (SelectedRegions2, ImageReduced, OCRHandle, Class, Confidence)



*窗口显示文本信息
dev_disp_text (Class, 'image', Row3+20, Column3, 'black',  ['box','box_color'], ['true','white'])

 

 

posted @ 2024-08-18 19:09  别动我的猫  阅读(67)  评论(0编辑  收藏  举报