[字符识别系列][一] 字符识别中的图像归一化算法简介

本文介绍3种基本的字符形状归一化算法(Character Shape Normalization)。字符归一化是光学字符识别中的一个子步骤,给定一个字符区域,我们要做的就是将该区域内的字符归一化到一个标准模板大小,然后才能提取特征,并送给分类器做具体的识别。好的归一化算法可以尽量提高后续特征提取在同一类内的一致性。

先来看一个例子,假如上帝拥有一个完美的字符归一化算法,那么他将可以做到如下所示的效果:

图1,完美的归一化:左边为原始字符区域,右边为归一化后的结果。

如果说我们能做到上述结果,那么也就无需再做特征提取,也无需再做训练,而只需简单的模板匹配即可得到100%准确的分类结果。可以看到,上述算法的能力在于:

1. 归一化到标准模板大小

2. 倾斜校正

3. 笔画宽度归一化

4. 字形归一化


可惜的是,今天介绍的几种常见算法仅能保证第1点的实现,而2,3则只能实现部分。至于4,就让后续的特征提取去弥补吧。言归正传,3个算法分别是:线性归一化算法,基于图像矩的归一化以及非线性归一化算法。


按惯例,3个算法的标准c实现可在:

https://github.com/UnilVision/visionbase/tree/master/ocr/baseline/normalization找到。希望对大家有所帮助。


线性归一化:线性归一化算法就是一个标准的线性采样过程,采用线性插值获得最终的图像结果。在我们的实现中,使用反向计算的方式:

其中为长和宽的比值。

对应代码中的函数为:

void backward_linear(unsigned char* src, int src_wid, int src_hei, int src_widstep,
					 CHARECT_t* region,
					 unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep,
					 int ratio_preserve_func);

图像矩归一化: 我们可以通过图像矩来预先校正字符的倾斜度,并通过矩来获得字体的实际大小[w1, h1]及中心位置[xc, yc]。归一化的原始区域被修改为

[xc-w1/2, xc+w1/2, yc-h1/2, yc+h1/2]。其计算方法为:


是一个经验值,一般取4。


其中图像矩的计算方法:



在找到新的区域[xc-w1/2, xc+w1/2, yc-h1/2, yc+h1/2]后,后续即调用线性归一化算法即可。对应代码中的实现为:

void backward_moment(unsigned char* src, int src_wid, int src_hei, int src_widstep,
					 CHARECT_t* region,
					 unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep,
					 int ratio_preserve_func);


图像矩倾斜校正:利用图像矩,我们可以找到字符的倾斜角

采样计算方式为:


注意这里我们仅调整x的位置以保证图像的中心仍然处于原始的xc,yc。其实现对于:

// slant correction
// Note>> (dst_wid, dst_hei) must equal to (region.width, region.height)
void backward_moment_slantcorrection(unsigned char* src, int src_wid, int src_hei, int src_widstep,
				     CHARECT_t* region,
				     unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep);

通常倾斜校正会放在归一化之前,已获得更好的效果。


非线性归一化:这里实现的是Jun Tsukumo在1988年提出的一个经典算法(原论文名称为Classification of Handprinted Chinese Characters Using Non-linear Normalization and Correlation Methods)。作者的思路是希望每一行,每一列的背景区域都可以平均分布。

为此,他首先为每个像素在x,y方向分别定义了个概率密度函数:以及。这两个函数的计算方法是:

如果(x,y)是一个属于字符区域的像素,那么都取一个极小值(在我们的实现中,这个值是0.001f,调整这个参数可以引起归一化后笔画的粗细变化)。

如果(x,y)是背景区域像素,那么:



其中分别是当前像素所处x方向背景像素的run-length和y方向的run-length。有了这两个密度函数,定义:



这里px和py就是归一化后的投影直方图了,为了在归一化后的图像中让px和py平均分布,引入两个函数hx,hy:



通过前向映射采样即可实现归一化操作:



注意这里与前两个算法的不同之处,前向映射是将当前图像的某个像素映射到归一化的图像中。而反向映射则是将归一化的图像中的某个像素位置映射到原图像中。

非线性归一化的实现对应:

void forward_nonlinear_1d(unsigned char* src, int src_wid, int src_hei, int src_widstep,
						  CHARECT_t* region,
						  unsigned char* dst, int dst_wid, int dst_hei, int dst_widstep,
						  int ratio_preserve_func);

参考结果

最后看下各个算法的结果:


图2,参考结果。从左到右依次:1. 原始扣取的图像通过OpenCV的resize函数缩放。2. 线性归一化。3.基于矩的归一化。4.先倾斜校正再基于矩的归一化。5.非线性归一化。


[原创文章,转载请注明出处:http://blog.csdn.net/unilvision/article/details/8624606]




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值