一、起语
点状喷射字符检测在实际项目中经常遇到,特别是在一些日期检测,SN编码检测项目中 非常常见,Halcon自带的例子dotprt.hdev程序,就这类检测给出了一定的项目思路,现做如下解析:
二、程序分析
第一步 读取图像

* 读图显示
dev_update_window ('off')
read_image (Needle, 'needle1')
dev_close_window ()
get_image_size (Needle, Width, Height)
dev_open_window (0, 0, 2 * Width, 2 * Height, 'black', WindowID)
set_display_font (WindowID, 16, 'mono', 'true', 'false')
dev_display (Needle)
disp_continue_message (WindowID, 'black', 'true')
stop ()
第二步 图像转正
* *图像转正
Row1 := 50
Column1 := 90
Row2 := 250
Column2 := 370
Px := Column1 + (Column2 - Column1) / 2
Py := Row1 + (Row2 - Row1) / 2
gen_rectangle1 (Rectangle1, Row1, Column1, Row2, Column2)
* orientation correction
*获取图像内文字的倾斜角度
text_line_orientation (Needle, Needle, 35, -0.523599, 0.523599, OrientationAngle)
*生成齐次变换矩阵
hom_mat2d_identity (HomMat2DIdentity)
*给变换矩阵添加旋转角度(即文字角度的反方向角度 将文字转水平)
hom_mat2d_rotate (HomMat2DIdentity, -OrientationAngle, Px, Py, HomMat2DRotate)
*对图像进行仿射变换
affine_trans_image (Needle, Rotated, HomMat2DRotate, 'constant', 'false')
dev_display (Rotated)
disp_continue_message (WindowID, 'black', 'true')
stop ()
第三步提取字符
*阈值分割提取图像内黑色特征区域
threshold (Rotated, RawSegmentation, 0, 105)
connection (RawSegmentation, ConnectedRegions)
select_shape (ConnectedRegions, MinSizeRegions, 'area', 'and', 6, 99999)
union1 (MinSizeRegions, RemovedNoise)
dev_display (Rotated)
dev_set_color ('green')
dev_set_draw ('fill')
dev_display (RemovedNoise)
disp_continue_message (WindowID, 'black', 'true')
stop ()
*指定区域大小(提取主要文字所在区域)
clip_region (RemovedNoise, RawSegmentation, 53, 75, 260, 356)
dev_display (Rotated)
dev_display (RawSegmentation)
disp_continue_message (WindowID, 'black', 'true')
stop ()
第四步 字符间断地方连接
closing_circle (RawSegmentation, ClosedPatterns, 6)
*通过开、闭运算将字符断开地方连接起来
opening_rectangle1 (ClosedPatterns, SplitPatterns, 1, 5)
connection (SplitPatterns, ConnPatterns)
select_shape (ConnPatterns, CharCandidates, 'area', 'and', 150, 5999)
shape_trans (CharCandidates, CharBlocks, 'rectangle1')
dev_set_draw ('margin')
dev_set_line_width (2)
dev_display (Rotated)
dev_display (CharBlocks)
disp_continue_message (WindowID, 'black', 'true')
stop ()
第五步 字符区域分割求交集
*这个算子 是根据文字单体大小 用矩形将文字区分开来(为后面求交集做准备)
partition_rectangle (CharBlocks, CharCandidates, 25, 100)
*原始文字分割区域与已经间断部分连接起来的文字区域求交集(使得每个字符都是一个整体)
intersection (CharCandidates, RawSegmentation, Characters)
closing_circle (Characters, IntermedCharacters, 2.5)
dev_set_colored (12)
dev_display (Rotated)
dev_set_draw ('fill')
dev_display (IntermedCharacters)
disp_continue_message (WindowID, 'black', 'true')
stop ()
第六步 筛选字符区域要识别的字符(去除干扰)
gen_empty_obj (Characters)
count_obj (IntermedCharacters, NumIntermediate)
dev_display (Rotated)
for i := 1 to NumIntermediate by 1
dev_set_color ('red')
select_obj (IntermedCharacters, Char, i)
dev_display (Char)
connection (Char, CharParts)
select_shape (CharParts, CharCandidates, 'area', 'and', 40, 99999)
union1 (CharCandidates, Char)
dev_set_color ('green')
dev_display (Char)
* disp_continue_message (WindowID, 'black', 'true')
* stop ()
concat_obj (Characters, Char, Characters)
endfor
select_shape (Characters, Heigh, 'height', 'and', 24, 50)
*将筛选得到的字符排序
sort_region (Heigh, FinalCharacters, 'character', 'true', 'row')
dev_set_color ('red')
dev_set_draw ('margin')
dev_display (Rotated)
dev_display (FinalCharacters)
dev_set_color ('green')
dev_set_line_width (3)
dev_set_shape ('rectangle1')
dev_display (FinalCharacters)
dev_set_shape ('original')
dev_set_line_width (1)
dev_set_draw ('fill')
第七步 字符识别
*利用Halcon自带的字库 DotPrint 进行字符识别
*读入字库
read_ocr_class_mlp ('DotPrint', OCRHandle)
*进行字符识别
do_ocr_multi_class_mlp (FinalCharacters, Rotated, OCRHandle, Class, Confidence)
smallest_rectangle1 (FinalCharacters, Row11, Column1, Row2, Column21)
*显示读取结果
count_obj (FinalCharacters, NumberFinal)
for i := 1 to NumberFinal by 1
disp_message (WindowID, Class[i - 1], 'image', Row2[i - 1], Column1[i - 1], 'green', 'false')
endfor
clear_ocr_class_mlp (OCRHandle)
dev_update_window ('on')
三、结语
总结这个例子,对于字符识别(非自训练字符),其识别过程关键步骤为:
1、字符的每个部分要组合成一个整体进行识别
2、字符如果有倾斜要先做仿射变换转正再做后续处理
3、要适当剔除字符中所有杂乱干扰特征