初学VC++和Windows编程,有很多不懂,希望能请教各位。以下为最近学习内容中涉及的部分代码,从网上看到的,先感谢下资源分享者。
想问这种字符识别的算法思想是怎样的,想看下理论基础方便学习。另外作为车牌上的文字,该程序只给出部分省份字符模板特征值,其他文字的怎样求得,或者是有完整模板的,是什么样的?另外这个程序用到了OpenCV。
希望各位能给些意见,或者相关方面的指导,先谢谢了。以下为// 车牌字符模板特征值
const int Num_Templete[TEMPLETENUM][CHARACTER]=
{
  {16,19,10,12,10,10,15,18,110,3,2,2,3,3,3},     //0
  {9,11,10,10,10,10,9,10,79,2,2,2,0,2,12},       //1
  {18,19,3,18,10,10,23,22,123,4,2,2,7,6,8},      //2
  {19,21,11,14,4,20,18,22,129,2,2,4,6,6,7},      //3
  {2,18,11,22,20,21,11,18,123,2,4,2,6,7,5},      //4
  {23,19,20,12,9,20,18,22,143,2,4,4,6,6,6},      //5
  {6,13,17,8,15,20,18,20,117,2,2,4,5,7,6},       //6
  {21,21,0,20,8,12,9,11,102,2,2,2,2,8,15},       //7
  {17,18,18,19,14,20,17,20,143,4,2,4,6,6,6},     //8
  {16,18,15,21,7,19,13,7,116,3,2,2,6,6,5},       //9
  {10,10,16,16,20,20,18,19,129,2,4,2,8,3,6},     //A
  {24,20,20,19,22,22,24,20,171,4,8,4,6,6,6},     //B
  {18,19,20,4,20,8,17,21,127,3,2,4,4,4,4},       //C
  {23,19,11,20,12,20,22,21,148,3,3,3,4,4,4},     //D
  {23,19,21,9,22,8,23,23,148,2,2,2,6,6,6},       //E
  {25,17,20,9,22,8,19,0,120,2,2,2,4,4,4},        //F
  {17,18,22,14,12,24,18,21,146,4,7,4,4,6,6},     //G
  {14,20,18,22,17,22,16,20,149,4,1,4,2,2,2},     //H
  {0,17,0,20,3,20,18,22,100,2,2,4,2,2,2},        //J
  {19,20,26,10,20,20,20,22,157,4,4,4,3,5,11},    //K
  {20,0,20,0,20,0,25,20,105,2,2,2,2,2,2},        //L
  {20,10,27,17,20,10,22,14,140,1,3,3,4,1,5},     //M
  {21,12,25,17,26,12,18,18,149,3,5,3,5,5,6},     //N 
  {23,19,18,20,21,8,22,0,131,3,3,2,4,4,4},       //P
  {18,19,20,10,26,15,18,21,147,3,3,4,5,7,5},     //Q
  {26,19,21,18,21,17,20,21,163,4,3,4,4,6,5},     //R
  {18,18,18,10,8,17,17,22,128,4,3,4,6,6,6},      //S
  {22,18,10,10,10,10,10,10,100,2,2,2,33,2,2},    //T
  {18,12,20,10,20,10,19,21,130,3,3,3,2,2,2},     //U
  {20,19,20,20,15,14,9,10,127,4,4,2,9,1,8},      //V
  {21,25,26,28,16,16,21,19,172,6,2,4,13,0,7},    //W
  {21,21,13,13,12,11,22,21,134,4,2,4,8,0,10},    //X
  {21,20,10,11,10,10,10,11,103,3,2,2,5,2,6},     //Y
  {21,23,5,15,15,5,24,20,128,2,2,2,8,8,7},       //Z
  {13,14,10,10,10,10,13,13,93,2,2,2,29,2,29},    //I
  {20,20,13,20,19,12,17,20,141,3,3,4,4,4,4},     //O          //36
  {14,15,17,17,16,10,25,24,138,0,2,4,12,8,9},    //云        //37
  {17,20,17,12,33,28,23,20,170,3,4,7,13,6,4},    //苏
  {21,21,23,24,24,25,31,27,196,0,9,6,8,6,7},     //京
  {19,27,20,34,19,36,24,37,216,4,4,7,13,28,3},   //湘
  {17,14,23,27,36,40,26,27,210,4,13,4,16,14,14}, //鲁
  {24,24,32,38,34,32,17,22,223,9,6,10,11,12,9}, // 粤
  {22,20,33,37,25,24,24,25,210,13,3,6,12,8,7}     //蒙
};以下为字符识别部分
int CMyDialog::CodeRecognize(IplImage *imgTest, int num, int char_num)
{
if (imgTest==NULL){ return 0;}

int i=0,j=0,k=0,t=0;//循环变量
int  char_start=0,char_end=0;//*PlateCode[TEMPLETENUM] 车牌字符里字母、数字、汉字起始位置
    int num_t[CHARACTER ]={0};


 switch(num)//这里这样分 可以提高效率,并且提高了识别率
 {
    case 0:  char_start =0;         // 数字
                  char_end  = 9;
                   break;
    case 1:  char_start =10;        // 英文
                  char_end  = 35;
                   break;
    case 2:  char_start =0;       // 英文和数字
                  char_end  = 35;
                   break;  
    case 3:  char_start =36;       // 中文
                  char_end  = TEMPLETENUM-1;
                   break;
     default: break;              
 }  // 提取前8个特征  前8个特征 可以说是固定位置的值  固定算法
for(k=0; k<8; k++)

    for(j=int(k/2)*10; j<int(k/2+1)*10; j++)
{
for(i=(k%2)*10;i<(k%2+1)*10;i++)
{
   num_t[k]+=CV_IMAGE_ELEM(imgTest,uchar,j,i)/255 ;
}
}
  num_t[8]+= num_t[k];  // 第9个特征 前8个特征的和作为第9个特征值
}
  
