Halcon 非线性模式的字符识别(ocr_cd_print_polar_trans.hdev例程分析)
Halcon的学习笔记(一)——非线性字符识别
项目上需要对非线性模式的字符进行识别,halcon中包含的例程,我搜了一下,网上对于该例程的解析比较少,因此自己便记录了一下自己的学习例程,也算自己的学习笔记。
1. 什么是非线性字符识别?
字符排列整齐的前提下,识别只需要按照固定的方向即可完成对应的字符识别,然而并不是所有的字符都是符合上述排序方式的。其中有一部分是按照圆形、螺旋、锯齿等不规则模式进行排序的,那么此时就需要一些特殊的处理方式了。
图像来源于halcon例程
2. 图像预处理
先将包含待检测的字符区域的圆环提取出来:
* 均值滤波后与原图进行动态阈值分割,凸显出圆边缘
mean_image (Image, ImageMean, 211, 211)
dyn_threshold (Image, ImageMean, RegionDynThresh, 15, 'dark')
connection (RegionDynThresh, ConnectedRegions)
* 选择区域面积最大的区域
select_shape_std (ConnectedRegions, SelectedRegions, 'max_area', 0)
* 区域转换成轮廓并且进行拟合,拟合后以拟合圆心生成半径不同的同心圆
gen_contour_region_xld (SelectedRegions, Contours, 'border')
fit_circle_contour_xld (Contours, 'ahuber', -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
gen_circle (CircleO, Row, Column, Radius - 5)
gen_circle (CircleI, Row, Column, Radius - 30)
* 再将两个区域求差集获得圆环区域
difference (CircleO, CircleI, Ring)
到了这一步基本上完成了区域提取,提取这个圆环区域“Ring”有什么用呢?我们往下看(好吧,这个其实作用不大,只是display作用,后续展开的图像“高”是这个玩意儿,就类似于圆环彩纸剪开成矩形的那个“宽”)。
3. 图像极坐标转换
图像极坐标系转换原理请参考这篇文章,里面包含opencv的实现方式,能够更好的帮助理解 http://t.csdnimg.cn/XrUx7
其大致的意思比较简单如下图所示:
(上述图仅为个人对极坐标转换的理解,本人的表述可能存在一定问题,如果有问题还请大佬指正,谢谢)
halcon中的实现方式如下:
polar_trans_image_ext (Image, ImagePolar, Row, Column, 0, rad(360), Radius - 30, Radius - 5, WidthP, HeightP, 'bilinear')
dev_open_window (0, 0, WidthP, HeightP, 'black', WindowHandle2)
rotate_image (ImagePolar, ImageRotate, 180, 'constant')
其中“polar_trans_image_ext”具体请参考halcon的帮助文档,其中“Nearest Neighbor”是最近邻插值,合成的图像可能造成边缘锐利;“Bilinear”是双线性插值法,四邻域的加权平均生成新的像素值,边缘较好,但是耗时较久。
其中“rotate_image”是将平铺的图像旋转180°。
4. 字符区域提取
通过图像极坐标转换后,获得图像展开图像后需要有效的提取区域中的字符区域,具体代码如下:
* 再次利用动态阈值分割找到字符的区域
mean_image (ImageRotate, ImageMeanRotate, 51, 9)
dyn_threshold (ImageRotate, ImageMeanRotate, RegionDynThreshChar, 5, 'dark')
connection (RegionDynThreshChar, ConnectedRegions1)
* 提取“ConnectedRegions1”面积30-150 宽度4-10 的区域
select_shape (ConnectedRegions1, SelectedRegions, ['area', 'width'], 'and', [30, 4], [150, 10])
* 将区域按照“column”进行排序
sort_region (SelectedRegions, SortedRegions, 'character', 'false', 'column')
* 防呆作用 利用全局分割找到字符区域的整体范围,保留其与“SelectedRegions”有交集的
threshold (ImageMeanRotate, Region, 90, 255)
intersection (SelectedRegions, Region, RegionIntersection)
area_center (RegionIntersection, Area, Row1, Column1)
select_mask_obj (RegionIntersection, Characters, Area [>] 0)
dev_display (ImageRotate)
效果如下图所示:
5. 字符识别
* 加载0-9与A-z的字符模型
read_ocr_class_mlp ('Industrial_0-9A-Z_NoRej', OCRHandle)
* 按照character 模式排序
sort_region (Characters, SortedRegions, 'character', 'true', 'row')
* 字符识别 "Class"识别的结果,"Confidence"置信度
do_ocr_multi_class_mlp (SortedRegions, ImageRotate, OCRHandle, Class, Confidence)
* 将字符串中的"o"替换为"0"
tuple_regexp_replace (sum(Class), 'O', '0', Result)
“sort_region”其中’character’讲述起来有点困难,参考了下面这篇文章,按照文章描述该例程 对“row”还是“column”区别不大?该部分等后续再研究一下吧,也欢迎大佬替我补充解释一下。
https://www.cnblogs.com/xh6300/p/16573269.html
该例程主要是如何通过极坐标转换完成环形的字符识别,对于字符识别类的项目参考意义很大。
参考
[1] https://blog.csdn.net/LuohenYJ/article/details/114842373
[2] https://www.cnblogs.com/xh6300/p/16573269.html