Halcon学习(6):Halcon制作训练集、训练分类器并识别汉字

时间:2024-04-03 10:46:52

代码不是很鲁棒,所以换一张图片,Blob分析的结果有很大的可能是提取不到下面九个字,不过处理的方法和流程是相同的,可以参考参考。其他没有什么好说明的,信息全在注释里面,原图有点大,这里只贴个部分截图。

Halcon学习(6):Halcon制作训练集、训练分类器并识别汉字

代码如下:

*
******提取原图“机器视觉算法与运用”这个9个字
*
dev_close_window ( )
dev_update_window ('off')
read_image (Chaincharact, 'E:/HalconCodeing/image/chainCharact.jpg')
dev_open_window_fit_image (Chaincharact, 0, 0, -1, -1, WindowHandle)
dev_display (Chaincharact)
rgb1_to_gray (Chaincharact, GrayImage)
*缩放像素值,加强对比度
scale_image (GrayImage, ImageScaled, 6.71053, -698)
threshold (ImageScaled, Regions, 226, 255)
dev_clear_window ( )
dev_set_colored(12)
connection (Regions, ConnectedRegions)
dev_display (ConnectedRegions)
*汉字笔画间不连通,通过膨胀让它们连接
dilation_rectangle1 (ConnectedRegions, RegionDilation, 8, 8)
union1 (RegionDilation, RegionUnion)
connection (RegionUnion, ConnectedRegions1)
select_shape (ConnectedRegions1, SelectedRegions, ['area','width','height'], 'and', [10884,117,136.655], [16358,131,157])
dev_clear_window ( )
dev_display (SelectedRegions)
*
******几何校正
*
union1 (SelectedRegions, RegionUnion1)
shape_trans (RegionUnion1, RegionTrans, 'rectangle2')
orientation_region (RegionTrans, Phi)
area_center (RegionTrans, Area, Row, Column)
vector_angle_to_rigid (Row, Column, Phi, Row, Column, -rad(180), HomMat2D)
affine_trans_region (RegionTrans, RegionAffineTrans, HomMat2D, 'false')
affine_trans_image (Chaincharact, ImageAffinTrans, HomMat2D, 'constant', 'false')
reduce_domain (ImageAffinTrans, RegionAffineTrans, ImageReduced)
dev_clear_window ( )
dev_display (ImageReduced)
*
******得到校正后“机器视觉算法与运用”这个9个字
*
rgb1_to_gray (ImageReduced, GrayImage1)
threshold (GrayImage1, Regions1, 214, 238)
dev_set_colored (12)
connection (Regions1, ConnectedRegions2)
dev_clear_window ( )
dev_display (ConnectedRegions2)
dilation_rectangle1 (ConnectedRegions2, RegionDilation1, 11, 11)
union1 (RegionDilation1, RegionUnion2)
connection (RegionUnion2, ConnectedRegions3)
dev_clear_window ( )
dev_display (ConnectedRegions3)

*
******下面的代码是自己训练分析器,并识别上面的汉字(下面包含Halcon制作训练集、训练分析器和识别的整个过程)
*

*1 制作训练集TrainFile。这里只是制作了这九个字的训练集,并且每个字只有一张trf图片。所以整个训练集只有九张trf图片
*本来每个字的图片是可以用Halcon提供的工具通过旋转等方法,由一张图片生成若干张相似的图片。我看到Halcon12
*有这样的工具,不过我用的Halcon10没发现有。
sort_region (ConnectedRegions3, SortedRegions, 'first_point' , 'true', 'column')
count_obj (SortedRegions, Number)
characts := ['计','器','视','觉','算','法','与','运','用']
TrainFile := 'E:/HalconCodeing/charact.trf'
for i := 1 to Number by 1
    select_obj (SortedRegions, ObjectSelected, i)
    append_ocr_trainf (ObjectSelected, ImageAffinTrans, characts[i-1], TrainFile)
endfor

*2 得到分类器FontFile。


*2.1 训练分类器前准备
read_ocr_trainf_names (TrainFile, CharacterNames, CharacterCount)
NumHidden := 20
*2.2 创建神经网络分类器
create_ocr_class_mlp (8, 10, 'constant', 'default', CharacterNames, 80, 'none', 10, 42, OCRHandle)
*2.3 训练分类器
FontFile := 'E:/HalconCodeing/charact.omc'
trainf_ocr_class_mlp (OCRHandle, TrainFile, 200, 1, 0.01, Error, ErrorLog)
*2.4 保存分类器到本地
write_ocr_class_mlp (OCRHandle, FontFile)
*2.5 释放资源
clear_ocr_class_mlp (OCRHandle)


*3 用自己训练得到的分类器识别汉字

read_ocr_class_mlp (FontFile, OCRHandle1)
do_ocr_multi_class_mlp (SortedRegions, ImageReduced, OCRHandle1, Class, Confidence)

*吐槽Halcon显示算子和机制,体验感极差!!!这个显示有问题,选择window时不能正常显示结果。
*选用image时,有字体显示,但是每次只会显示一个汉字
*有哪位大佬知道下面不能显示的原因嘛?????????????
dev_display (Chaincharact)
for i := 1 to Number by 1
    Column := Column + 20
    disp_message (WindowHandle, Class[i-1], 'image', Row - 40, Column, 'black', 'true')
endfor

虽然显示结果不友好,但还是贴一下:

Halcon学习(6):Halcon制作训练集、训练分类器并识别汉字

好像知道了错在哪里了,选择在image显示不能正常展示的是Column := Column + 20这个加20有点小,后显示的会覆盖前面显示的,换成如下代码就有如下效果:

dev_display (Chaincharact)
for i := 1 to Number by 1
    disp_message (WindowHandle, Class[i-1], 'image', 720, 100+i*120, 'black', 'true')
endfor

Halcon学习(6):Halcon制作训练集、训练分类器并识别汉字

选择在window显示不能正常展示的原因是窗口像素体系比image像素体系要小,改成如下代码有如下显示效果(可以对比一下这两个体系中横纵坐标像素值的巨大差异):

dev_display (Chaincharact)
for i := 1 to Number by 1
    disp_message (WindowHandle, Class[i-1], 'window', 220, 20+i*40, 'black', 'true')
endfor

Halcon学习(6):Halcon制作训练集、训练分类器并识别汉字

总结:汉字识别的过程在上述代码注释中,这里就不啰嗦了。关键是发现了算子disp_message选择‘image’和‘window’两种不同方式会导致巨大差异的现象。以前没有出现这种巨大的差异,应该是以前读入的图片不是很大,窗口像素体系和图片像素体系相同或者相似。这次读入的图片是用手机拍摄的,分辨率是1444*1920,而窗口的分辨率大概在600*600左右。