识别简单的数字,字母的手写识别框架
2013年10月01日
⁄ 综合
⁄ 共 20980字 ⁄ 字号
小 中 大
-
-
-
- #include "stdafx.h"
- #include "pattern.h"
- #include "patternDlg.h"
- #include "Afxwin.h"
- #include "Afxdlgs.h"
- #include "winuser.h"
- #include "Store.h"
- #include <STDIO.H>
-
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- #include<WINDOWS.H>
- #include<MATH.H>
-
- #define Startx 30
- #define Starty 190
- #define wid 192
- #define lon 192
- #define yu 3 //2 area
- #define yu1 5 //dou dong
-
- #define yu2 4
- int num,Time;
-
- int xmax,ymax,xmin,ymin;
-
-
-
- struct
- {
- int x;
- int y;
- }store[15][300];
-
-
- struct
- {
- int x;
- int y;
- }storeback[15][300];
-
- struct
- {
- int total;
- char zifu[2];
- int dian[15];
- struct{
- int relate;
- int region;
- int arc;
- }detail[15][20];
- }tez[2002];
-
- struct
- {
- int total;
- int dian[15];
- struct
- {
- int relate;
- int region;
- int arc;
- }detail[15][20];
- }test;
-
- int queue[50];
- int queue1[40];
- int zong;
-
-
-
-
- class CAboutDlg : public CDialog
- {
- public:
- CAboutDlg();
-
-
-
- enum { IDD = IDD_ABOUTBOX };
-
-
-
-
- protected:
- virtual void DoDataExchange(CDataExchange* pDX);
-
-
-
- protected:
-
-
- DECLARE_MESSAGE_MAP()
- };
-
- CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
- {
-
-
- }
-
- void CAboutDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
-
-
- }
-
- BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
-
-
-
- END_MESSAGE_MAP()
-
-
-
-
- CPatternDlg::CPatternDlg(CWnd* pParent )
- : CDialog(CPatternDlg::IDD, pParent)
- {
-
-
-
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
- }
-
- void CPatternDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
-
- DDX_Control(pDX, IDC_EDIT2, m_edit2);
- DDX_Control(pDX, IDC_EDIT1, m_edit1);
- DDX_Control(pDX, IDC_BUTTON4, m_escape);
- DDX_Control(pDX, IDC_BUTTON3, m_clear);
- DDX_Control(pDX, IDC_BUTTON1, m_recog);
- DDX_Control(pDX, IDC_BUTTON2, m_study);
-
- }
-
- BEGIN_MESSAGE_MAP(CPatternDlg, CDialog)
-
- ON_WM_SYSCOMMAND()
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- ON_BN_CLICKED(IDC_BUTTON4, OnEsp)
- ON_BN_CLICKED(IDC_BUTTON1, OnRecog)
- ON_WM_MOUSEMOVE()
- ON_BN_CLICKED(IDC_BUTTON3, OnClear)
- ON_BN_CLICKED(IDC_BUTTON2, OnStudy)
- ON_WM_LBUTTONUP()
- ON_WM_LBUTTONDOWN()
- ON_COMMAND(ID_EXIT_MENU, OnExitMenu)
- ON_COMMAND(ID_ABOUT_MENU, OnAboutMenu)
- ON_COMMAND(ID_SAVE_MENU, OnSaveMenu1)
- ON_COMMAND(ID_OPEN_MENU, OnOpenMenu)
-
- END_MESSAGE_MAP()
-
-
-
-
- BOOL CPatternDlg::OnInitDialog()
- {
- CFile cf;
-
- CDialog::OnInitDialog();
-
- mouseDown=0;
-
- int i,j,k;
-
-
- for(i=0;i<15;i++)
- {
- for(j=0;j<300;j++)
- {
- store[i][j].x=-1;
- store[i][j].y=-1;
- }
- }
-
- for(i=0;i<15;i++)
- {
- for(j=0;j<300;j++)
- {
- storeback[i][j].x=-1;
- storeback[i][j].y=-1;
- }
- }
-
- for(i=0;i<10;i++)
- {
- tez[i].total=-1;
-
- for(j=0;j<15;j++)
- tez[i].dian[j]=-1;
-
- for(j=0;j<15;j++)
- {
- for(k=0;k<20;k++)
- {
- tez[i].detail[j][k].relate=0;
- tez[i].detail[j][k].arc=0;
- tez[i].detail[j][k].region=0;
- }
- }
- }
-
- Time=0;
- num=0;
- zong=-1;
- xmax=0;
- ymax=0;
- xmin=31;
- ymin=31;
-
- for(i=0;i<50;i++)
- queue[i]=-1;
- for(i=0;i<40;i++)
- queue1[i]=-1;
-
- test.total=-1;
- for(j=0;j<15;j++)
- test.dian[j]=-1;
-
- for(j=0;j<15;j++)
- {
- for(k=0;k<20;k++)
- {
- test.detail[j][k].relate=0;
- test.detail[j][k].arc=0;
- test.detail[j][k].region=0;
- }
- }
-
-
-
- ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
- ASSERT(IDM_ABOUTBOX < 0xF000);
-
- CMenu* pSysMenu = GetSystemMenu(FALSE);
- if (pSysMenu != NULL)
- {
- CString strAboutMenu;
- strAboutMenu.LoadString(IDS_ABOUTBOX);
- if (!strAboutMenu.IsEmpty())
- {
- pSysMenu->AppendMenu(MF_SEPARATOR);
- pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
- }
- }
-
-
-
- SetIcon(m_hIcon, TRUE);
- SetIcon(m_hIcon, FALSE);
-
-
- if(cf.Open("mydata.dat",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite)==NULL){
- AfxMessageBox("打开文件失败,/n您最好退出程序");}
-
- return TRUE;
- }
-
- void CPatternDlg::OnSysCommand(UINT nID, LPARAM lParam)
- {
- if ((nID & 0xFFF0) == IDM_ABOUTBOX)
- {
- CAboutDlg dlgAbout;
- dlgAbout.DoModal();
- }
- else
- {
- CDialog::OnSysCommand(nID, lParam);
- }
- }
-
-
-
-
-
- void CPatternDlg::OnPaint()
- {
- CPaintDC dc(this);
- HBRUSH hB;
- hB=CreateSolidBrush(RGB(255,255,255));
- SelectObject(dc,hB);
- Rectangle(dc,Startx,Starty,Startx+wid-1,Starty+lon-1);
- DeleteObject(hB);
-
- if (IsIconic())
- {
-
- SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
-
-
- int cxIcon = GetSystemMetrics(SM_CXICON);
- int cyIcon = GetSystemMetrics(SM_CYICON);
- CRect rect;
- GetClientRect(&rect);
- int x = (rect.Width() - cxIcon + 1) / 2;
- int y = (rect.Height() - cyIcon + 1) / 2;
-
-
- dc.DrawIcon(x, y, m_hIcon);
- }
- else
- {
- CDialog::OnPaint();
- }
- }
-
-
-
- HCURSOR CPatternDlg::OnQueryDragIcon()
- {
- return (HCURSOR) m_hIcon;
- }
-
- void CPatternDlg::OnEsp()
- {
- OnOK();
- }
-
-
- void CPatternDlg::OnRecog()
- {
- int j1,k1,m1,n1,x,y,xmod,ymod;
- int flagok2=0;
- char s[20];
- DealData();
-
-
- for(j1=0;j1<=zong&&test.total>=0&&flagok2==0;j1++)
- {
- if(tez[j1].total==test.total)
- {
- for(k1=0;k1<=test.total;k1++)
- {
- if(test.dian[k1]!=tez[j1].dian[k1])
- break;
- }
-
- if(k1>test.total)
-
- {
- for(m1=0;m1<=test.total;m1++)
- {
- for(n1=0;n1<=test.dian[m1];n1++)
- {
- xmod=2*(tez[j1].detail[m1][n1].region % 8);
- ymod=2*((int)tez[j1].detail[m1][n1].region/8);
- x=test.detail[m1][n1].region % 16;
- y=(int)test.detail[m1][n1].region/16;
-
- if(( test.detail[m1][n1].relate!=tez[j1].detail[m1][n1].relate
- &&(test.detail[m1][n1].relate-10*(int)(test.detail[m1][n1].relate/10))!=tez[j1].detail[m1][n1].relate
- &&(int)(test.detail[m1][n1].relate/10)!=tez[j1].detail[m1][n1].relate)
- ||((tez[j1].detail[m1][n1].arc!=test.detail[m1][n1].arc)&&(test.total<4)&&(test.dian[m1]<4))
- ||((x<XMOD-3||X>xmod+3)||(y<YMOD-3||Y>ymod+3)))
- break;
- }
- if(n1<=test.dian[m1])
- break;
- }
- if(m1>test.total)
- {
- flagok2=1;
- sprintf(s,"输入正确,可识别,为:%s, 在字库%d个",tez[j1].zifu,j1);
- AfxMessageBox(s);
- m_edit1.ReplaceSel(tez[j1].zifu);
- OnClear();
- }
- }
- }
- }
-
- if(flagok2==0)
- {
- AfxMessageBox("字库不足或输入不规范,无法识别,请学习");
- OnRecogch();
- }
- }
-
-
- void CPatternDlg::OnStudy()
- {
- int j1,k1,m1,n1,k,m,xmod,ymod,x,y;
- CString z1;
- int i,j;
- int flagok1=0;
- char s[30];
- Inputdialog inputdlg;
-
-
- DealData();
-
- if(test.total==-1)
- {
- AfxMessageBox("没有笔迹输入,/n请重示");
- }
-
- for(j1=0;j1<=zong&&test.total!=-1;j1++)
- {
- if(flagok1==1)
- break;
-
- if(tez[j1].total==test.total&&flagok1==0)
- {
- for(k1=0;k1<=test.total;k1++)
- {
- if(test.dian[k1]!=tez[j1].dian[k1])
- break;
- }
-
- if(k1>test.total)
- {
- for(m1=0;m1<=test.total;m1++)
- {
- for(n1=0;n1<=test.dian[m1];n1++)
- {
- if(( test.detail[m1][n1].relate!=tez[j1].detail[m1][n1].relate
- &&(test.detail[m1][n1].relate % 10)!=tez[j1].detail[m1][n1].relate
- &&((int)(test.detail[m1][n1].relate/10))!=tez[j1].detail[m1][n1].relate)
- ||(tez[j1].detail[m1][n1].arc!=test.detail[m1][n1].arc))
- break;
- xmod=2*(tez[j1].detail[m1][n1].region % 8);
- ymod=2*((int)tez[j1].detail[m1][n1].region/8);
- x=test.detail[m1][n1].region % 16;
- y=(int)test.detail[m1][n1].region/16;
- if((x<XMOD-1||X>xmod+1)||(y<YMOD-1||Y>ymod+1))
- break;
- }
- if(n1<=test.dian[m1])
- break;
- }
-
- if(m1>test.total&&k1>test.total)
- {
- flagok1=1;
-
- sprintf(s,"您输入的是:%s,数据已有",tez[j1].zifu);
- AfxMessageBox(s);
- m_edit1.ReplaceSel(tez[j1].zifu);
- OnClear();
- }
- }
- }
- }
-
- if(flagok1==0&&test.total>=0&&inputdlg.DoModal()==IDOK)
- {
- if(inputdlg.m_input1!=inputdlg.m_input2
- ||inputdlg.m_input1==""||inputdlg.m_input1==" ")
- {
- AfxMessageBox("您的输入有误(不等或空格),/n请重新输入");
- for(i=0;i<50;i++)
- queue[i]=-1;
- for(i=0;i<40;i++)
- queue1[i]=-1;
-
- test.total=-1;
- for(j=0;j<15;j++)
- test.dian[j]=-1;
-
- for(j=0;j<15;j++)
- {
- for(k=0;k<20;k++)
- {
- test.detail[j][k].relate=0;
- test.detail[j][k].region=0;
- }
- }
- }
- else
- {
- zong++;
- sprintf(tez[zong].zifu,"%s",inputdlg.m_input1);
- tez[zong].total=test.total;
-
- for(i=0;i<=test.total;i++)
- {
- tez[zong].dian[i]=test.dian[i];
- for(j=0;j<=test.dian[i];j++)
- {
- tez[zong].detail[i][j].relate=(test.detail[i][j].relate % 10);
- tez[zong].detail[i][j].arc=test.detail[i][j].arc;
-
- x=(int)(test.detail[i][j].region % 16)/2;
- y=(int)(test.detail[i][j].region/16)/2;
- tez[zong].detail[i][j].region=8*y+x;
- }
- }
- OnSaveMenu();
-
- if(zong>=2000)
- AfxMessageBox("版本太低,容量受限,Sorry!");
-
- m_edit1.ReplaceSel(inputdlg.m_input1);
- OnClear();
- }
- }
- }
-
- void CPatternDlg::OnLButtonDown(UINT nFlags, CPoint point)
- {
- mouseDown=1;
- CWnd::OnLButtonDown(nFlags, point);
- }
-
-
- void CPatternDlg::OnLButtonUp(UINT nFlags, CPoint point)
- {
- mouseDown=0;
-
- if(store[num][Time-1].x>=0&&Time>0)
- {
- num++;
- Time=0;
- }
- if(num>=14)
- {
- AfxMessageBox("写入有误(笔划太多)",NULL,NULL);
- OnClear();
- }
-
- CWnd::OnLButtonUp(nFlags, point);
- }
-
-
- void CPatternDlg::OnMouseMove(UINT nFlags, CPoint point)
- {
-
- int x,y;
- CBrush Brush (RGB (0, 0 , 255) );
- CBrush* pOldBrush;
- CDC *pDC=GetDC();
- CRgn Rgn;
- Rgn.CreateRectRgn(Startx,Starty,Startx+wid-1,Starty+lon-1);
- pDC->SelectClipRgn(&Rgn);
-
- if((point.x>=Startx)&&(point.x<STARTX+WID)&&(POINT.Y>=Starty)
- &&(point.y<STARTY+LON)) m_HCross="AfxGetApp()-" m_HCross; HCURSOR {>LoadStandardCursor(IDC_CROSS);
- SetCursor(m_HCross);
- }
-
- if((mouseDown==1)&&(point.x>=Startx)&&(point.x<STARTX+WID) &&(point.y>=Starty)&&(point.y<STARTY+LON)) { pOldBrush="pDC-" CBrush* . context device the into brush Select>SelectObject (&Brush);
- pDC->Ellipse(point.x-4,point.y-4,point.x+4,point.y+4);
- pDC->SelectObject (pOldBrush );
- x=(int)(point.x-Startx)*32/wid;
- y= (int)(point.y-Starty)*32/lon;
-
- if(Time==0)
- {
- store[num][Time].x=x;
- store[num][Time].y=y;
- Time++;
- if(y>ymax)
- ymax=y;
- if(y<YMIN) if(x ymin="y;">xmax)
- xmax=x;
- if(x<XMIN) { if(y Time++; store[num][Time].y="y;" store[num][Time].x="x;" if(x!="store[num][Time-1].x||y!=store[num][Time-1].y)" else } xmin="x;">ymax)
- ymax=y;
- if(y<YMIN) if(x ymin="y;">xmax)
- xmax=x;
- if(x<XMIN) } xmin="x;" if(Time>=300)
- {
- AfxMessageBox("当前笔划写入有误(太多)",NULL,NULL);
- OnClear();
- }
- }
-
- ReleaseDC(pDC );
- DeleteObject(pOldBrush);
- DeleteObject(Rgn);
- DeleteObject(Brush);
-
- CWnd::OnMouseMove(nFlags, point);
- }
-
-
- void CPatternDlg::OnClear()
- {
- int i,j,k;
- CDC *pDC=GetDC();
- pDC-> PatBlt (Startx,Starty,wid,lon, PATCOPY );
- ReleaseDC(pDC );
- mouseDown=0;
-
- for(i=0;i<15;i++){
- for(j=0;j<300;j++)
- {
- store[i][j].x=-1;
- store[i][j].y=-1;
- }
- }
-
- for(i=0;i<15;i++){
- for(j=0;j<300;j++)
- {
- storeback[i][j].x=-1;
- storeback[i][j].y=-1;
- }
- }
-
- Time=0;
- num=0;
- xmax=0;
- ymax=0;
- xmin=32;
- ymin=32;
-
- for(i=0;i<50;i++)
- queue[i]=-1;
- for(i=0;i<40;i++)
- queue1[i]=-1;
-
- test.total=-1;
- for(j=0;j<15;j++)
- test.dian[j]=-1;
- for(j=0;j<15;j++)
- {
- for(k=0;k<20;k++)
- {
- test.detail[j][k].relate=0;
- test.detail[j][k].arc=0;
- test.detail[j][k].region=0;
- }
- }
-
- return;
- }
-
-
- int CPatternDlg::Ridnoise(int j)
- {
- int i,k,ff;
- k=0;
- ff=test.total+1;
-
- queue1[0]=queue[0];
- for(i=1;i<J-1;I++) { else } if(abs(y1-y3) are="abs(x1-x3);" y3="store[kk][queue1[j]].y;" x3="store[kk][queue1[j]].x;" y1="store[kk][queue1[j-1]].y;" x1="store[kk][queue1[j-1]].x;" kk="test.total;" kk; int smax="0;ci=0;vct=0;" s; float x1,x2,y1,y2,x3,y3,t1,smax,ci,vct,are; j) CPatternDlg::Getarc(int 得到arc特征 k; return queue1[k]="queue[i];" k++; &&abs(store[ff][queue[j-1]].x-store[ff][queue1[k]].x)<2) abs(store[ff][queue[j-1]].y-store[ff][queue1[k]].y)<2 if( {;} &&(((store[ff][queue[i]].x-store[ff][queue1[k]].x)*(store[ff][queue[i]].x-store[ff][queue[i+1]].x))<0||abs(store[ff][queue[i]].x-store[ff][queue[i+1]].x)<yu2)) (abs(store[ff][queue[i]].y-store[ff][queue1[k]].y)<yu1+1+1 if ||abs(store[ff][queue[i]].y-store[ff][queue[i+1]].y)<yu2)) &&(((store[ff][queue[i]].y-store[ff][queue1[k]].y)*(store[ff][queue[i]].y-store[ff][queue[i+1]].y))<0 (abs(store[ff][queue[i]].x-store[ff][queue1[k]].x)<yu1+1+1>are)
- are=abs(y1-y3);
-
- for(t1=queue1[j-1]+1;t1<QUEUE1[J];T1++) { if(s s="(x1*y2+x2*y3+x3*y1-x1*y3-x2*y1-x3*y2)/are;" x2="store[kk][t1].x;" y2="store[kk][t1].y;">=yu||s<=-yu)
- {
- if(s*smax==0)
- {
- if(s>0)
- vct=1;
- else
- vct=-1;
- }
-
- if(s*smax<=0)
- {
- ci++;
- smax=s;
- }
-
- if(abs(smax)<ABS(S)) { } int smax="s;" float return if(j="=0)" test.detail[tat][j].arc="0;" test.detail[tat][j].relate="10;" test.detail[tat][j].region="16*l+m;" l="(int)((store[tat][queue1[j]].y-ymin)*16/(ymax-ymin+1));" m="(int)((store[tat][queue1[j]].x-xmin)*16/(xmax-xmin+1));" for(j="0;j<=k;j++)" points,初值为-1,定义此条值 test.dian[test.total]="k;//k+1" tat="test.total;//没有排序" 特征总条数加一 test.total++; value; i,j,m,l,tat; 此条共k+1个点 k) CPatternDlg::Save(int void 保存特征点 ci; ci="vct*ci;">0)
- {
- if((store[tat][queue1[j]].x-store[tat][queue1[j-1]].x)>5.67*abs(store[tat][queue1[j]].y-store[tat][queue1[j-1]].y))
- {
- test.detail[test.total][j].relate=1;
- test.detail[test.total][j].arc=Getarc(j);
- }
- else
- {
- if((store[tat][queue1[j]].x-store[tat][queue1[j-1]].x)<-5.67*abs(store[tat][queue1[j]].y-store[tat][queue1[j-1]].y))
- {
- test.detail[test.total][j].relate=9;
- test.detail[test.total][j].arc=Getarc(j);
- }
- else
- {
- if(5.67*abs(store[tat][queue1[j]].x-store[tat][queue1[j-1]].x)<(store[tat][queue1[j]].y-store[tat][queue1[j-1]].y))
- {
- test.detail[test.total][j].relate=7;
- test.detail[test.total][j].arc=Getarc(j);
- }
- else
- {
- if(-5.67*abs(store[tat][queue1[j]].x-store[tat][queue1[j-1]].x)>(store[tat][queue1[j]].y-store[tat][queue1[j-1]].y))
-