一、实验目的 

初步了解模板匹配算法,理解bmp 图像在内存中的存储形式,实现bmp 格式图像印刷体数字的识别。 

二、算法概要 

由于实验要求是对标准印刷体数字进行识别,本实验采用模板匹配中最简单的像素点重合的方法,将待测图像中的数字与模板库中的各个数字进行比对,认为待测数字就是模板库中与其重合像素点最多的数字。 当bmp 图像读入实验板存储空间之后,imgbuf 指针指向其像素点数据的首地址。 

a) 模板库的建立 

将包含0—9 十个数字的十张bmp 格式的图像(本模板库的图像均为白色背景黑色字体)读入,将其像素信息分别存入十个50*50 的二维数组中。实验中规定灰度值低于50 的为有效像素点,其对应的二维数组中的数值定义为1,灰度值大于50 的认为是无效点,其对应的二维数组中的数值定义为0. 

b)待检测图像中的数字分离 

定义结构体 

struct 
{ 
int Left; 
int Right; 
}W[20]; 
struct 
{ 
int Up; 
int Down; 
}H[20];

如输入图像包含n*m 个数字,则需要将n*m 个数字分离开之后,分别与模板库匹配并分别识别,将识别结果存入result[m*n]的数组中。 以1*m 个数字的图像为例,先统计图像中每行每列有效像素点分别存入grayw[]和grayh[]中,然后逐行逐列扫描图像,通过W[].Left 和W[].Right,H[].Up 和H[].Down 分

别标记每个数字的左右上下位置可将数值分离。 

c) 模板的匹配与识别 

 

android 通用印刷体识别 印刷体数字识别_大作业

依次识别每一位数字。将每一位数字的像素信息存入50*50 的名为t 二维数组中,有效像素点定为1,无效像素点定义0。将得到的分离后的数字的二维数组t 与各个模板进行匹配。由于模板和待检测数字中的有效像素点在数组中均表示为1,可通过对应点相加之后对2 取余数再相加得到结果sum,比较待检测图像与十个模板得到的sum 的值,sum 最小的表示待检测数字与其图像重合点最多,即认为待检测数字为该数字。 

 

android 通用印刷体识别 印刷体数字识别_大作业_02

三、算法步骤 

Step1:模板库的建立 

Step2:待检测图像中的数字分离 

Step3:模板的匹配与识别 

四、程序说明 

char * ImageNumReg( int ContW,int ContH)
{
for( i=1; i<=ContH; i++)
{
for( j=1; j<=ContW; j++)
        {
         for( k=0; k<q; k++)
         {
         for( m=0; m<q; m++)
         {
         t[k][m] = 0;
         }
         }
 
for( ii=H[i].Up; ii<H[i].Down; ii++) 
{
for( jj=W[j].Left; jj<W[j].Right; jj++)
{
if(*(bmpimage.imgbuf+ii*bmpimage.infohead.biWidth+jj) < 50)
                        t[ii-H[i].Up][jj-W[j].Left] = 1;
                    else
                        t[ii-H[i].Up][jj-W[j].Left] = 0;
}
}
            for ( k=0; k<10; k++)
            {
             sum[k] = 0;
            }
for( k=0; k<q; k++)
{
for( m=0; m<q; m++)
{
sum[0] += ( a0[k][m]+t[k][m])%2;
sum[1] += ( a1[k][m]+t[k][m])%2;
sum[2] += ( a2[k][m]+t[k][m])%2;
sum[3] += ( a3[k][m]+t[k][m])%2;
sum[4] += ( a4[k][m]+t[k][m])%2;
sum[5] += ( a5[k][m]+t[k][m])%2;
sum[6] += ( a6[k][m]+t[k][m])%2;
sum[7] += ( a7[k][m]+t[k][m])%2;
sum[8] += ( a8[k][m]+t[k][m])%2;
sum[9] += ( a9[k][m]+t[k][m])%2;
}
}
for( k=0; k<9; k++)
{
if ( sum[k]>sum[k+1]) 
                    result[(i-1)*ContW+j-1] = k+1;
else 
                    sum[k+1] = sum[k];
}
}
}
return result;
}