OCR(Optical Character Recognition),光学字符识别,是指使用扫描仪或数码相机等电子设备检查纸上的字符,通过检测暗、亮的方法确定字符的形状,并使用字符识别方法把字符转化为计算机数据的过程;即对文本资料进行扫描,然后对图像文件进行图像处理和分析,最终获取文字的过程。
一、OCR主要步骤:
获取图像、选取感兴趣区域(ROI,Region ofInterest)、图像校正、图像预处理(滤波)、提取分割参数、分割图像等步骤主要运用图像处理技术。训练OCR、读取特征、显示结果、摧毁分类器等步骤主要运用人工神经网络技术。
图像预处理
- 倾斜校正
模板匹配 - 降噪
滤波、光照处理 - 增强(可选)
灰度拉伸 - 二值化
由灰度图像变成二值图像
图像分割
- 行分割
身份证图像字符信息分布规则,每行有一定间隙;采用水平投影法进行图像分割 - 字符分割
垂直投影
字符识别,即模式识别技术
- 训练OCR(或读取Halcon中自带的训练分类器)
- 读取特征
识别结果处理
- 例程验证
可能有些人在图像处理技术里面会有做着做着就不知道下一步该干什么了的问题,其实,我们要知道我们前面应用图像处理技术这一步的目的是什么,无非就是把需要识别的字符分割出来。那么大方向有了,细节其实就没有那么死板了,是很灵活的,只要记住字体有倾斜要校正,后面一系列处理都是为分割服务的,无非就是用二值化、形态学、特征提取、然后分割(点状字体要intersection求一下交集,将点连接起来形成一个连通域)这些套路,至于其中一些具体细节、方法需要大家实战积累,最后交给后面的识别就妥了。
二、模式识别技术
1、训练OCR分为离线处理和在线识别:
- 离线处理:包括训练字体,将区域代表的字母或数字提取出来并以相应的字符名储存在训练文件中,用来训练字体的训练文件中的内容可以有选择的进行再次修改。
离线处理过程:
1)生成训练文件.trf:每一个字符的大量训练样本存在训练文件.trf 中
注意:图像上每个字体都要形成一个连通域
2)创建训练器:对如颜色、纹理等特征进行分类。Halcon中的分类器主要有多层神经网络(MLP)、支持向量机(SVM) 、K-最邻近 (K-NN)、高斯混合类型(GMM)
3)训练分类器:训练文件.trf+新ocr分类器
4)保存分类器
5)识别字符:do_ocr_multi_class_mlp(一起识别)或 do_ocr_single_class_mlp(逐个识别) - 在线识别部分:读取已经训练好的字体文件(.ocm)或Halcon自带的训练文件(.ocm),通过图像预处理将图像中的字符区域提取并分割来,再使用分类器对提取出来的区域进行识别。
三、实战 1:以食品包装袋生产日期为例
dev_close_window () dev_open_window (0, 0, 680, 300, 'black', WindowHandle) *定位 read_image (Image2, 'C:/Users/Administrator/Desktop/2.bmp') disp_message (WindowHandle, '请绘制ROI区域,我的宝贝', 'window', 12, 12, 'blue', 'true') draw_rectangle2 (WindowHandle, Row, Column, Phi, Length1, Length2) gen_rectangle2 (Rectangle, Row, Column, Phi, Length1, Length2) *校正 area_center (Rectangle, Area, Row1, Column1) text_line_orientation (Rectangle, Image2, 75, -Phi, Phi, OrientationAngle) vector_angle_to_rigid (Row1, Column1, OrientationAngle, Row1, Column1, 0, HomMat2D) affine_trans_image (Image2, ImageAffinTrans, HomMat2D, 'constant', 'false') affine_trans_region (Rectangle, RegionAffineTrans, HomMat2D, 'nearest_neighbor') *字符分割 reduce_domain (ImageAffinTrans, RegionAffineTrans, ImageReduced) dots_image (ImageReduced, DotImage, 15, 'dark', 0) binary_threshold (DotImage, Region, 'max_separability', 'light', UsedThreshold) dilation_rectangle1 (Region, RegionClosing, 10, 10) connection (RegionClosing, ConnectedRegions) shape_trans (ConnectedRegions, RegionTrans, 'rectangle1') select_shape (RegionTrans, SelectedRegions, ['height','width'], 'and', [69.184,27.55], [200,200]) partition_rectangle (SelectedRegions, Partitioned, 45, 85) intersection (Partitioned, Region, RegionIntersection) *字符识别 sort_region (RegionIntersection, SortedRegions, 'character', 'true', 'row') read_ocr_class_mlp ('C://Users//Administrator//Desktop//halcon程序//包装袋生产日期识别//DotPrint_0-9A-Z.omc', OCRHandle) do_ocr_multi_class_mlp (SortedRegions, ImageReduced, OCRHandle, Class, Confidence) *字符显示 dev_display (ImageAffinTrans) count_obj (SortedRegions, Number) smallest_rectangle1 (SortedRegions, Row11, Column1, Row2, Column21) for i := 1 to Number by 1 disp_message (WindowHandle, Class[i - 1], 'image', Row2[i - 1]+120, Column1[i - 1], 'blue', 'false') endfor
实战 2:表盘数字
dev_close_window () dev_open_window (0, 0, 680, 320, 'black', WindowHandle) set_display_font (WindowHandle, 40, 'mono', 'true', 'false') read_image (Image2, 'C:/Users/Administrator/Desktop/halcon程序/温度计表盘识别/字符.bmp') mirror_image (Image2, ImageMirror, 'row') mirror_image (ImageMirror, ImageMirror1, 'column') *1、预处理 scale_image (ImageMirror1, ImageScaled, 4.39655, -853) *2、Blob分析定位 threshold (ImageScaled, Regions, 0, 42) connection (Regions, ConnectedRegions) select_shape (ConnectedRegions, SelectedRegions, ['area','width','height'], 'and', [0,621.9,408.06], [459711,2000,542.36]) reduce_domain (ImageMirror1, SelectedRegions, ImageReduced) *3、字符分割 threshold (ImageReduced, Regions1, 67, 129) connection (Regions1, ConnectedRegions1) select_shape (ConnectedRegions1, SelectedRegions1, ['roundness','height','ra','rb'], 'and', [-0.8673,17.86,34.18,0.663], [0.6755,125,435.2,34.541]) union1 (SelectedRegions1, RegionUnion) *法一: *gen_rectangle2 (Rectangle, 16, 16, rad(145), 7, 7) *closing (RegionUnion, Rectangle, RegionClosing) *connection (RegionClosing, ConnectedRegions2) *intersection ( ConnectedRegions2, Regions1, RegionIntersection) *法二 dilation_rectangle1 (RegionUnion, RegionDilation, 10, 10) connection (RegionDilation, ConnectedRegions2) intersection ( ConnectedRegions2, Regions1, RegionIntersection) *4、字符识别 sort_region (RegionIntersection, SortedRegions, 'character', 'true', 'row') read_ocr_class_mlp ('Industrial_0-9A-Z_NoRej.omc', OCRHandle) do_ocr_multi_class_mlp (SortedRegions, ImageMirror1, OCRHandle, Class, Confidence) *5、显示 dev_display (ImageMirror1) count_obj (SortedRegions, Number) smallest_rectangle1 (SortedRegions, Row11, Column1, Row2, Column21) for i := 1 to Number by 1 disp_message (WindowHandle, Class[i - 1], 'image', Row2[i - 1], Column1[i - 1], 'blue', 'false') endfor
实战 3:环形字符
*1、读取图像 read_image (Image11, 'C:/Users/Administrator/Desktop/halcon程序/环形字符识别/1.1.bmp') dev_close_window () dev_open_window (0, 0, 480, 480, 'black', WindowHandle) dev_display (Image11) get_image_size (Image11, Width, Height) *2、环形字符校正 rgb1_to_gray (Image11, GrayImage) scale_image (GrayImage, ImageScaled, 1, 0) *求环形外圆区域 threshold (ImageScaled, Regions, 0, 106) shape_trans (Regions, RegionTrans, 'outer_circle') *求环形内圆区域 complement (Regions, RegionComplement) opening_circle (RegionComplement, RegionOpening, 8) connection (RegionOpening, ConnectedRegions) select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 1.37755e+006, 2.29592e+006) *求内外圆尺寸(圆心坐标和半径) *smallest_circle——一个区域周围的最小外接圆 *内圆 smallest_circle (SelectedRegions, Row, Column, Radius) *外圆 smallest_circle (RegionTrans, Row1, Column1, Radius1) *极坐标转换 polar_trans_image_ext (GrayImage, PolarTransImage, Row, Column, rad(360), 0, Radius1-100, Radius+40,1440,100, 'nearest_neighbor') *3、预处理+字符分割 invert_image (PolarTransImage, ImageInvert) scale_image (ImageInvert, ImageScaled1, 5.54348, -1147) binary_threshold (ImageScaled1, Region, 'max_separability', 'light', UsedThreshold) connection (Region, ConnectedRegions1) select_shape (ConnectedRegions1, SelectedRegions1, 'area', 'and', 67.15, 5000) union1 (SelectedRegions1, RegionUnion) dilation_rectangle1 (RegionUnion, RegionDilation, 5, 5) connection (RegionDilation, ConnectedRegions2) intersection (ConnectedRegions2, Region, RegionIntersection) sort_region (RegionIntersection, SortedRegions, 'character', 'true', 'column') *4、字符识别 read_ocr_class_mlp ('Industrial_0-9A-Z_NoRej.omc', OCRHandle) do_ocr_multi_class_mlp (SortedRegions, PolarTransImage, OCRHandle, Class, Confidence) *5、显示 dev_display (PolarTransImage) set_display_font (WindowHandle, 40, 'mono', 'true', 'false') count_obj (SortedRegions, Number) smallest_rectangle1 (SortedRegions, Row11, Column1, Row2, Column21) for i := 1 to Number by 1 disp_message (WindowHandle, Class[i - 1], 'image', Row2[i - 1]+10, Column1[i - 1], 'blue', 'false') endfor
核心思想:先进行极坐标转换,把环形区域拉直,后面套路一样,字符分割、提取、识别
关键代码:将图像直角坐标系转换成极坐标系函数
polar_trans_image_ext(Image :输入图像
PolarTransImage :输出图像
Row, 环形区域中心点y坐标
Column, 环形区域中心点x坐标
AngleStart, 要拉直的环形区域起始角度(与x轴正方向)
AngleEnd, 要拉直的环形区域终点角度
RadiusStart,要拉直的环形区域内圆与原点的距离
RadiusEnd, 要拉直的环形区域外圆与原点的距离
Width, Height, 输出图像的宽(一般1440)、高(一般字符高度)
Interpolation : 变换的差值算法)
注:因为直接用的halcon训练好的文件,里面并没有训练&,所以会显示8
总结:一般我们拿到图像后,一般都需要对目标区域进行校正处理,也就是几何变换,几何变换种类有:
- 极坐标转换:针对环形字符,将原图像直角坐标转换成极坐标,拉直polar_trans_image_ext()
zoom_image_factor() - 仿射变换:针对倾斜字体进行旋转(位移、缩放)等校正处理
- 投射变换:针对图像可能不是垂直拍摄的,发生了深度变化、垂直于图像方向发生倾斜时使用
戳戳小手帮忙点个免费的赞和关注吧,嘿嘿。 |