基于多特征提取的手写汉字识别算法及其实现 第5页
为了便于识别,需要定义阙值dis,若d<dis,即可认为输入汉字为字库中第i个字符。
至此该算法的步骤可以归纳如下:
(1) 对输入图形进行4*4分区,统计每区黑色相素点数。
(2) 将每区黑色相素点数除以图像总黑相素点数,的到p[i],i=1,2……9。
(3) 由2.5式得到距离d,然后匹配判别。
该方法形象直观,也很容易实现,但其弊端很多,表现在以下几个方面,
(1) 这种方法只局限于一种字体且多用于印刷体汉字的识别,手写体汉字由于字形变化、歪曲教大,只使用该方法收效甚微。
(2) 由于汉字图像大小不一,在读如图像后需要对其做规范化预处理。
(3) 在汉字中存在很多字形十分相似的字,如“冢”和“家”,“狼”和“狠”等,基于统计的识别算法对这些字不能区分。
(4) 由于直接对图像进行分析,所以该方法主要用于脱机汉字识别。
2.2 现行算法的结合和改进
上节我们分别讲述了基因笔划特征和基于基于统计特征的的汉字识别算法,也讲了两种方法的优缺点,下面我面介绍怎么将两种算法结合并改进以进行联机手写汉字识别。
汉字是一种结构文字,即它的输入有一定的顺序,每一笔也有一定的结构,所以在进行联机手写汉字识别时,笔划信息一定要充分利用起来,同时我们知道,单纯的笔划特征不足以区分所有汉字,现在我们考虑将输入汉字图像分别从笔划和相素角度做两次分类识别,以下分别称为粗分类和细分类。
在粗分类阶段,我们根据2.1.1小节中的算法先把汉字定位于小范围内,即根据笔划数和笔划顺序从字库选出几个可能的汉字,至于怎样从这几个汉字中找出正确的对应字符就由细分类部分完成。
在细分类阶段,可以根据2.1.2小节中的算法对粗分类后的若干汉字进行识别,由于范围已经很小,所以该步骤不需要划分太细,通常情况下做3*3分区即可取得理想结果。注意,正如2.1.2小节中所说,用该方法要对汉字图像做规范化处理,我们可以稍做改进,把每区的黑色相素点数改为次数与汉字总相素点数的比值,这样就可以排除汉字大小不一的干扰。
在以上两个阶段,阙值的选取都十分重要,阙值太大则无法选出具体的汉字,阙值太小又可能由于书写不规范而无法识别,具体值可以根据多次实践、观察结果分析得出,同样处理的还有2.1.1小节的笔划相似度表,若结果不理想可以适当修改该表。
至此我们已经很详细的讲述了要采取联机手写汉字的识别算法,但不管什么算法都需要一种计算机语言去实现(通常使用高级语言),在下章,我们将给出各步骤实现的vc 代码,以便分析结果。
附注:
在下图中给出了基于多特征提取的联机手写汉字识别算法的流程图,借助此图可以更清晰地理解该算法。
图2.6 汉字识别算法流程图
3 识别算法对应的vc代码
在本章中,我们将介绍文字预处理、识别、识别后处理的代码,语句一般大都简单,有难度的语句后面都有文章注释,所以在文中不在详细讲解,每一程序都在vc平台中调试过并成功运行,如不能允许请检查代码是否抄错。因为篇幅原因,用户界面、鼠标手写笔模拟等程序代码不再给出,有需要可自行查阅参考数目。首先介绍一下程序实现所需的数据结构:
int num,Time;
int xmax,ymax,xmin,ymin;//随时记录最大x,y坐标
int mouseDown;//鼠标按下标记
int fxm[15][300];//方向码
int zong;//字库中的字符总数
struct
{
int x;
int y;
}store[15][300];//一笔划点序列
//备份的序列
struct
{
int x;
int y;
}storeback[15][300];
struct
{
char zifu[2];//代表字符
int total;//总的笔划数
int bh[15];//每个笔划的点数
double p[9];//每区相素比重
}tez[4000];
struct
{
char zifu[2];
int total;//笔画数
int bh[15];//笔画码序列
double p[9];//每区相素比重
}test;//意义同上,为测试点的结构
struct fangxtz
{
int b[8];//每方向点数
int total;//共有方向数
int totaldian;//共有点数
}fxtz[15];
3.1 输入预处理
//数据去噪、处理函数,得到笔划码序列
void CRecogDlg::DealDat()
{
int i,j,k;
for(i=0;i<15;i++) //得到方向序列码fxm[15][300],已验证,正确
for(j=0;(j<300)&&(store[i][j].x!=-1);j++)
{
if(store[i][j+2].y==store[i][j].y)
{
if(store[i][j+2].x>store[i][j].x)
fxm[i][j]=1;
else if(store[i][j+2].x<store[i][j].x)
fxm[i][j]=5;
}
if(store[i][j+2].x==store[i][j].x)
{
if(store[i][j+2].y>store[i][j].y)
fxm[i][j]=3;
else if(store[i][j+2].y<store[i][j].y)
fxm[i][2]=7;
}
if(store[i][j+2].y>store[i][j].y)
{
if(store[i][j+2].x>store[i][j].x)
fxm[i][j]=2;
else if(store[i][j+2].x<store[i][j].x)
fxm[i][j]=4;
}
上一页 [1] [2] [3] [4] [5] [6] [7] [8] 下一页