for(i=0;i<20;i++)  //以下特征也是 固定算法得到的 
num_t[9]+=CV_IMAGE_ELEM(imgTest,uchar,10,i)/255 ;
for(i=0;i<20;i++)
    num_t[10]+=CV_IMAGE_ELEM(imgTest,uchar,20,i)/255 ;
for(i=0;i<20;i++)
    num_t[11]+=CV_IMAGE_ELEM(imgTest,uchar,30,i)/255 ;
  
    for(j=0;j<40;j++)
num_t[12]+=CV_IMAGE_ELEM(imgTest,uchar,j,7)/255;
for(j=0;j<40;j++)
num_t[13]+=CV_IMAGE_ELEM(imgTest,uchar,j,10)/255 ;
for(j=0;j<40;j++)
num_t[14]+=CV_IMAGE_ELEM(imgTest,uchar,j,13)/255 ; int num_tt[CHARACTER]={0};
int matchnum=0;  //可以说是 匹配度或 相似度
int matchnum_max=0;  
int matchcode = 0;         // 匹配号
//int matchtempnum[10]={0}; j=0; for(k=char_start;k<=char_end;k++)
//for(k=40;k<42;k++)
{
matchnum=0;
  
for(i=0;i<8;i++) //区域的匹配
{
  // num_tt[i]= abs(num_t[i]-num[k][i]);   
if (abs(num_t[i]-Num_Templete[k][i])<=2)//与模板里的相应值进行匹配
         matchnum++;//两者相减,如果绝对值小于2,标记匹配成功一次
}

   if(Num_Templete[k][i]-abs(num_t[i])<=8)//对第9个特征进行匹配 
      matchnum+=2;
       for(i=9;i<CHARACTER;i++)  // 横竖的匹配  
{
   if (Num_Templete[k][i]>=5)  //特征值 大于5 
   {
    if(abs(num_t[i]-Num_Templete[k][i])<=1)
    matchnum+=2;
   }
       else if( num_t[i]==Num_Templete[k][i])
   { 
        matchnum+=2;
   }
}
if(matchnum>matchnum_max)
        {
           matchnum_max=matchnum;  //保留最大的 匹配 
           matchcode= k;  //记录 识别的字符的 索引 
           //matchtempnum[j]=matchnum_min
        }
}
//识别输出  存放输出结果
G_PlateChar[char_num]=PlateCode[matchcode]; //保存下该字符
}