本篇笔记着重写的是如何训练汉字字符,让电脑能够识别出来汉字
1.使用系统训练好的文件完成车牌的识别
首先我在网上随便找了一直车牌图像
然后灰度化再进行阈值操作
下一步连通区域后进行特征选择,因为识别中文要训练,这里就先识别英文和数字,后面会有中文的识别详解。
因为这里的车牌看起来跟基本是水平的,就不用矫正了。识别前需要将灰度图反转一下(因为我选的字体’Industrial_0-9A-Z_NoRej.omc’是在亮背景下识别暗的字体)
车牌识别比较简单,就没有详细解释了,接下来重点来了。
2.训练OCR模型识别汉字
首先,我采用的图像是自己简单手写的几个字(字写得不好见谅哈)
老套路,首先进行灰度化,再通过阈值操作、区域连通、特征选择等操作来讲字符提取出来。
不过这里值得一提的是,汉字不像英文字符和数字一样,每个汉字并不是全都是相连的,可以从图中看出这个识别的识字,就笔画就隔得非常远,我私下试过很多形态学操作,还是不能将这留个字符一次性分割出来,所以我就先将识字单独拿出来训练识别。
* 灰度化
rgb1_to_gray (Image, GrayImage)
* 通过图像可以看出,想要将这个'识'字连通会很难,将它膨胀,可以会与旁边的别字连起来(这里我已经试过了)
* 所以这里的别字我是单独拿出来的
* 阈值操作初步筛选
threshold (GrayImage, Regions, 29, 44)
* 膨胀,尽量的将单个字体连接起来
dilation_circle (Regions, RegionDilation, 30)
* 区域分割
connection (RegionDilation, ConnectedRegions)
* 特征区域选择
select_shape (ConnectedRegions, SelectedRegions, 'row', 'and', 2305.56, 2657.41)
拿出来之后,将其各个区域合并(求并集)
* 将各个区域求并集
union1 (SelectedRegions, RegionUnion)
现在看到的字还是倾斜的,我们要把它矫正
* 得到带方向的外界矩形
shape_trans (RegionUnion, RegionTrans, 'rectangle2')
* 得到区域的弧度
orientation_region (RegionTrans, Phi)
* 得到区域的中心点和面积
area_center (RegionUnion, Area, Row, Column)
* 得到刚性仿射变换矩阵,这里只是旋转了一下
vector_angle_to_rigid (Row, Column, Phi, Row, Column, rad(90), HomMat2D)
* 区域仿射变换
affine_trans_region (RegionUnion, RegionAffineTrans, HomMat2D, 'nearest_neighbor')
* 图像仿射变换
affine_trans_image (GrayImage, ImageAffineTrans, HomMat2D, 'constant', 'false')
区域矫正:
灰度图矫正:
再将’识’字的区域从上面这张图中抠出来
* 抠图
reduce_domain (ImageAffineTrans, RegionAffineTrans, ImageReduced)
阈值选择拿到’识’字区域
* 阈值选择
threshold (ImageReduced, Regions1, 25, 49)
接下来先创建一个trf文件,用于存放’识’字
* 创建一个trf文件,将‘识’字存放进去
write_ocr_trainf (Regions1, ImageAffineTrans, '识', 'D:/shi.trf')
再拿到这个文件的句柄,用于创建模型
* 加载我们创建的trf文件
read_ocr_trainf_names ('D:/shi.trf', CharacterNames, CharacterCount)
* 创建模型
create_ocr_class_mlp (8, 10, 'constant', 'default', CharacterNames,\
80, 'none', 10, 42, OCRHandle)
模型创建好了之后就开始训练
* 训练模型
trainf_ocr_class_mlp (OCRHandle, 'D:/shi.trf', 200, 1, 0.01, Error1, ErrorLog1)
训练完就开始识别
* 识别
do_ocr_multi_class_mlp (Regions1, ImageAffineTrans, OCRHandle, Class, Confidence)
* 显示
disp_message (200000, Class, 'window', 0, 0, 'red', 'true')
做完了’识’字的训练,接下来就做剩下几个字符的训练
前面已经对图像做了blob分析了,现在直接拿来用,先进行特征选择拿到剩下几个字符的区域
* 特征选择
select_shape (ConnectedRegions, SelectedRegions1, ['area','height'], 'and', \
[10925.9,354.63], [163148,552.78])
然后一样的套路,求并集、得到外接矩形、矫正至水平方向
* 求并集
union1 (SelectedRegions1, RegionUnion1)
* 得到带方向的外界矩形
shape_trans (RegionUnion1, RegionTrans1, 'rectangle2')
* 得到弧度
orientation_region (RegionTrans1, Phi1)
* 旋转至水平,矫正
vector_angle_to_rigid (Row, Column, Phi1, Row, Column, rad(180), HomMat2D1)
* 区域旋转(矫正)
affine_trans_region (RegionTrans1, RegionAffineTrans1, HomMat2D1, 'nearest_neighbor')
* 灰度图旋转(矫正)
affine_trans_image (GrayImage, ImageAffineTrans1, HomMat2D1, 'constant', 'false')
然后进行抠图
* 抠图
reduce_domain (ImageAffineTrans1, RegionAffineTrans1, ImageReduced1)
阈值选择
* 阈值选择
threshold (ImageReduced1, Regions2, 21, 53)
因为这里的’别’字还不是完全连接的,所以这里要做一个膨胀操作,让字符连接起来
这样就连起来了,接下来就是连接区域
* 连接区域
connection (RegionDilation3, ConnectedRegions1)
这里有多个字符,所以我们要排一下序(字符排序:‘character’,按列来排序:‘column’)
* 排序
sort_region (ConnectedRegions1, SortedRegions, 'character', 'true', 'column')
然后创建训练的字符数组,一个一个训练
* 创建训练的字符数组
words := ['字','符','别','专','用']
for Index := 1 to |words| by 1
* 按顺序拿到单个字符
select_obj (SortedRegions, ObjectSelected, Index)
* 加入到训练文件
append_ocr_trainf (ObjectSelected, ImageAffineTrans, words[Index-1], 'D:/shi.trf')
endfor
然后就是读取训练文件,创建模型,训练模型
* 读取训练文件
read_ocr_trainf_names ('D:/shi.trf', CharacterNames1, CharacterCount1)
* 创建模型
create_ocr_class_mlp (8, 10, 'constant', 'default', CharacterNames1, 80, 'none', 10, 42, \
OCRHandle1)
* 训练模型
trainf_ocr_class_mlp (OCRHandle1, 'D:/shi.trf', 200, 1, 0.01, Error, ErrorLog)
最后进行识别
* 识别
do_ocr_multi_class_mlp (SortedRegions, ImageAffineTrans , OCRHandle1, Class1, Confidence1)
* 显示
disp_message (200000, Class1, 'window', 0, 0, 'green', 'true')
最后我们可以用新模型来识别一下’识’字看看行不行
* 识别
do_ocr_multi_class_mlp (Regions1, ImageReduced1, OCRHandle1, Class2, Confidence2)
可以看到是可以识别的,最后整个代码:
* Image Acquisition 01: Code generated by Image Acquisition 01
read_image (Image, 'D:/QQ下载/MobileFile/IMG_20201208_092539.jpg')
* 灰度化
rgb1_to_gray (Image, GrayImage)
* 通过图像可以看出,想要将这个'识'字连通会很难,将它膨胀,可以会与旁边的别字连起来(这里我已经试过了)
* 所以这里的别字我是单独拿出来识别的
* 阈值操作初步筛选
threshold (GrayImage, Regions, 29, 44)
* 膨胀,尽量的将单个字体连接起来
dilation_circle (Regions, RegionDilation, 30)
* 区域分割
connection (RegionDilation, ConnectedRegions)
* 特征区域选择
select_shape (ConnectedRegions, SelectedRegions, 'row', 'and', 2305.56, 2657.41)
* 将各个区域求并集
union1 (SelectedRegions, RegionUnion)
* 得到带方向的外界矩形
shape_trans (RegionUnion, RegionTrans, 'rectangle2')
* 得到区域的弧度
orientation_region (RegionTrans, Phi)
* 得到区域的中心点和面积
area_center (RegionUnion, Area, Row, Column)
* 得到刚性仿射变换矩阵,这里只是旋转了一下
vector_angle_to_rigid (Row, Column, Phi, Row, Column, rad(90), HomMat2D)
* 区域仿射变换
affine_trans_region (RegionUnion, RegionAffineTrans, HomMat2D, 'nearest_neighbor')
* 图像仿射变换
affine_trans_image (GrayImage, ImageAffineTrans, HomMat2D, 'constant', 'false')
* 抠图
reduce_domain (ImageAffineTrans, RegionAffineTrans, ImageReduced)
* 阈值选择
threshold (ImageReduced, Regions1, 25, 49)
* 创建一个trf文件,将‘识’字存放进去
write_ocr_trainf (Regions1, ImageAffineTrans, '识', 'D:/shi.trf')
* 加载我们创建的trf文件
read_ocr_trainf_names ('D:/shi.trf', CharacterNames, CharacterCount)
* 创建模型
create_ocr_class_mlp (8, 10, 'constant', 'default', CharacterNames,\
80, 'none', 10, 42, OCRHandle)
* 训练模型
trainf_ocr_class_mlp (OCRHandle, 'D:/shi.trf', 200, 1, 0.01, Error1, ErrorLog1)
* 识别
do_ocr_multi_class_mlp (Regions1, ImageAffineTrans, OCRHandle, Class, Confidence)
* 显示
disp_message (200000, Class, 'window', 0, 0, 'red', 'true')
* 特征选择
select_shape (ConnectedRegions, SelectedRegions1, ['area','height'], 'and', \
[10925.9,354.63], [163148,552.78])
* 求并集
union1 (SelectedRegions1, RegionUnion1)
* 得到带方向的外界矩形
shape_trans (RegionUnion1, RegionTrans1, 'rectangle2')
* 得到弧度
orientation_region (RegionTrans1, Phi1)
* 旋转至水平,矫正
vector_angle_to_rigid (Row, Column, Phi1, Row, Column, rad(180), HomMat2D1)
* 区域旋转(矫正)
affine_trans_region (RegionUnion1, RegionAffineTrans1, HomMat2D1, 'nearest_neighbor')
* 灰度图旋转(矫正)
affine_trans_image (GrayImage, ImageAffineTrans1, HomMat2D1, 'constant', 'false')
* 抠图
reduce_domain (ImageAffineTrans1, RegionAffineTrans1, ImageReduced1)
* 阈值选择
threshold (ImageReduced1, Regions2, 21, 53)
* 膨胀
dilation_circle (Regions2, RegionDilation3, 30)
* 连接区域
connection (RegionDilation3, ConnectedRegions1)
* 排序
sort_region (ConnectedRegions1, SortedRegions, 'character', 'true', 'column')
* 创建训练的字符数组
words := ['字','符','别','专','用']
for Index := 1 to |words| by 1
* 按顺序拿到单个字符
select_obj (SortedRegions, ObjectSelected, Index)
* 加入到训练文件
append_ocr_trainf (ObjectSelected, ImageAffineTrans, words[Index-1], 'D:/shi.trf')
endfor
* 读取训练文件
read_ocr_trainf_names ('D:/shi.trf', CharacterNames1, CharacterCount1)
* 创建模型
create_ocr_class_mlp (8, 10, 'constant', 'default', CharacterNames1, 80, 'none', 10, 42, \
OCRHandle1)
* 训练模型
trainf_ocr_class_mlp (OCRHandle1, 'D:/shi.trf', 200, 1, 0.01, Error, ErrorLog)
* 识别
do_ocr_multi_class_mlp (SortedRegions, ImageAffineTrans , OCRHandle1, Class1, Confidence1)
* 显示
disp_message (200000, Class1, 'window', 0, 0, 'green', 'true')
* 识别
do_ocr_multi_class_mlp (Regions1, ImageReduced1, OCRHandle1, Class2, Confidence2)
萌新学习中,请大佬们多多指点。
原创不易,对您有帮助点个小赞吧,谢谢!