基于特征点标识法在OCR上的应用开发
吕威 学号:071210119
<此论文 版权所有:吕威,拒绝转载,只作为技术交流>
摘要:本文主要针对特定字体的汉字识别与研究,阐述了基于特征点标示法在具体汉字识别中的开发和设计。
关键词:汉字识别。
Abstract: This paper mainly focuses on chinese recognition and research of specific font, describing the scientific development and designing of labelling method baseed on characteristic point.
Keywords: chinese recognition
OCR识别技术是根据一定的图像特征进行的,特征选择和提取的基本任务为从众多特征中找到最有效的特征,汉字的识别有很多方法提取各种特征,如统计决策法,句法结构法等,提取不同的特征使建立的特征字典的模板的不同。本文所讨论的建立特征字典的方法是类似于统计决策法中的汉字特征点的一种更简单的思路:特征点标示法来建立特征字典,论文后面我们将给出他们的区别。
1.一个简单的应用
算法思想来源于对识别象棋棋盘的的思索。关于特征点标识法的一个小简单的应用:QQ新中国象棋自动下棋程序,象棋自动下棋程序的关键思路在于识别棋盘,下面我们将用基于特征点标识的识别方法进行讨论。
1.1我为特征点标识下的定义是:我们可以对汉字提取出一个或多个黑点(称汉字中填充汉字的为黑点),而此组黑点在其他的有待识别的汉字中为非黑点或不全为黑点,那么我们就称这几个特征点为此汉字的标识特征点(或关键点),那么用这几个特征点即可标识此汉字。
1.2象棋棋盘特征点提取的过程:
(1)先截屏PrintScreen,保存屏幕到bmp;
(2)用Photoshop截出每个棋子(52px*52px);
(3)写程序各提取出红字的标识特征点和黑子的标识特征点(红炮比较特殊,颜色与其它不同可单独判断)(这里每个字只提一个标识特征点即可)
1.3象棋棋盘识别的过程(以下坐标为以屏幕坐上角为原点,单位:px):
(1)程序对含棋盘的屏幕截屏;
(2)用Photoshop找到棋盘开始点(268,84),每行和每列宽:57,黑子颜色为RGB(26,26,26),普通红字颜色为RGB(172,32,0),红炮为RGB(173,2,0),
(3)用上述数据建立棋盘,输出给象棋算法运算,然后控制鼠标走棋即可。
以下为取图判断的代码
void CXQWLIGHTDlg::QuTuPanDuan()
{
int x, y;
int akeypoint[14][2]= //找到的标识特征点(已转换到以棋子的中心为原点的坐标)
{
{-14,8 }, //黑将RGB(26,26,26)
{-16,-3 }, //黑士RGB(26,26,26)
{15,9 }, //黑象RGB(26,26,26)
{0,-12 }, //黑马RGB(26,26,26)
{-17,7 }, //黑车RGB(26,26,26)
{-17,4 }, //黑炮RGB(26,26,26)
{-16,2 }, //黑卒RGB(26,26,26)
{-14,-9 }, //红帅
{-15,-8 }, //红仕
{-16,-5 }, //红相
{-14,8 }, //红马
{14,5 }, //红车
{-14,-9 }, //红炮 12
{-16,3 }, //红兵
};
CDC dc; //截屏,保存到memDC建立的数据缓冲区
dc.CreateDC("DISPLAY",NULL,NULL,NULL);
CBitmap bm;
int Width=GetSystemMetrics(SM_CXSCREEN);
int Height=GetSystemMetrics(SM_CYSCREEN);
bm.CreateCompatibleBitmap(&dc,Width,Height);
CDC tdc;
tdc.CreateCompatibleDC(&dc);
CBitmap*pOld=tdc.SelectObject(&bm);
tdc.BitBlt(0,0,Width,Height,&dc,0,0,SRCCOPY);
tdc.SelectObject(pOld);
BITMAP btm;
bm.GetBitmap(&btm);
DWORD size=btm.bmWidthBytes*btm.bmHeight;
LPSTR lpData=(LPSTR)GlobalAlloc(GPTR,size);
CDC memDC;
memDC.CreateCompatibleDC(&dc);
SelectObject(memDC,bm); ///截屏到此
for(y=84; y<603; y+=57)//开始识别,棋盘开始点(268,84),每行列宽:57
{
for(x=268; x<729; x+=57)
{
//对每一个xy点识别以此点为中心点是否含有棋子,并识别此棋子
int i,flag=0; // flag标示棋子是否已找到,1表示不用再找了
for(i=0;i<7;i++) //识别红子
if(flag==0&& memDC.GetPixel(x+akeypoint[i][0],y+akeypoint[i][1])==RGB(26,26,26)
)
{ //Init_i, Init_j用作棋盘的建立
InitChessBoard[Init_i][Init_j++]=i+16; //存储棋子
if(Init_j>=9) {Init_i++;Init_j=0;} //请看棋盘的结构
flag=1;
}
for(i=7;i<14;i++) //识别黑子
if( flag==0 &&
( memDC.GetPixel(x+akeypoint[i][0],y+akeypoint[i][1])==RGB(172,32,0) ||
( i==12 &&
memDC.GetPixel(x+akeypoint[i][0],y+akeypoint[i][1])==RGB(173,2,0) )//红炮
)