初学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]; //保存下该字符
}
想问这种字符识别的算法思想是怎样的,想看下理论基础方便学习。另外作为车牌上的文字,该程序只给出部分省份字符模板特征值,其他文字的怎样求得,或者是有完整模板的,是什么样的?另外这个程序用到了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]; //保存下该字符
}
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货