文章目录
前言
本文主要实现基于halcon的机器学习的多层感知机分类器实现OCR,从数据集训练到数据检测,训练符合自己的OCR模型。
一、数据集介绍
本次数据集为喷枪打码的工件图像
需要实现的功能是计算机识别得到:G37657183P的字符串。
二、halcon实现思路
- 因为工件在相机中的位置是固定的,所以首先可设置ROI,对图像进行截取,把不必要的区域直接去掉
- 然后阈值处理,得到每个字符的region,这样每一个字符就代表一个region,可以单独取出region内容
- 对每个region进行标注
- 对标注好的数据输送到OCR的MLP训练器中进行训练。
- 得到模型后即可完成检测
三、halcon脚本-标注训练
1.理解训练OCR得到的是什么
TrainFile:='MyTrainocr.trf'
FontFile:='MyTrainOCR.omc'
这两个文件分别是训练数据集和保存训练完的模型
2.对原始图像进行处理,获得训练数据集
1.首先绘制ROI获得感兴趣区域
这里使用算子:
draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
2.对截图图像进行区域处理
先二值化获得区域,分割区域后进行按行排序,确保顺序
主要用到算子:
threshold (ImageReduced, Region, 0, 130)
connection (RegionDilation, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5000, 99999)
sort_region (SelectedRegions, SortedRegions, 'character', 'true', 'row')
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)
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)
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)
四、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)
效果如图
这里分别获得分数和类别,直接把RecNum拼接即可。
总结
对本次OCR的脚本有疑问可直接私聊,源码在文章中已全部展示,如果搭建时有问题可进行询问