dipView.cpp
资源名称:vcc.rar [点击查看]
上传用户:cdscwht
上传日期:2022-07-27
资源大小:264k
文件大小:79k
源码类别:
图形/文字识别
开发平台:
Visual Basic
- // dipView.cpp : implementation of the CDipView class
- //
- #include "stdafx.h"
- #include "dip.h"
- #include "dipDoc.h"
- #include "dipView.h"
- #include "afxdlgs.h"
- #include "afxwin.h"
- #include "math.h"
- #include ".dipview.h"
- #include "stdlib.h"
- #include "malloc.h"
- #include "mainfrm.h"
- #include "charview.h"
- #include "recvchar.h"
- #include "training.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CDipView
- IMPLEMENT_DYNCREATE(CDipView, CView)
- BEGIN_MESSAGE_MAP(CDipView, CView)
- //{{AFX_MSG_MAP(CDipView)
- ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
- ON_WM_PAINT()
- ON_COMMAND(ID_FILE_SAVE, OnFileSave)
- ON_COMMAND(ID_reopen, Onreopen)
- ON_WM_MOUSEMOVE()
- ON_WM_CREATE()
- ON_COMMAND(ID_LINE, OnLine)
- ON_COMMAND(ID_F3, Onfse)
- ON_COMMAND(ID_F4, Onfz)
- ON_COMMAND(ID_MoHu, OnMoHu)
- ON_COMMAND(ID_ForHandle, OnForHandle)
- ON_COMMAND(ID_HSearch, OnHSearch)
- ON_COMMAND(ID_Banlance, OnBanlance)
- ON_COMMAND(ID_SubVertical, OnSubVertical)
- ON_COMMAND(ID_SubHorizontal, OnSubHorizontal)
- ON_COMMAND(ID_MidValue, OnMidValue)
- ON_COMMAND(ID_Average, OnAverage)
- ON_COMMAND(ID_Bool, OnBool)
- ON_COMMAND(ID_Choose, OnChoose)
- ON_COMMAND(ID_TRAINFROMVEHICLE, OnTrainfromvehicle)
- ON_COMMAND(ID_SAVESA, OnSave)
- ON_COMMAND(ID_READSA, OnLoad)
- ON_COMMAND(ID_CHANGE, OnChange)
- ON_COMMAND(ID_TRAIN, OnTrain)
- ON_COMMAND(ID_SAVEBP, OnSavebp)
- ON_COMMAND(ID_VSearch, OnVSearch)
- ON_COMMAND(ID_Locate, OnLocate)
- ON_COMMAND(ID_Sobel, OnSobel)
- ON_COMMAND(ID_VSplit, OnVSplit)
- ON_COMMAND(ID_CharacterRec, OnCharacterRecg)
- ON_COMMAND(ID_READBP, OnReadbp)
- //}}AFX_MSG_MAP
- // Standard printing commands
- ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CDipView construction/destruction
- CDipView::CDipView()
- //: Height(NULL)
- //, TopRow(NULL)
- //: Widths(NULL)
- //, Left(NULL)
- //: Rect_X(NULL)
- //, Rect_Y(NULL)
- //, Rect_W(NULL)
- //, Rect_H(NULL)
- //, Rect_Areas(0)
- {
- // TODO: add construction code here
- //初始化
- m_pMemDC=new CDC; //分配内存DC
- m_pBitmap=new CBitmap; //分配背景图像的空间
- IsNewFile=true;
- IsNewBitmap=true;
- m_pBmp=NULL;
- Height=new int[20];
- TopRow=new int[20];
- Widths=new int[30]; //Top' width
- Left=new int[30]; //Top' top col
- Rect_X=new int[50];
- Rect_Y=new int[50];
- Rect_W=new int[50];
- Rect_H=new int[50];
- Rect_Areas=0;
- cRects=new crect[10];
- CharacterNum=0;
- cDatas=new cData[10]; //实际大小由CharacterNum确定
- char_ConnectPos=NULL;
- num_ConnectPos=NULL;
- han_ConnectPos=NULL;
- }
- CDipView::~CDipView()
- {
- //释放内存
- delete m_pBitmap;
- delete m_pMemDC;
- }
- BOOL CDipView::PreCreateWindow(CREATESTRUCT& cs)
- {
- // TODO: Modify the Window class or styles here by modifying
- // the CREATESTRUCT cs
- return CView::PreCreateWindow(cs);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDipView drawing
- void CDipView::OnDraw(CDC* pDC)
- {
- CDipDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- // TODO: add draw code for native data here
- //如果已经读入一幅新的图像,则向CDC中写入新的图像信息
- if ((pDoc->ImgData!=NULL)&&IsNewFile)
- {
- //
- ChageStatuBar(&"正在打开文件 ");
- //
- int i,j,k;
- k=0;
- BYTE r,g,b;
- for(i=0;i<pDoc->ImgHeight;i++)
- for(j=0;j<pDoc->ImgWidth;j++)
- {
- //从调色板中得到r,g,b分量
- r=pDoc->palette[pDoc->ImgData[k]].rgbBlue;
- g=pDoc->palette[pDoc->ImgData[k]].rgbGreen;
- b=pDoc->palette[pDoc->ImgData[k]].rgbRed;
- pDC->SetPixel(j,i,(r<<16)|(g<<8)|b);
- k++;
- }
- IsNewFile=false; //写完后,将文件标志位置为假
- //恢复鼠标
- char * path =pDoc->FileName.GetBuffer(256) ;
- ChageStatuBar(path);
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDipView printing
- BOOL CDipView::OnPreparePrinting(CPrintInfo* pInfo)
- {
- // default preparation
- return DoPreparePrinting(pInfo);
- }
- void CDipView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
- {
- // TODO: add extra initialization before printing
- }
- void CDipView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
- {
- // TODO: add cleanup after printing
- }
- /////////////////////////////////////////////////////////////////////////////
- // CDipView diagnostics
- #ifdef _DEBUG
- void CDipView::AssertValid() const
- {
- CView::AssertValid();
- }
- //setpentext
- void CDipView::Dump(CDumpContext& dc) const
- {
- CView::Dump(dc);
- }
- CDipDoc* CDipView::GetDocument() // non-debug version is inline
- {
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDipDoc)));
- return (CDipDoc*)m_pDocument;
- }
- #endif //_DEBUG
- /////////////////////////////////////////////////////////////////////////////
- // CDipView message handlers
- //打开一个BMP文件
- void CDipView::OnFileOpen()
- {
- // TODO: Add your command handler code here
- CFileDialog mydlg(true);
- CString filename;
- mydlg.m_ofn.lpstrFilter="BMP files(*.bmp) *.bmp JPG files(*.jpg) *.jpg ";
- //显示文件对话框
- if (mydlg.DoModal()==IDOK)
- {
- filename=mydlg.GetPathName();
- //读入文件
- CDipDoc * myDoc;
- myDoc=GetDocument(); //enable you to call the number
- //function of CDocment
- myDoc->FileOpen(filename);
- //将文件标志位和图像标志位置为真
- IsNewFile=true;
- IsNewBitmap=true;
- //刷新屏幕
- myDoc->UpdateAllViews(NULL);
- }
- }
- void CDipView::OnPaint()
- {
- CPaintDC dc(this); // device context for painting
- // TODO: Add your message handler code here
- this->GetActiveWindow()->SetWindowText("数字图像处理程序");
- //设定从内存DC到屏幕DC的拷贝区域
- CRect rc(0,0,::GetSystemMetrics(SM_CXSCREEN),::GetSystemMetrics(SM_CYSCREEN));
- CBitmap * pOldBitmap=(CBitmap *)(m_pMemDC->SelectObject(m_pBitmap));
- if (IsNewBitmap)
- m_pMemDC->Rectangle(-1,-1,2000,2000); //新图,清除背景
- else
- m_pMemDC->SelectObject(mymap); //旧图,直接调用内存中的图像
- m_pMemDC->SelectClipRgn(NULL);
- OnDraw(m_pMemDC); //向内存DC中画图像
- //拷贝到屏幕DC中
- dc.BitBlt(rc.left,rc.top,rc.Width(),rc.Height(),m_pMemDC,rc.left,rc.top,SRCCOPY);
- if (IsNewBitmap)
- {
- //保存历史图像,已备下次显示
- mymap=m_pMemDC->GetCurrentBitmap();
- IsNewBitmap=false;
- }
- m_pMemDC->SelectObject(pOldBitmap);
- // m_wait=theapp->LoadCursor(IDC_ARROW);
- // SetCursor(m_wait);
- // Do not call CView::OnPaint() for painting messages
- }
- void CDipView::OnInitialUpdate()
- {
- CView::OnInitialUpdate();
- // ChageStatuBar(&"请打开一个BMP格式的位图文件");
- // TODO: Add your specialized code here and/or call the base class
- //初始化m_pMemDC和m_pBitmap
- if (m_pMemDC->GetSafeHdc()==NULL)
- {
- CClientDC dc(this);
- OnPrepareDC(&dc);
- //设定背景图像的大小
- CRect rc(0,0,::GetSystemMetrics(SM_CXSCREEN),::GetSystemMetrics(SM_CYSCREEN));
- m_pMemDC->CreateCompatibleDC(&dc);
- m_pBitmap->CreateCompatibleBitmap(&dc,rc.right,rc.bottom);
- }
- CDipDoc* pDoc=GetDocument();
- int i;
- for( i=0;i<pDoc->ImgWidth*pDoc->ImgHeight;i++)
- img[i]=pDoc->ImgData[i];
- }
- void CDipView::OnFileSave()
- {
- // TODO: Add your command handler code here
- CFileDialog mydlg(false);
- CString filename,promt;
- mydlg.m_ofn.lpstrFilter="BMP files(*.bmp) *.bmp ";
- //打开存储对话框
- if (mydlg.DoModal()==IDOK)
- {
- filename=mydlg.GetPathName();
- if(filename.Find(".bmp")<=0)
- filename=filename+".bmp";
- //存储图像
- CDipDoc* pDoc = GetDocument();
- pDoc->FileSave(filename);
- }
- }
- //重新显示原始图像
- void CDipView::Onreopen()
- {
- // TODO: Add your command handler code here
- CDipDoc* pDoc = GetDocument();
- pDoc->FileOpen();
- IsNewBitmap=true;
- IsNewFile=true;
- pDoc->UpdateAllViews(NULL);
- }
- void CDipView::OnMouseMove(UINT nFlags, CPoint point)
- {
- if (AfxGetApp() != NULL && AfxGetApp()->m_pMainWnd != NULL) {
- char buffer[256];
- CStatusBar* pStatus = (CStatusBar*)
- AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
- va_list argptr;
- pStatus->SetPaneInfo(2,2,SBPS_STRETCH ,7);
- CString x;
- x.Format(_T("%d"),point.x);
- CString y;
- y.Format(_T("%d"),point.y);
- CString zuobiao=" x= "+x + " , " + "y= " +y;
- char * fmt=zuobiao.GetBuffer(12);
- va_start(argptr, fmt);
- vsprintf(buffer, fmt, argptr);
- va_end(argptr);
- if (pStatus != NULL)
- {
- pStatus->SetPaneText(2, buffer);
- pStatus->UpdateWindow();
- }
- }
- // TODO: Add your message handler code here and/or call default
- CView::OnMouseMove(nFlags, point);
- }
- void CDipView::ChageStatuBar(char * fmt)
- {
- if (AfxGetApp() != NULL && AfxGetApp()->m_pMainWnd != NULL) {
- char buffer[256];
- CStatusBar* pStatus = (CStatusBar*)
- AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
- va_list argptr;
- va_start(argptr, fmt);
- vsprintf(buffer, fmt, argptr);
- va_end(argptr);
- if (pStatus != NULL) {
- pStatus->SetPaneText(0, buffer);
- pStatus->UpdateWindow();
- }
- }
- }
- //DEL BOOL CDipView::OnEraseBkgnd(CDC* pDC)
- //DEL {
- //DEL // TODO: Add your message handler code here and/or call default
- //DEL if (AfxGetApp() != NULL && AfxGetApp()->m_pMainWnd != NULL) {
- //DEL char buffer[256];
- //DEL CStatusBar* pStatus = (CStatusBar*)
- //DEL AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
- //DEL
- //DEL va_list argptr;
- //DEL // char * fmt =&" BMPBMPBMPBMP";
- //DEL //gai kuandu
- //DEL pStatus->SetPaneInfo(2,2,SBPS_STRETCH ,7);
- //DEL //itoa(point.x,,10)
- //DEL
- //DEL char * fmt="请打开文件";
- //DEL va_start(argptr, fmt);
- //DEL vsprintf(buffer, fmt, argptr);
- //DEL va_end(argptr);
- //DEL if (pStatus != NULL)
- //DEL {
- //DEL // pStatus
- //DEL pStatus->SetPaneText(2, buffer);
- //DEL pStatus->UpdateWindow();
- //DEL }
- //DEL }
- //DEL return CView::OnEraseBkgnd(pDC);
- //DEL }
- int CDipView::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CView::OnCreate(lpCreateStruct) == -1)
- return -1;
- OnLoad();
- char_bp.Initialize(3434);
- char_bp.CreateBP(13,60,26);
- num_bp.Initialize(3434);
- num_bp.CreateBP(13,60,10);
- char_num_bp.Initialize(3434);
- char_num_bp.CreateBP(13,60,36);
- // TODO: Add your specialized creation code here
- // ChageStatuBar(&"请打开一个BMP格式的位图文件");
- return 0;
- }
- void CDipView::OnLine()
- {
- // TODO: Add your command handler code here
- CDipDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- Mdlg dlg;
- dlg.DoModal();
- a=dlg.m_edit1;
- b=dlg.m_edit2;
- for(int i=0;i<pDoc->ImgWidth*pDoc->ImgHeight;i++)
- {
- pDoc->ImgData[i]=a*pDoc->ImgData[i]+b;
- if(pDoc->ImgData[i]>255) pDoc->ImgData[i]=255;
- if(pDoc->ImgData[i]<0) pDoc->ImgData[i]=0;
- }
- IsNewFile=true;
- IsNewBitmap=true;
- Invalidate();
- }
- void CDipView::Onfse()
- {
- // TODO: Add your command handler code here
- CDipDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- for(int i=0;i<pDoc->ImgWidth*pDoc->ImgHeight;i++)
- {
- //pDoc->ImgData[i]=a*pDoc->ImgData[i]+b;
- pDoc->ImgData[i]=255-pDoc->ImgData[i];
- //if(pDoc->ImgData[i]<0) pDoc->ImgData[i]=0;
- }
- IsNewFile=true;
- IsNewBitmap=true;
- Invalidate();
- }
- void CDipView::Onfz()
- {
- // TODO: Add your command handler code here
- CDipDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- BYTE * ImgData1=new BYTE[pDoc->ImgWidth*pDoc->ImgHeight];
- for(int i=0;i<pDoc->ImgWidth*pDoc->ImgHeight;i++)
- {
- //pDoc->ImgData[i]=a*pDoc->ImgData[i]+b;
- ImgData1[pDoc->ImgWidth*pDoc->ImgHeight-i]=pDoc->ImgData[i];
- //if(pDoc->ImgData[i]<0) pDoc->ImgData[i]=0;
- }
- for( i=0;i<pDoc->ImgWidth*pDoc->ImgHeight;i++)
- {
- //pDoc->ImgData[i]=a*pDoc->ImgData[i]+b;
- pDoc->ImgData[i]=ImgData1[i];
- //if(pDoc->ImgData[i]<0) pDoc->ImgData[i]=0;
- }
- IsNewFile=true;
- IsNewBitmap=true;
- Invalidate();
- }
- void CDipView::OnMoHu()
- {
- // TODO: Add your command handler code here
- CDipDoc* pDoc = GetDocument();
- int h=pDoc->ImgHeight;
- int w=pDoc->ImgWidth;
- BYTE * g=new BYTE[h*w];
- float temp;
- //标示图象的坐标
- int x,y;
- //标示算子的坐标
- int i,j;
- BYTE mb[3][3]={{-1,0,0},{0,0,0},{0,0,1}};
- for(x=1;x<h-1;x++)
- {
- for(y=1;y<w-1;y++)
- {
- temp=0;
- for(i=0;i<3;i++)
- {
- for(j=0;j<3;j++)
- {
- temp=temp+(float( mb[i][j])*( float (pDoc->ImgData[(x-1+i)*w+(y-1+j)])));
- }
- }
- g[x*w+y]=int(temp);
- }
- }
- for(x=1;x<h-1;x++)
- for(y=1;y<w-1;y++)
- pDoc->ImgData[x*w+y]=g[x*w+y];
- IsNewFile=true;
- IsNewBitmap=true;
- Invalidate();
- }
- void CDipView::OnForHandle()
- {
- // TODO: Add your command handler code here
- CDipDoc *p=GetDocument();
- BYTE *temp=new BYTE[p->ImgHeight*p->ImgWidth];
- int x,y;
- for(x=0;x<p->ImgHeight;x++)
- {
- for(y=0;y<p->ImgWidth;y++)
- {
- temp[(x*p->ImgWidth)+y]=p->ImgData[(x*p->ImgWidth)+y];
- }
- }
- long double total=0;
- float aver=0;
- for(x=0;x<p->ImgHeight;x++)
- {
- for(y=0;y<p->ImgWidth;y++)
- {
- total+=p->ImgData[x*p->ImgWidth+y];
- }
- }
- aver=(BYTE)(total/(float)(p->ImgHeight*p->ImgWidth));
- float delt;
- float sub=0;
- for(x=0;x<p->ImgHeight;x++)
- {
- for(y=0;y<p->ImgWidth;y++)
- {
- sub+=(p->ImgData[x*p->ImgWidth+y]-aver)*(p->ImgData[x*p->ImgWidth+y]-aver);
- }
- }
- delt=(float)(sqrt(sub/(float)(p->ImgHeight*p->ImgWidth)));
- BYTE judge;
- judge=(BYTE)(delt+aver);
- for(x=0;x<p->ImgHeight;x++)
- {
- for(y=0;y<p->ImgWidth;y++)
- {
- if(p->ImgData[(x*p->ImgWidth)+y]>=judge)
- {
- p->ImgData[(x*p->ImgWidth)+y]=255;
- }
- else
- {
- p->ImgData[(x*p->ImgWidth)+y]=0;
- }
- }
- }
- free(temp);
- IsNewBitmap=true;
- IsNewFile=true;
- p->UpdateAllViews(NULL);
- }
- void CDipView::OnHSearch()
- {
- // TODO: Add your command handler code here
- CDipDoc *pDoc=GetDocument();
- int width,height;
- width=pDoc->ImgWidth;
- height=pDoc->ImgHeight;
- BYTE *g=new BYTE[width*height];
- int *Count= new int[height];
- int *TempCount=new int[height];
- int *maxChanges=new int[10];
- int *Rows=new int[10];
- int H[20];
- int Top[20];
- for(int row=0;row<pDoc->ImgHeight;row++)
- {
- for(int col=0;col<pDoc->ImgWidth;col++)
- {
- g[row*width+col]=pDoc->ImgData[row*width+col];
- }
- }
- for(int c=0;c<height;c++)
- {
- Count[c]=0;
- TempCount[c]=0;
- }
- for(c=0;c<10;c++)
- {
- maxChanges[c]=0;
- Rows[c]=0;
- H[c]=0;
- Top[c]=1;
- }
- for(row=0;row<height;row++)
- {
- for(int col=0;col<width-1;col++)
- {
- if(pDoc->ImgData[row*width+col]!=pDoc->ImgData[row*width+col+1])
- Count[row]++;
- }
- TempCount[row]=Count[row];
- }
- /////////////////////////////////////Top 10 chage row
- for(int top=0;top<10;top++)
- {
- int Max=0;
- for(row=0;row<height;)
- {
- if(Max<TempCount[row])
- {
- Max=TempCount[row];
- }
- row=row+10 ;
- }
- maxChanges[top]=Max;
- int R=0;
- for(row=0;row<height;)
- {
- if(Max!=TempCount[row])
- {
- row=row+10;
- }
- else
- {
- R=row;
- break;
- }
- }
- Rows[top]=R;
- TempCount[R]=0;
- }
- for(top=0;top<10;top++)
- {
- for(int range=-10;range<10;range++)
- {
- if((0.7*Count[Rows[top]]<=Count[Rows[top]+range])&&(Count[Rows[top]+range]<=1.3*Count[Rows[top]]))
- {
- for(int col=0;col<width;col++)
- {
- g[(Rows[top]+range)*width+col]=255;
- }
- }
- }
- }
- for(row=0;row<height;row++)
- {
- for(int col=0;col<pDoc->ImgWidth;col++)
- {
- if(g[row*width+col]<255)
- {
- g[row*width+col]=0;
- }
- }
- }
- int Area=0; //标识区域的地点
- if(g[0*width+10]==255)
- {
- Area++;
- H[Area]++;
- Top[Area]=0;
- }
- for(row=1;row<height;row++)
- {
- if((g[row*width+10]==255) && (g[(row-1)*width+10]==0))
- {
- Area++;
- H[Area]++;
- Top[Area]=row;
- }
- else
- {
- if(g[row*width+10]==255&&g[(row-1)*width+10]==255)
- {
- H[Area]++;
- }
- }
- }
- for(int x=0;x<20;x++)
- {
- int h=H[x];
- if(h>20) //特定应用条件,拍摄所得车牌的区域高度、宽度均有一定的范围
- { //分析图象可得
- int r=0;
- int r0=0;
- r=Top[x];
- r0=Top[x]+h;
- if(r!=0&&r0!=height)
- {
- for(int col=0;col<width;col++)
- {
- pDoc->ImgData[r*width+col]=255;
- pDoc->ImgData[r0*width+col]=255;
- }
- }
- else
- {
- if(r==0)
- {
- r=5;
- for(int col=0;col<width;col++)
- {
- pDoc->ImgData[r*width+col]=255;
- pDoc->ImgData[r0*width+col]=255;
- }
- }
- else
- {
- if(r0==height)
- {
- r0=height-10;
- for(int col=0;col<width;col++)
- {
- pDoc->ImgData[r*width+col]=255;
- pDoc->ImgData[r0*width+col]=255;
- }
- }
- }
- }
- }
- }
- free(g);
- IsNewBitmap=true;
- IsNewFile=true;
- pDoc->UpdateAllViews(NULL);
- }
- void CDipView::OnBanlance()
- {
- // TODO: Add your command handler code here
- CDipDoc *pDoc=GetDocument();
- int width,height;
- width=pDoc->ImgWidth;
- height=pDoc->ImgHeight;
- float num=0;
- int row,col;
- int count[256];
- float s0[256];
- int s[256]; //256个灰度等级
- int x=0;
- int temp=0;
- for( x=0;x<256;x++)
- {
- count[x]=0;
- s0[x]=0.0;
- s[x]=0;
- }
- for(row=0;row<pDoc->ImgHeight;row++) //每个灰度等级象素个数
- {
- for(col=0;col<pDoc->ImgWidth;col++)
- {
- temp=pDoc->ImgData[row*width+col];
- count[temp]++;
- }
- }
- for(x=0;x<256;x++) //对应灰度等级概率
- {
- num=(float)width*height;
- s0[x]=(float)(count[x]/num);
- }
- for( x=1;x<256;x++) //概率累计,合并灰度等级
- {
- s0[x]+=s0[x-1];
- }
- for( x=0;x<256;x++) //映射
- {
- s[x]=(int)(s0[x]*255+0.5);
- }
- for(row=0;row<pDoc->ImgHeight;row++) //每个灰度等级象素个数
- {
- for(col=0;col<pDoc->ImgWidth;col++)
- {
- int reflect=0;
- temp=pDoc->ImgData[row*width+col];
- reflect=s[temp];
- pDoc->ImgData[row*width+col]=reflect;
- }
- }
- IsNewBitmap=true;
- IsNewFile=true;
- pDoc->UpdateAllViews(NULL);
- }
- void CDipView::OnSubVertical()
- {
- // TODO: Add your command handler code here
- CDipDoc *pDoc=GetDocument();
- int width,height;
- width=pDoc->ImgWidth;
- height=pDoc->ImgHeight;
- BYTE *g=new BYTE[width*height];
- int row,col,sub;
- for(row=0;row<height-1;row++)
- {
- for(col=0;col<width;col++)
- {
- sub=abs((pDoc->ImgData[row*width+col])-(pDoc->ImgData[(row+1)*width+col]));
- g[row*width+col]=sub;
- }
- }
- for(row=0;row<height;row++)
- {
- for(col=0;col<width-1;col++)
- {
- pDoc->ImgData[row*width+col]=g[row*width+col];
- }
- }
- free(g);
- IsNewBitmap=true;
- IsNewFile=true;
- pDoc->UpdateAllViews(NULL);
- }
- void CDipView::OnSubHorizontal()
- {
- // TODO: Add your command handler code here
- CDipDoc *pDoc=GetDocument();
- int width,height;
- width=pDoc->ImgWidth;
- height=pDoc->ImgHeight;
- BYTE *g=new BYTE[width*height];
- int row,col,sub;
- for(row=0;row<height;row++)
- {
- for(col=0;col<width-1;col++)
- {
- sub=abs((pDoc->ImgData[row*width+col])-(pDoc->ImgData[row*width+col+1]));
- if(sub<15)
- {
- g[row*width+col]=0;
- }
- else
- {
- if(sub>15)
- {
- g[row*width+col]=sub+50;
- }
- // else
- // g[row*width+col]=sub;
- }
- }
- }
- for(row=0;row<height;row++)
- {
- for(col=0;col<width-1;col++)
- {
- pDoc->ImgData[row*width+col]=g[row*width+col];
- if(col==0)
- {
- pDoc->ImgData[row*width+col]=0;
- }
- }
- }
- free(g);
- IsNewBitmap=true;
- IsNewFile=true;
- pDoc->UpdateAllViews(NULL);
- }
- void CDipView::OnMidValue()
- {
- // TODO: Add your command handler code here
- CDipDoc *pDoc=GetDocument();
- int width,height;
- width=pDoc->ImgWidth;
- height=pDoc->ImgHeight;
- BYTE *g=new BYTE[width*height];
- BYTE temp[25];
- int row,col;
- int u,v,a;
- for(row=2;row<height-2;row++)
- {
- for(col=2;col<width-2;col++)
- {
- for(u=0;u<5;u++)
- {
- for(v=0;v<5;v++)
- {
- temp[u*5+v]=pDoc->ImgData[(row-2+u)*width+(col-2)+v];
- }
- }
- for(u=0;u<25;u++)
- {
- for(v=u+1;v<25;v++)
- {
- if(temp[u]>temp[v])
- {
- a=temp[u];
- temp[u]=temp[v];
- temp[v]=a;
- }
- }
- }
- g[row*width+col]=temp[12];
- }
- }
- for(row=0;row<height;row++)
- {
- for(col=0;col<width-1;col++)
- {
- pDoc->ImgData[row*width+col]=g[row*width+col];
- }
- }
- IsNewBitmap=true;
- IsNewFile=true;
- pDoc->UpdateAllViews(NULL);
- }
- void CDipView::OnAverage()
- {
- // TODO: Add your command handler code here
- CDipDoc *pDoc=GetDocument();
- int width,height;
- width=pDoc->ImgWidth;
- height=pDoc->ImgHeight;
- BYTE *g=new BYTE[width*height];
- int row,col;
- BYTE s[3][3]={{1,1,1},{1,1,1},{1,1,1}};
- for(row=1;row<pDoc->ImgHeight-1;row++)
- {
- for(col=1;col<pDoc->ImgWidth-1;col++)
- {
- long sum=0;
- for(int i=0;i<3;i++)
- {
- for(int j=0;j<3;j++)
- {
- sum+=s[i][j]*pDoc->ImgData[((row-1+i)*pDoc->ImgWidth)+(col-1+j)];
- }
- }
- g[(row*pDoc->ImgWidth)+col]=(BYTE)(sum/9);
- }
- }
- for(row=0;row<height;row++)
- {
- for(col=0;col<width;col++)
- {
- pDoc->ImgData[row*width+col]=g[row*width+col];
- }
- }
- IsNewBitmap=true;
- IsNewFile=true;
- pDoc->UpdateAllViews(NULL);
- }
- void CDipView::OnBool()
- {
- // TODO: Add your command handler code here
- CDipDoc *pDoc=GetDocument();
- int width,height;
- width=pDoc->ImgWidth;
- height=pDoc->ImgHeight;
- int row,col;
- for(row=0;row<pDoc->ImgHeight;row++)
- {
- for(col=0;col<pDoc->ImgWidth;col++)
- {
- if(pDoc->ImgData[row*width+col]<255)
- {
- pDoc->ImgData[row*width+col]=0;
- }
- }
- }
- IsNewBitmap=true;
- IsNewFile=true;
- pDoc->UpdateAllViews(NULL);
- }
- void CDipView::OnVSearch()
- {
- // TODO: 在此添加命令处理程序代码
- CDipDoc *pDoc=GetDocument();
- int width,height;
- width=pDoc->ImgWidth;
- height=pDoc->ImgHeight;
- BYTE *g=new BYTE[width*height];
- int *Count= new int[width];
- int *TempCount=new int[width];
- int *maxChanges=new int[30];
- int *Cols=new int[30]; //maxChanges' col
- int *W=new int[30]; //Top' width
- int *left=new int[30]; //Top' top col
- for(int row=0;row<pDoc->ImgHeight;row++)
- {
- for(int col=0;col<pDoc->ImgWidth;col++)
- {
- g[row*width+col]=pDoc->ImgData[row*width+col];
- }
- }
- for(int c=0;c<width;c++)
- {
- Count[c]=0;
- TempCount[c]=0;
- }
- for(c=0;c<30;c++)
- {
- maxChanges[c]=0;
- Cols[c]=0;
- W[c]=0;
- left[c]=-1;
- }
- for(int col=0;col<width;col++)
- {
- for(int row=0;row<height-1;row++)
- {
- if(pDoc->ImgData[row*width+col]!=pDoc->ImgData[(row+1)*width+col])
- Count[col]++;
- }
- TempCount[col]=Count[col];
- }
- /////////////////////////////////////Top 30 change col
- for(int top=0;top<30;top++)
- {
- int Max=0;
- for(int col=0;col<width;)
- {
- if(Max<TempCount[col])
- {
- Max=TempCount[col];
- }
- col=col+10 ;
- }
- maxChanges[top]=Max;
- int C=0;
- for(col=0;col<width;)
- {
- if(Max!=TempCount[col])
- {
- col=col+10;
- }
- else
- {
- C=col;
- break;
- }
- }
- Cols[top]=C;
- TempCount[C]=0;
- }
- for(top=0;top<30;top++)
- {
- for(int range=-20;range<20;range++)
- {
- if((Cols[top]+range)>=0&&(Cols[top]+range)<width)
- {
- if((0.8*Count[Cols[top]]<=Count[Cols[top]+range])&&(Count[Cols[top]+range]<=1.2*Count[Cols[top]]))
- {
- for(int row=0;row<height;row++)
- {
- g[row*width+(Cols[top]+range)]=255;
- }
- }
- }
- else
- {
- continue;
- }
- }
- }
- for(row=0;row<height;row++)
- {
- for(int col=0;col<width;col++)
- {
- if(g[row*width+col]<255)
- {
- g[row*width+col]=0;
- }
- }
- }
- int Area=-1; //标识区域的地点
- if(g[10*width+0]==255)
- {
- Area++;
- W[Area]++;
- left[Area]=0;
- }
- for(col=1;col<width;col++)
- {
- if(g[10*width+col]==255 && g[10*width+(col-1)]==0)
- {
- Area++;
- W[Area]++;
- left[Area]=col;
- }
- else
- {
- if((g[10*width+col]==255)&&(g[10*width+col-1]==255))
- {
- W[Area]++;
- }
- }
- }
- for(int x=0;x<30;x++)
- {
- int w=W[x];
- if(w>10)
- {
- int c=0;
- int c0=0;
- c=left[x];
- c0=left[x]+w;
- if(c!=0&&c0!=width)
- {
- for(int row=0;row<height;row++)
- {
- pDoc->ImgData[row*width+c]=255;
- pDoc->ImgData[row*width+c0]=255;
- }
- }
- else
- {
- if(c==0)
- {
- c=10;
- for(int row=0;row<height;row++)
- {
- pDoc->ImgData[row*width+c]=255;
- pDoc->ImgData[row*width+c0]=255;
- }
- }
- else
- {
- if(c0==width)
- {
- c0=width-10;
- for(int row=0;row<height;row++)
- {
- pDoc->ImgData[row*width+c]=255;
- pDoc->ImgData[row*width+c0]=255;
- }
- }
- }
- }
- }
- }
- free(g);
- IsNewBitmap=true;
- IsNewFile=true;
- pDoc->UpdateAllViews(NULL);
- }
- /// <summary>
- /// CDipView::OnLocate()的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:完成车牌定位的整个过程
- /// 程序流程:1.产生副本
- /// 2.水平差分提取边缘,寻找横向的车牌带状区域
- /// 3.垂直差分提取边缘,寻找纵向的车牌带状区域
- /// 4.利用先验知识标识车牌区域,进行车牌带状区域的选择,(横纵向)
- /// 5.构造出车牌矩形域;
- /// 6.再次利用利用跳变数选择车牌矩形区域,进行车牌区域的最终选择;
- /// 7.精确定位车牌,即削弱车牌横向宽度;
- /// 8.更新图象;
- /// </summary>
- void CDipView::OnLocate()
- {
- // TODO: 在此添加命令处理程序代码
- CDipDoc *pDoc=GetDocument();
- int width,height;
- width=pDoc->ImgWidth;
- height=pDoc->ImgHeight;
- BYTE *g=new BYTE[width*height];
- CopyImg(pDoc,g,width,height);
- //Banlance(g,width,height);
- HSub(g,width,height);
- Search(g,width,height);
- CopyImg(pDoc,g,width,height);
- VSub(g,width,height);
- VSearch(g,width,height);
- Mark(pDoc,width,height);
- VMark(pDoc,width,height);
- DrawRect(pDoc,width,height);
- Choose(pDoc,width,height);
- FurtherLocate(pDoc,width,height);
- free(g);
- IsNewBitmap=true;
- IsNewFile=true;
- pDoc->UpdateAllViews(NULL);
- }
- // 均衡化图象
- void CDipView::Banlance(BYTE* DisposeImg,int Width,int Height)
- {
- float num=0;
- int row,col;
- int count[256];
- float s0[256];
- int s[256]; //256个灰度等级
- int x=0;
- int temp=0;
- for( x=0;x<256;x++)
- {
- count[x]=0;
- s0[x]=0.0;
- s[x]=0;
- }
- for(row=0;row<Height;row++) //每个灰度等级象素个数
- {
- for(col=0;col<Width;col++)
- {
- temp=DisposeImg[row*Width+col];
- count[temp]++;
- }
- }
- for(x=0;x<256;x++) //对应灰度等级概率
- {
- num=(float)Width*Height;
- s0[x]=(float)(count[x]/num);
- }
- for( x=1;x<256;x++) //概率累计,合并灰度等级
- {
- s0[x]+=s0[x-1];
- }
- for( x=0;x<256;x++) //映射
- {
- s[x]=(int)(s0[x]*255+0.5);
- }
- for(row=0;row<Height;row++) //每个灰度等级象素个数
- {
- for(col=0;col<Width;col++)
- {
- int reflect=0;
- temp=DisposeImg[row*Width+col];
- reflect=s[temp];
- DisposeImg[row*Width+col]=reflect;
- }
- }
- }
- // 图象复制
- void CDipView::CopyImg(CDipDoc * SourceImg, BYTE* DestImg, int Width, int Height)
- {
- for(int row=0;row<Height;row++)
- {
- for(int col=0;col<Width;col++)
- {
- DestImg[row*Width+col]=SourceImg->ImgData[row*Width+col];
- }
- }
- }
- // 图象复制
- void CDipView::CopyImg(BYTE* SourceImg, BYTE* DestImg, int Width , int Height)
- {
- for(int row=0;row<Height;row++)
- {
- for(int col=0;col<Width;col++)
- {
- DestImg[row*Width+col]=SourceImg[row*Width+col];
- }
- }
- }
- /// <summary>
- /// CDipView::HSub(BYTE* DisposeImg, int Width , int Height)的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:水平差分提取图象边缘。
- /// 程序流程:1.逐行扫描,sub=|f(x,y)-f(x,y+1)|;
- /// 2.若差值小于20,则g(x,y)=0;
- /// 若差值大于30,则增强原图象,令g(x,y)=g(x,y)+30;
- /// 3.另最后一列全部为0,即黑色;
- /// </summary>
- // 水平差分
- void CDipView::HSub(BYTE* DisposeImg, int Width , int Height)
- {
- int row,col,sub;
- for(row=0;row<Height;row++)
- {
- for(col=0;col<Width-1;col++)
- {
- sub=abs((DisposeImg[row*Width+col])-(DisposeImg[row*Width+col+1]));
- if(sub<20)
- {
- DisposeImg[row*Width+col]=0;
- }
- else
- {
- if(sub>30)
- {
- DisposeImg[row*Width+col]=sub+30;
- }
- else
- DisposeImg[row*Width+col]=sub;
- }
- }
- }
- for(row=0;row<Height;row++)
- {
- DisposeImg[row*Width+Width-1]=0;
- }
- }
- // 纵向差分
- void CDipView::VSub(BYTE* DisposeImg, int Width , int Height)
- {
- int row,col,sub;
- for(row=0;row<Height-1;row++)
- {
- for(col=0;col<Width;col++)
- {
- sub=abs((DisposeImg[row*Width+col])-(DisposeImg[(row+1)*Width+col]));
- /* if(sub<5)
- {
- DisposeImg[row*Width+col]=0;
- }
- else
- {
- if(sub>10)
- {
- DisposeImg[row*Width+col]=sub+30;
- }
- else
- DisposeImg[row*Width+col]=sub;
- }*/
- DisposeImg[row*Width+col]=sub;
- }
- }
- for(col=0;col<Width-1;col++)
- {
- DisposeImg[(Height-1)*Width+col]=0;
- }
- }
- /// <summary>
- /// CDipView::Search(BYTE* DisposeImg, int width , int height)的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:完成图象车牌区域的初步定位。即寻找出差分扫描后水平跳变数最大的前10个区域。
- /// 程序流程:1.利用间行扫描的方式找出跳变数最大的前10行;
- /// 2.对 Top 10 行进行区域细粒度增长选择;
- /// 其相似度的选取为:0.7~1.3 倍的该行跳变总数;
- /// 3.二值化,threshold=255;
- /// 4.任意选择一列,最好不要边缘列,可能有干扰(本程序选择为第十列),搜索出各个带状候选域,存入标志;
- /// </summary>
- void CDipView::Search(BYTE* DisposeImg, int width , int height)
- {
- BYTE*TempImg=new BYTE[width*height];
- int *Count= new int[height];
- int *TempCount=new int[height];
- int *maxChanges=new int[10];
- int *Rows=new int[10];
- CopyImg(DisposeImg,TempImg,width,height);
- for(int c=0;c<height;c++)
- {
- Count[c]=0;
- TempCount[c]=0;
- }
- for(c=0;c<10;c++)
- {
- maxChanges[c]=0;
- Rows[c]=0;
- Height[c]=0;
- TopRow[c]=-1;
- }
- for(int row=0;row<height;row++)
- {
- for(int col=0;col<width-1;col++)
- {
- if(DisposeImg[row*width+col]!=DisposeImg[row*width+col+1])
- Count[row]++;
- }
- TempCount[row]=Count[row];
- }
- /////////////////////////////////////Top 10 chage row
- for(int top=0;top<10;top++)
- {
- int Max=0;
- for(row=0;row<height;)
- {
- if(Max<TempCount[row])
- {
- Max=TempCount[row];
- }
- row=row+10 ;
- }
- maxChanges[top]=Max;
- int R=0;
- for(row=0;row<height;)
- {
- if(Max!=TempCount[row])
- {
- row=row+10;
- }
- else
- {
- R=row;
- break;
- }
- }
- Rows[top]=R;
- TempCount[R]=0;
- }
- for(top=0;top<10;top++)
- {
- for(int range=-10;range<10;range++)
- {
- if((0.7*Count[Rows[top]]<=Count[Rows[top]+range])&&(Count[Rows[top]+range]<=1.3*Count[Rows[top]]))
- {
- for(int col=0;col<width;col++)
- {
- DisposeImg[(Rows[top]+range)*width+col]=255;
- }
- }
- }
- }
- for(row=0;row<height;row++)
- {
- for(int col=0;col<width;col++)
- {
- if(DisposeImg[row*width+col]<255)
- {
- DisposeImg[row*width+col]=0;
- }
- }
- }
- int Area=0; //标识区域的地点
- if(DisposeImg[0*width+10]==255)
- {
- Area++;
- Height[Area]++;
- TopRow[Area]=0;
- }
- for(row=1;row<height;row++)
- {
- if((DisposeImg[row*width+10]==255) && (DisposeImg[(row-1)*width+10]==0))
- {
- Area++;
- Height[Area]++;
- TopRow[Area]=row;
- }
- else
- {
- if(DisposeImg[row*width+10]==255&&DisposeImg[(row-1)*width+10]==255)
- {
- Height[Area]++;
- }
- }
- }
- // Mark(TempImg,width,height);
- // CopyImg(TempImg,DisposeImg,width,height);
- free(TempImg);
- free(Count);
- free(TempCount);
- free(maxChanges);
- free(Rows);
- }
- /// <summary>
- /// CDipView::Mark(CDipDoc * DisposeImg, int width , int height)的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:利用先验知识标识车牌区域,进行车牌区域的选择,(横向)
- /// 函数说明:特定应用条件,拍摄所得车牌的区域高度、宽度均有一定的范围,其大小可以分析图象后可得
- /// 根据统计得到:车牌的顶部极少出现在高度小于100个像素的区域;
- /// 车牌高度也一般大于20个像素。
- /// 程序的最终结果为满足条件的经过扩展了的带状区域
- /// 程序流程:1.舍弃区域顶部小于100的待选域
- /// 2.选择区域高度大于20的待选域
- /// 3.区域扩展,上下各增大5个像素。若顶部小于5,则顶部坐标不变,高度加5;
- /// 若底部大于图象的底部,则底部坐标不变,高度加5;
- /// </summary>
- void CDipView::Mark(CDipDoc * DisposeImg, int width , int height)
- {
- for(int x=0;x<20;x++)
- {
- int h=Height[x];
- if(TopRow[x]<=5)
- {
- Height[x]=0;
- TopRow[x]=-1;
- }
- }
- for(x=0;x<20;x++)
- {
- int h=Height[x];
- if(h>20)
- {
- int r=0;
- int r0=0;
- r=TopRow[x]-5;
- r0=TopRow[x]+h+5;
- if((r>0)&&(r0<height))
- {
- // for(int col=0;col<width;col++)
- // {
- // DisposeImg->ImgData[r*width+col]=255;
- // DisposeImg->ImgData[r0*width+col]=255;
- // }
- TopRow[x]=r+5;
- Height[x]=h;
- }
- else
- {
- if(r<=0)
- {
- r=r+5;
- //for(int col=0;col<width;col++)
- // {
- // DisposeImg->ImgData[r*width+col]=255;
- // DisposeImg->ImgData[r0*width+col]=255;
- //}
- TopRow[x]=r;
- Height[x]=h;
- }
- else
- {
- if(r0>=height)
- {
- r0=r0-5;
- //for(int col=0;col<width;col++)
- //{
- // DisposeImg->ImgData[r*width+col]=255;
- // DisposeImg->ImgData[r0*width+col]=255;
- //}
- Height[x]=Height[x]-5;
- }
- }
- }
- }
- }
- for(x=0;x<20;x++)
- {
- int h=Height[x];
- if(h<20||TopRow[x]<=100)
- {
- Height[x]=0;
- TopRow[x]=-1;
- }
- }
- }
- /// <summary>
- /// CDipView::VSearch(BYTE* DisposeImg, int width , int height)的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:水平查找后,纵向查找。完成图象车牌区域的初步定位。即寻找出差分扫描后垂直跳变数最大的前30个区域。
- /// 程序流程:1.利用间行扫描的方式找出跳变数最大的前30行;
- /// 2.对 Top 30 行进行区域增长;
- /// 其相似度的选取为:0.8~1.2 倍的该行跳变总数;
- /// 3.二值化,threshold=255;
- /// 4.任意选择一列,(本程序选择为第十行),搜索出各个带状候选域,存入标志;
- /// </summary>
- //
- void CDipView::VSearch(BYTE* DisposeImg, int width, int height)
- {
- BYTE *g=new BYTE[width*height];
- int *Count= new int[width];
- int *TempCount=new int[width];
- int *maxChanges=new int[30];
- int *Cols=new int[30]; //maxChanges' col
- CopyImg(DisposeImg,g,width,height);
- for(int c=0;c<width;c++)
- {
- Count[c]=0;
- TempCount[c]=0;
- }
- for(c=0;c<30;c++)
- {
- maxChanges[c]=0;
- Cols[c]=0;
- Widths[c]=0;
- Left[c]=-1;
- }
- for(int col=0;col<width;col++)
- {
- for(int row=0;row<height-1;row++)
- {
- if(DisposeImg[row*width+col]!=DisposeImg[(row+1)*width+col])
- Count[col]++;
- }
- TempCount[col]=Count[col];
- }
- /////////////////////////////////////Top 30 change col
- for(int top=0;top<30;top++)
- {
- int Max=0;
- for(int col=0;col<width;)
- {
- if(Max<TempCount[col])
- {
- Max=TempCount[col];
- }
- col=col+10 ;
- }
- maxChanges[top]=Max;
- int C=0;
- for(col=0;col<width;)
- {
- if(Max!=TempCount[col])
- {
- col=col+10;
- }
- else
- {
- C=col;
- break;
- }
- }
- Cols[top]=C;
- TempCount[C]=0;
- }
- for(top=0;top<30;top++)
- {
- for(int range=-20;range<20;range++)
- {
- if((Cols[top]+range)>=0&&(Cols[top]+range)<width)
- {
- if((0.8*Count[Cols[top]]<=Count[Cols[top]+range])&&(Count[Cols[top]+range]<=1.2*Count[Cols[top]]))
- {
- for(int row=0;row<height;row++)
- {
- DisposeImg[row*width+(Cols[top]+range)]=255;
- }
- }
- }
- else
- {
- continue;
- }
- }
- }
- for(int row=0;row<height;row++)
- {
- for(int col=0;col<width;col++)
- {
- if(DisposeImg[row*width+col]<255)
- {
- DisposeImg[row*width+col]=0;
- }
- }
- }
- int Area=-1; //标识区域的地点
- if(DisposeImg[10*width+0]==255)
- {
- Area++;
- Widths[Area]++;
- Left[Area]=0;
- }
- for(col=1;col<width;col++)
- {
- if(DisposeImg[10*width+col]==255 && DisposeImg[10*width+(col-1)]==0)
- {
- Area++;
- Widths[Area]++;
- Left[Area]=col;
- }
- else
- {
- if((DisposeImg[10*width+col]==255)&&(DisposeImg[10*width+col-1]==255))
- {
- Widths[Area]++;
- }
- }
- }
- }
- // 纵向定位
- void CDipView::VMark(CDipDoc* DisposeImg, int width, int height)
- {
- for(int x=0;x<30;x++)
- {
- int w=Widths[x];
- if(w>100)
- {
- int c=0;
- int c0=0;
- c=Left[x];
- c0=Left[x]+w-10;
- if(c!=0&&c0>0)
- {
- //for(int row=0;row<height;row++)
- //{
- // DisposeImg->ImgData[row*width+c]=255;
- // DisposeImg->ImgData[row*width+c0]=255;
- //}
- Widths[x]=Widths[x]-10;
- }
- else
- {
- if(c<=0)
- {
- c=5;
- //for(int row=0;row<height;row++)
- //{
- // DisposeImg->ImgData[row*width+c]=255;
- // DisposeImg->ImgData[row*width+c0]=255;
- //}
- Left[x]=c;
- }
- else
- {
- if(c0<=0)
- {
- c0=c0+10;
- //for(int row=0;row<height;row++)
- // {
- // DisposeImg->ImgData[row*width+c]=255;
- // DisposeImg->ImgData[row*width+c0]=255;
- //}
- //Widths[x]=Widths[x]-5;
- }
- }
- }
- }
- }
- for(x=0;x<30;x++)
- {
- int w=Widths[x];
- if(w<100)
- {
- Widths[x]=0;
- Left[x]=-1;
- }
- }
- }
- /// <summary>
- /// CDipView::DrawRect(CDipDoc* DisposeImg, int width, int height)的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:利用先验知识标识车牌区域,进行车牌区域的选择,(横纵向)
- /// 函数说明:国家标准:车牌的宽高比近似为3:1;
- /// 程序流程:1.初始化存储数组
- /// 2.选择区域高宽比大于3的待选域
- /// </summary>
- void CDipView::DrawRect(CDipDoc* DisposeImg, int width, int height)
- {
- for(int x=0;x<50;x++)
- {
- Rect_X[x]=-1;
- Rect_Y[x]=-1;
- Rect_W[x]=0;
- Rect_H[x]=0;
- }
- Rect_Areas=0;
- for(int m=0;m<20;m++)
- {
- for(int n=0;n<30;n++)
- {
- if((Widths[n]>3*Height[m])&&(Widths[n]*Height[m]!=0))
- {
- Rect_Areas++;
- Rect_X[Rect_Areas-1]=Left[n];
- Rect_Y[Rect_Areas-1]=TopRow[m];
- Rect_W[Rect_Areas-1]=Widths[n];
- Rect_H[Rect_Areas-1]=Height[m];
- }
- }
- }
- //for( x=0;x<Rect_Areas;x++)
- //{
- // for(int row=Rect_Y[x];row<(Rect_Y[x]+Rect_H[x]);row++)
- // {
- // DisposeImg->ImgData[row*width+Rect_X[x]]=255;
- // DisposeImg->ImgData[row*width+Rect_X[x]+Rect_W[x]]=255;
- // }
- //}
- //for( x=0;x<Rect_Areas;x++)
- //{
- // for(int col=Rect_X[x];col<(Rect_X[x]+Rect_W[x]);col++)
- // {
- // DisposeImg->ImgData[Rect_Y[x]*width+col]=255;
- // DisposeImg->ImgData[(Rect_Y[x]+Rect_H[x])*width+col]=255;
- // }
- //}
- }
- void CDipView::OnChoose()
- {
- // TODO: Add your command handler code here
- }
- /// <summary>
- /// CDipView::Choose(CDipDoc *DisposeImg, int width, int height)的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:再次利用利用跳变数选择车牌区域,进行车牌区域的最终选择,(横纵向)
- /// 程序流程:1.初始化存储数组
- /// 2.计算每个伪车牌区域的跳变数
- /// 3.选择具有最大跳变数的区域为车牌区
- /// </summary>
- void CDipView::Choose(CDipDoc *DisposeImg, int width, int height)
- {
- int row=0;
- int col=0;
- int temp=0;
- int *JumpNums=new int[Rect_Areas];
- for(int area=0;area<Rect_Areas;area++)
- {
- JumpNums[area]=0;
- }
- for(area=0;area<Rect_Areas;area++) //计算每个伪车牌区域的行跳变数
- {
- BYTE* TempImg=new BYTE[Rect_W[area]*Rect_H[area]];
- for(row=0;row<Rect_H[area];row++)
- {
- for(col=0;col<Rect_W[area];col++)
- {
- TempImg[row*Rect_W[area]+col]=DisposeImg->ImgData[(Rect_Y[area]+row)*width+(Rect_X[area]+col)];
- }
- }
- JumpNums[area]=JumpNum(TempImg,Rect_W[area],Rect_H[area]);
- free(TempImg);
- }
- temp=MaxJump(JumpNums,Rect_Areas);
- // 区域刻画
- /* for(row=Rect_Y[temp];row<(Rect_Y[temp]+Rect_H[temp]);row++)
- {
- DisposeImg->ImgData[row*width+Rect_X[temp]]=255;
- DisposeImg->ImgData[row*width+(Rect_X[temp]+Rect_W[temp])]=255;
- }
- for(col=Rect_X[temp];col<(Rect_X[temp]+Rect_W[temp]);col++)
- {
- DisposeImg->ImgData[Rect_Y[temp]*width+col]=255;
- DisposeImg->ImgData[(Rect_Y[temp]+Rect_H[temp])*width+col]=255;
- } */
- //剔除伪车牌区
- for(area=0;area<Rect_Areas;area++)
- {
- if(area!=temp)
- {
- Rect_X[area]=-1;
- Rect_Y[area]=-1;
- Rect_W[area]=0;
- Rect_H[area]=0;
- }
- }
- //移至第一位
- Rect_X[0]=Rect_X[temp];
- Rect_Y[0]=Rect_Y[temp];
- Rect_W[0]=Rect_W[temp];
- Rect_H[0]=Rect_H[temp];
- //清空
- if(temp!=0)
- {
- Rect_X[temp]=-1;
- Rect_Y[temp]=-1;
- Rect_W[temp]=0;
- Rect_H[temp]=0;
- }
- Rect_Areas=1;
- }
- /// <summary>
- /// CDipView::JumpNum(BYTE *DisposeImg,int width,int height)的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:计算伪车牌区的跳变平均数
- /// 程序流程:1.初始化;
- /// 2.水平差分,边缘提取;
- /// 3.选择车牌的中间1/3行来计算每个伪车牌区域的跳变平均数;
- /// </summary>
- /// <return>各个区域的平均跳变数</return>
- int CDipView::JumpNum(BYTE *DisposeImg,int width,int height)
- {
- int startRow=0;
- int endRow=0;
- long JumpNum=0;
- int averJump=0;
- int r=0;
- BYTE* g=new BYTE[width*height];
- CopyImg(DisposeImg,g,width,height);
- HSub(g,width,height);
- startRow=(int)(0+height/3);
- endRow=(int)(0+2*height/3);
- for(int row=startRow;row<endRow;row++)
- {
- for(int col=0;col<width-1;col++)
- {
- if(g[row*width+col]!=g[row*width+col+1])
- JumpNum++;
- }
- }
- r=endRow-startRow;
- averJump=(int)(JumpNum/r);
- free(g);
- return averJump;
- }
- /// <summary>
- /// CDipView::MaxJump(int *JumpNums,int num)的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:找出所有伪车牌区域中具有最大跳变平均数的区域号
- /// 程序说明:选择排序
- /// </summary>
- /// <return>最大跳变平均数的区域号</return>
- int CDipView::MaxJump(int *JumpNums,int num)
- {
- int area=0;
- int temp=0;
- int val=0;
- val=JumpNums[0];
- for(area=0;area<num;area++)
- {
- if(JumpNums[area]>val)
- {
- temp=area;
- val=JumpNums[area];
- }
- }
- return temp;
- }
- /// <summary>
- /// CDipView::FurtherLocate(CDipDoc *DisposeImg,int width,int height)的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:精确定位车牌
- /// 程序流程:
- /// 程序说明:由于水平分割出的伪车牌区域已经比较准确,故仅作垂直方向的进一步定位(缩小宽度)
- /// </summary>
- void CDipView::FurtherLocate(CDipDoc *DisposeImg,int width,int height)
- {
- int row=0;
- int col=0;
- //copy 到一个暂存数组,以便处理操作且不破坏原图象
- BYTE* TempImg=new BYTE[Rect_W[0]*Rect_H[0]];
- for(row=0;row<Rect_H[0];row++)
- {
- for(col=0;col<Rect_W[0];col++)
- {
- TempImg[row*Rect_W[0]+col]=DisposeImg->ImgData[(Rect_Y[0]+row)*width+(Rect_X[0]+col)];
- }
- }
- VFurthLocate(TempImg,Rect_W[0],Rect_H[0]);
- /* int temp=0;
- // 区域刻画
- for(row=Rect_Y[temp];row<(Rect_Y[temp]+Rect_H[temp]);row++)
- {
- DisposeImg->ImgData[row*width+Rect_X[temp]]=255;
- DisposeImg->ImgData[row*width+(Rect_X[temp]+Rect_W[temp])]=255;
- }
- for(col=Rect_X[temp];col<(Rect_X[temp]+Rect_W[temp]);col++)
- {
- DisposeImg->ImgData[Rect_Y[temp]*width+col]=255;
- DisposeImg->ImgData[(Rect_Y[temp]+Rect_H[temp])*width+col]=255;
- } */
- free(TempImg);
- }
- /// <summary>
- /// CDipView::VFurthLocate(BYTE *DisposeImg, int width, int height)的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:找出车牌的左右边缘
- /// 程序流程:1.水平差分,二值化;
- /// 2.垂直方向投影,统计各列的投影值;
- /// 3.去除噪声点;
- /// 4.找出左右边缘
- /// 5.计算车牌宽度
- /// 6.车牌精确定位赋值
- /// </summary>
- void CDipView::VFurthLocate(BYTE *DisposeImg, int width, int height)
- {
- int row=0;
- int col=0;
- int num=0;
- int leftCol=0;
- int rightCol=width-1;
- HSub(DisposeImg,width,height);
- ForHandle(DisposeImg,width,height); //二值化
- //note the value of hProjection
- int*HProj=new int[width];
- for(col=0;col<width;col++)
- {
- HProj[col]=0;
- }
- for(col=0;col<width;col++)
- {
- for(row=0;row<height;row++)
- {
- if(DisposeImg[row*width+col]==255)
- HProj[col]++;
- }
- }
- HProj[0]=0;
- for(col=0;col<width;col++) //去除噪声点
- {
- if(HProj[col]<3)
- {
- HProj[col]=0;
- }
- }
- ///////////////////////////////////////////找出左边缘
- int nextCol=0;
- int w=0;
- for(col=0;col<width;col++)
- {
- num=0;
- if(HProj[col]==0&&HProj[col+1]!=0)
- {
- num++;
- nextCol=FindNextCol_LR(HProj,width,col);
- w=nextCol-col;
- leftCol=col;
- }
- if(w<3)
- {
- num=num-1;
- }
- if(num==1)
- {
- break;
- }
- }
- //////////////////////////////////////////找出右边缘
- nextCol=0;
- w=0;
- for(col=width;col>=0;col--)
- {
- num=0;
- if(HProj[col]==0&&HProj[col-1]!=0)
- {
- num++;
- nextCol=FindNextCol_RL(HProj,width,col);
- w=col-nextCol;
- rightCol=col;
- }
- if(w<3)
- {
- num=num-1;
- }
- if(num==1)
- {
- break;
- }
- }
- int blantCols=0;
- blantCols=leftCol+(width-rightCol);
- Rect_X[0]+=leftCol;
- Rect_W[0]=width-blantCols;
- free(HProj);
- }
- /// <summary>
- /// CDipView::ForHandle(BYTE *DisposeImg, int width, int height)的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:二值化图象
- /// 程序说明:threshold=average+delt;
- /// 程序流程:1.计算图象均值;
- /// 2.计算图象方差;
- /// 3.二值化
- /// </summary>
- void CDipView::ForHandle(BYTE *DisposeImg, int width, int height)
- {
- BYTE *temp=new BYTE[height*width];
- int x,y;
- CopyImg(DisposeImg,temp,width,height);
- long double total=0;
- float aver=0;
- for(x=0;x<height;x++)
- {
- for(y=0;y<width;y++)
- {
- total+=DisposeImg[x*width+y];
- }
- }
- aver=(BYTE)(total/(float)(height*width));
- float delt;
- float sub=0;
- for(x=0;x<height;x++)
- {
- for(y=0;y<width;y++)
- {
- sub+=(DisposeImg[x*width+y]-aver)*(DisposeImg[x*width+y]-aver);
- }
- }
- delt=(float)(sqrt(sub/(float)(height*width)));
- BYTE judge;
- judge=(BYTE)(delt+aver);
- for(x=0;x<height;x++)
- {
- for(y=0;y<width;y++)
- {
- if(DisposeImg[(x*width)+y]>=judge)
- {
- DisposeImg[(x*width)+y]=255;
- }
- else
- {
- DisposeImg[(x*width)+y]=0;
- }
- }
- }
- free(temp);
- }
- // 寻找left==255,right==0的列
- int CDipView::FindNextCol_LR(int* HProj, int size, int objectCol)
- {
- int num=0;
- int x=0;
- for(x=objectCol;x<size;x++)
- {
- if(HProj[x]>=0&&HProj[x+1]==0)
- {
- num++;
- }
- if(num==1)
- {
- break;
- }
- }
- if(num==0)
- {
- return objectCol;
- }
- else
- {
- return x;
- }
- }
- // 寻找right==255,left==0的列
- int CDipView::FindNextCol_RL(int* HProj, int size, int objectCol)
- {
- int num=0;
- int x=0;
- for(x=objectCol;x>=0;x--)
- {
- if(HProj[x]>=0&&HProj[x-1]==0)
- {
- num++;
- }
- if(num==1)
- {
- break;
- }
- }
- if(num==0)
- {
- return objectCol;
- }
- else
- {
- return x;
- }
- }
- void CDipView::OnSobel()
- {
- // TODO: 在此添加命令处理程序代码
- }
- /// <summary>
- /// CDipView::OnVSplit()的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:车牌字符分割
- /// 程序流程:1.区域扩展;
- /// 2.投影分割;
- /// 3.字符区域的获取;
- /// </summary>
- void CDipView::OnVSplit()
- {
- // TODO: 在此添加命令处理程序代码
- CDipDoc *pDoc=GetDocument();
- int width,height;
- width=pDoc->ImgWidth;
- height=pDoc->ImgHeight;
- int row=0;
- int col=0;
- //extend area
- int threshold=2;
- Rect_X[0]=Rect_X[0];
- Rect_Y[0]=Rect_Y[0];//-threshold;
- Rect_W[0]=Rect_W[0]+7;
- Rect_H[0]=Rect_H[0];//+2*threshold;
- //车牌区域的高度、宽度
- int w=Rect_W[0];
- int h=Rect_H[0];
- BYTE* TempImg=new BYTE[w*h];
- for(row=0;row<h;row++)
- {
- for(col=0;col<w;col++)
- {
- TempImg[row*w+col]=pDoc->ImgData[(Rect_Y[0]+row)*width+(Rect_X[0]+col)];
- }
- }
- //二值化车牌区域图象
- ForHandle(TempImg,w,h);
- //搜索各字符域
- int *projArray=new int[w];
- for(col=0;col<w;col++)
- {
- projArray[col]=0;
- }
- HProj(TempImg,projArray,w,h);
- CharacterSplit(projArray,w);
- // GetCharacter();
- ///////////////////////////////标记出各个字符区域
- int area;
- area=CharacterNum;
- for(;area>=0;area--)
- {
- if(cRects[area].w!=0&&cRects[area].x!=-1)
- {
- for(row=cRects[area].y;row<(cRects[area].y+cRects[area].h);row++) //draw vertical line
- {
- pDoc->ImgData[row*width+cRects[area].x]=255;
- pDoc->ImgData[row*width+(cRects[area].x+cRects[area].w)]=255;
- }
- for(col=cRects[area].x;col<(cRects[area].x+cRects[area].w);col++) //draw horizontal line
- {
- pDoc->ImgData[cRects[area].y*width+col]=255;
- pDoc->ImgData[(cRects[area].y+cRects[area].h)*width+col]=255;
- }
- }
- }
- // 区域刻画
- //int temp=0;
- //for(row=Rect_Y[temp];row<(Rect_Y[temp]+Rect_H[temp]);row++)
- //{
- // pDoc->ImgData[row*width+Rect_X[temp]]=255;
- // pDoc->ImgData[row*width+(Rect_X[temp]+Rect_W[temp])]=255;
- //}
- //
- // for(col=Rect_X[temp];col<(Rect_X[temp]+Rect_W[temp]);col++)
- //{
- // pDoc->ImgData[Rect_Y[temp]*width+col]=255;
- // pDoc->ImgData[(Rect_Y[temp]+Rect_H[temp])*width+col]=255;
- //}
- //for(row=Rect_Y[temp];row<(Rect_Y[temp]+Rect_H[temp]);row++)
- //{
- // for(col=0;col<w;col++)
- // {
- // if(projArray[col]==1)
- // {
- // pDoc->ImgData[row*width+Rect_X[temp]+col]=255;
- // // pDoc->ImgData[row*width+(Rect_X[temp]+Rect_W[temp])]=255;
- // }
- // }
- //}
- free(TempImg);
- free(projArray);
- IsNewBitmap=true;
- IsNewFile=true;
- pDoc->UpdateAllViews(NULL);
- }
- // 图像规定化0~100
- void CDipView::GuiYiHua(BYTE* DisposeImg, int width , int height)
- {
- }
- // 增强车牌区,削弱背景
- void CDipView::Hance(BYTE* DisposeImg, int width , int height)
- {
- }
- void CDipView::OnGuiYiHua()
- {
- // TODO: 在此添加命令处理程序代码
- }
- void CDipView::OnHance()
- {
- // TODO: 在此添加命令处理程序代码
- }
- /// <summary>
- /// CDipView::HProj(BYTE* DisposeImg, int* projArray, int width , int height)的摘要说明。
- /// 创建人 :刘陈炜
- /// 创建时间:2004.5.1
- /// 函数功能:水平方向投影,分割出字符
- /// 程序流程:1.统计各列白象素个数;
- /// 2.平滑投影曲线;
- /// 3.寻找波谷(trough)进行分割;
- /// </summary>
- void CDipView::HProj(BYTE* DisposeImg, int* projArray, int width , int height)
- {
- int row=0;
- int col=0;
- float alph=0.0;
- int*E=new int[width];
- long double*MSE=new long double[9]; //针对每一个alph的deltl;
- //统计各列白象素个数
- for(col=0;col<width;col++)
- {
- for(row=0;row<height;row++)
- {
- if(DisposeImg[row*width+col]==255)
- projArray[col]++;
- }
- }
- //一次平滑
- for(int x=1;x<10;x++)
- {
- alph=(float)(0.1*x);
- E[0]=projArray[0];
- for(col=1;col<width;col++)
- {
- E[col]=(int)(alph*projArray[col]+(1-alph)*E[col-1]);
- }
- for(col=0;col<width;col++)
- {
- MSE[x-1]+=(projArray[col]-E[col])*(projArray[col]-E[col]);
- }
- MSE[x-1]=MSE[x-1]/width;
- }
- long double min=0.0;
- for(x=1;x<10;x++)
- {
- if(MSE[x-1]>min)
- {
- min=MSE[x-1];
- }
- }
- for(x=1;x<10;x++)
- {
- if(MSE[x-1]==min)
- {
- alph=(float)(0.1*x);
- }
- }
- E[0]=projArray[0];
- for(col=1;col<width;col++)
- {
- E[col]=(int)(alph*projArray[col]+(1-alph)*E[col-1]);
- }
- for(col=1;col<width;col++)
- {
- projArray[col]=E[col];
- E[col]=0;
- }
- //二次平滑
- for(x=1;x<10;x++)
- {
- alph=(float)(0.1*x);
- E[0]=projArray[0];
- for(col=1;col<width;col++)
- {
- E[col]=(int)(alph*projArray[col]+(1-alph)*E[col-1]);
- }
- for(col=0;col<width;col++)
- {
- MSE[x-1]+=(projArray[col]-E[col])*(projArray[col]-E[col]);
- }
- MSE[x-1]=MSE[x-1]/width;
- }
- min=0.0;
- for(x=1;x<10;x++)
- {
- if(MSE[x-1]<min)
- {
- min=MSE[x-1];
- }
- }
- for(x=1;x<10;x++)
- {
- if(MSE[x-1]==min)
- {
- alph=(float)(0.1*x);
- }
- }
- E[0]=projArray[0];
- for(col=1;col<width;col++)
- {
- E[col]=(int)(alph*projArray[col]+(1-alph)*E[col-1]);
- }
- for(col=1;col<width;col++)
- {
- projArray[col]=E[col];
- E[col]=0;
- }
- //寻找波谷进行分割trough
- FindTrough(projArray,width); //获得波谷位置
- free(E);
- free(MSE);
- }
- // 寻找波谷,划分字符区间
- void CDipView::FindTrough(int* Array, int size)
- {
- int col=0;
- bool*flage=new bool[size];
- bool LFlage=false; //a wave start leftside
- bool RFlage=false; //a wave end rightside
- int LSide=0; //left side
- int RSide=0; //right side
- int length=0; //area width
- for(col=0;col<size;col++)
- {
- flage[col]=false;
- }
- for(col=1;col<size-1;col++)
- {
- if(Array[col]==0&&Array[col+1]!=0&&LFlage==false)
- {
- flage[col]=true;
- LFlage=true;
- }
- if((Array[col-1]!=0)&&(Array[col]==0)&&(LFlage==true)&&(RFlage==false))
- {
- flage[col]=true;
- RFlage=true;
- }
- if((LFlage==true)&&(RFlage==true))
- {
- LFlage=false;
- RFlage=false;
- }
- }
- for(col=0;col<size;col++)
- {
- Array[col]=0;
- if(flage[col]==true)
- {
- Array[col]=1;
- }
- }
- }
- // 分割字符
- void CDipView::CharacterSplit(int* Array, int size)
- {
- CDipDoc *pDoc=GetDocument();
- int width,height;
- width=pDoc->ImgWidth;
- height=pDoc->ImgHeight;
- int x=Rect_X[0];
- int y=Rect_Y[0];
- int w=Rect_W[0];
- int h=Rect_H[0];
- int num=0;
- for(num=0;num<10;num++)
- {
- cRects[num].x=-1;
- cRects[num].y=-1;
- cRects[num].w=0;
- cRects[num].h=0;
- }
- bool flage=false;
- int row=0;
- int col=0;
- int area=0;
- num=0;
- for(col=0;col<size;col++)
- {
- if(Array[col]==1)
- {
- num++;
- if(num%2!=0&&flage==false)
- {
- flage=true;
- cRects[area].x=x+col;
- }
- else if(num%2==0&&flage==true)
- {
- flage=false;
- cRects[area].w=col-(cRects[area].x-x);
- cRects[area].y=y;
- cRects[area].h=h;
- area++;
- }
- }
- }
- CharacterNum=area;
- // CharacterNum=area+1;
- for(;area>=0;area--)
- {
- if(cRects[area].w!=0)
- {
- for(row=cRects[area].y;row<(cRects[area].y+cRects[area].h);row++) //draw vertical line
- {
- pDoc->ImgData[row*width+cRects[area].x-1]=255;
- pDoc->ImgData[row*width+(cRects[area].x+cRects[area].w)]=255;
- }
- for(col=cRects[area].x;col<(cRects[area].x+cRects[area].w);col++) //draw horizontal line
- {
- pDoc->ImgData[(cRects[area].y-1)*width+col]=255;
- pDoc->ImgData[(cRects[area].y+cRects[area].h)*width+col]=255;
- }
- }
- }
- //save character
- for(area=CharacterNum;area>=0;area--)
- {
- cDatas[area].w=cRects[area].w;
- cDatas[area].h=cRects[area].h;
- cDatas[area].Img=new BYTE[cRects[area].w*cRects[area].h];
- for(row=cRects[area].y;row<(cRects[area].y+cRects[area].h);row++) //draw vertical line
- {
- for(col=cRects[area].x;col<(cRects[area].x+cRects[area].w);col++) //draw horizontal line
- {
- cDatas[area].Img[(row-cRects[area].y)*cRects[area].w+(col-cRects[area].x)]=pDoc->ImgData[row*width+col];
- }
- }
- }
- }
- /*
- // 读取样本库,传入一个sample类型的数组(从文件里读出的样本数据将放入其中),返回值为样本个数
- int CDipView::LoadCharLib(sample* sa)
- {
- CFile cf;
- if(cf.Open(".\mydata.dat",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite)==0)
- {
- AfxMessageBox("打开文件失败,n您最好退出程序");
- }
- int num=0;
- try
- {
- sample sampleTemp;
- cf.SeekToBegin();
- DWORD dwBytesRemaining=(DWORD)(cf.GetLength());
- while(dwBytesRemaining)
- {
- UINT nBytesRead=cf.Read(&sampleTemp,sizeof(sample));
- sa[num]=sampleTemp;
- dwBytesRemaining-=nBytesRead;
- num++;
- }
- CString s;
- // s.Format("共读取数据%d个,最后一个的序列号为%d",
- // num,sampleTemp.serialnum);
- // AfxMessageBox(s);
- }
- catch(CFileException *e)
- {
- e->ReportError();
- e->Delete();
- }
- cf.Close();
- return num;
- }
- // 缩放算法,一律缩放为20*36
- void CDipView::Zoom(BYTE* DisposeImg, int width, int height)
- {
- if ((width==20)&&(height==36))
- return;
- // 源图像的宽度和高度
- LONG lWidth=width;
- LONG lHeight=height;
- BYTE *temp_img=new BYTE[width*height];
- // 循环变量
- int i;
- int j;
- for(i = 0; i < height; i++)
- {
- for(j = 0; j < width; j++)
- {
- temp_img[j+i*width]=DisposeImg[j+i*width];
- }
- }
- // 缩放后图像的宽度和高度
- LONG lNewWidth;
- LONG lNewHeight;
- float XZRatio=(float)( 20.0/(float)(width));
- float YZRatio=(float)(36.0/(float)(height));
- // 象素在源坐标
- LONG i0;
- LONG j0;
- //归一后的大小
- lNewWidth = 20;
- lNewHeight = 36;
- height=lNewHeight;
- width=lNewWidth;
- for(i = 0;i< lNewHeight;i++)
- {
- for(j = 0;j< lNewWidth;j++)
- {
- i0 = (LONG) (i / YZRatio + 0.5);
- j0 = (LONG) (j / XZRatio + 0.5);
- // 判断是否在源图范围内
- if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight))
- {
- // 复制象素
- DisposeImg[j+i*lWidth] = temp_img[j0 + i0*lWidth];
- }
- else
- {
- // 对于源图中没有的象素,直接赋值为255
- // DisposeImg[j+i*lWidth] = 0;
- }
- }
- }
- delete [] temp_img;
- }
- // 二值化算法,二值化为0和1两种值
- void CDipView::BinaryImg(BYTE* DisposeImg, int width , int height)
- {
- BYTE *temp=new BYTE[height*width];
- int x,y;
- CopyImg(DisposeImg,temp,width,height);
- long double total=0;
- float aver=0;
- for(x=0;x<height;x++)
- {
- for(y=0;y<width;y++)
- {
- total+=DisposeImg[x*width+y];
- }
- }
- aver=(BYTE)(total/(float)(height*width));
- float delt;
- float sub=0;
- for(x=0;x<height;x++)
- {
- for(y=0;y<width;y++)
- {
- sub+=(DisposeImg[x*width+y]-aver)*(DisposeImg[x*width+y]-aver);
- }
- }
- delt=(float)(sqrt(sub/(float)(height*width)));
- BYTE judge;
- judge=(BYTE)(delt+aver);
- for(x=0;x<height;x++)
- {
- for(y=0;y<width;y++)
- {
- if(DisposeImg[(x*width)+y]>=judge)
- {
- DisposeImg[(x*width)+y]=(BYTE)1;
- }
- else
- {
- DisposeImg[(x*width)+y]=(BYTE)0;
- }
- }
- }
- free(temp);
- }
- // Hilditch细化算法
- void CDipView::ThinnerHilditch(void* image, unsigned long lx, unsigned long ly)
- {
- char *f, *g;
- char n[10];
- unsigned int counter;
- short k, shori, xx, nrn;
- unsigned long i, j;
- long kk, kk11, kk12, kk13, kk21, kk22, kk23, kk31, kk32, kk33, size;
- size = (long)lx * (long)ly;
- g = (char *)malloc(size);
- if(g == NULL)
- {
- printf("error in allocating memory!n");
- return;
- }
- f = (char *)image;
- for(i=0; i<lx; i++)
- {
- for(j=0; j<ly; j++)
- {
- kk=i*ly+j;
- if(f[kk]!=0)
- {
- f[kk]=1;
- g[kk]=f[kk];
- }
- }
- }
- counter = 1;
- do
- {
- printf("%4d*",counter);
- counter++;
- shori = 0;
- for(i=0; i<lx; i++)
- {
- for(j=0; j<ly; j++)
- {
- kk = i*ly+j;
- if(f[kk]<0)
- f[kk] = 0;
- g[kk]= f[kk];
- }
- }
- for(i=1; i<lx-1; i++)
- {
- for(j=1; j<ly-1; j++)
- {
- kk=i*ly+j;
- if(f[kk]!=1)
- continue;
- kk11 = (i-1)*ly+j-1;
- kk12 = kk11 + 1;
- kk13 = kk12 + 1;
- kk21 = i*ly+j-1;
- kk22 = kk21 + 1;
- kk23 = kk22 + 1;
- kk31 = (i+1)*ly+j-1;
- kk32 = kk31 + 1;
- kk33 = kk32 + 1;
- if((g[kk12]&&g[kk21]&&g[kk23]&&g[kk32])!=0)
- continue;
- nrn = g[kk11] + g[kk12] + g[kk13] + g[kk21] + g[kk23] +
- g[kk31] + g[kk32] + g[kk33];
- if(nrn <= 1)
- {
- f[kk22] = 2;
- continue;
- }
- n[4] = f[kk11];
- n[3] = f[kk12];
- n[2] = f[kk13];
- n[5] = f[kk21];
- n[1] = f[kk23];
- n[6] = f[kk31];
- n[7] = f[kk32];
- n[8] = f[kk33];
- n[9] = n[1];
- xx = 0;
- for(k=1; k<8; k=k+2)
- {
- if((!n[k])&&(n[k+1]||n[k+2]))
- xx++;
- }
- if(xx!=1)
- {
- f[kk22] = 2;
- continue;
- }
- if(f[kk12] == -1)
- {
- f[kk12] = 0;
- n[3] = 0;
- xx = 0;
- for(k=1; k<8; k=k+2)
- {
- if((!n[k])&&(n[k+1]||n[k+2]))
- xx++;
- }
- if(xx != 1)
- {
- f[kk12] = -1;
- continue;
- }
- f[kk12] = -1;
- n[3] = -1;
- }
- if(f[kk21]!=-1)
- {
- f[kk22] = -1;
- shori = 1;
- continue;
- }
- f[kk21] = 0;
- n[5] = 0;
- xx = 0;
- for(k=1; k<8; k=k+2)
- {
- if((!n[k])&&(n[k+1]||n[k+2]))
- {
- xx++;
- }
- }
- if(xx == 1)
- {
- f[kk21] = -1;
- f[kk22] = -1;
- shori =1;
- }
- else
- f[kk21] = -1;
- }
- }
- }while(shori);
- free(g);
- }
- // 细化算法
- void CDipView::ThinImage(BYTE* image, int width, int height)
- {
- LONG x,y,k;
- BYTE image1[10000];
- k=0;
- LONG digitWidth = width;
- LONG digitHeight = height;
- for(x=0; x<digitWidth; x++)
- {
- image[x*width+0] = (BYTE)0;
- image[x*width+digitHeight-1] = (BYTE)0;
- }
- for(y=0; y<digitHeight; y++)
- {
- image[0*width+y] = (BYTE)0;
- image[(digitWidth-1)*width+y] = (BYTE)0;
- }
- for(x=0; x<digitWidth; x++)
- {
- for(y=0; y<digitHeight; y++)
- {
- image1[k] = image[x*width+y];
- if(image1[k] != 0)
- image1[k] = (BYTE)1;
- k++;
- }
- }
- ThinnerHilditch((void *)image1, digitWidth, digitHeight);
- k=0;
- for(x=0; x<digitWidth; x++)
- {
- for(y=0; y<digitHeight; y++)
- {
- image[x*width+y] = image1[k];
- if(image[x*width+y]!=0)
- image[x*width+y] = (BYTE)1;
- k++;
- }
- }
- }
- // 获取特征值的函数
- void CDipView::GetFeature(BYTE* image, long width, long height, double* feature, int size)
- {
- int i,j;
- for(i=0; i<13; i++)
- feature[i] = 0;
- //图象是20×36大小的,分成9块
- //第一块
- for(i=0; i<7; i++)
- {
- for(j=0; j<12; j++)
- {
- if(image[i*width+j]==1)
- feature[0]+=1.0;
- }
- }
- //第二块
- for(i=0; i<7; i++)
- {
- for(j=12; j<24; j++)
- {
- if(image[i*width+j]==1)
- feature[1]+=1.0;
- }
- }
- //第三块
- for(i=0; i<7; i++)
- {
- for(j=24; j<36; j++)
- {
- if(image[i*width+j]==1)
- feature[2]+=1.0;
- }
- }
- //第四块
- for(i=7; i<13; i++)
- {
- for(j=0; j<12; j++)
- {
- if(image[i*width+j]==1)
- feature[3]+=1.0;
- }
- }
- //第五块
- for(i=7; i<13; i++)
- {
- for(j=12; j<24; j++)
- {
- if(image[i*width+j]==1)
- feature[4]+=1.0;
- }
- }
- //第六块
- for(i=7; i<13; i++)
- {
- for(j=24; j<36; j++)
- {
- if(image[i*width+j]==1)
- feature[5]+=1.0;
- }
- }
- //第七块
- for(i=13; i<20; i++)
- {
- for(j=0; j<12; j++)
- {
- if(image[i*width+j]==1)
- feature[6]+=1.0;
- }
- }
- //第八块
- for(i=13; i<20; i++)
- {
- for(j=12; j<24; j++)
- {
- if(image[i*width+j]==1)
- feature[7]+=1.0;
- }
- }
- //第九块
- for(i=13; i<20; i++)
- {
- for(j=24; j<36; j++)
- {
- if(image[i*width+j]==1)
- feature[8]+=1.0;
- }
- }
- //下面统计方向交点特征
- for(j=0; j<36; j++)
- {
- if(image[7*width+j]==1)
- feature[9]+=1.0;
- }
- for(j=0; j<36; j++)
- {
- if(image[13*width+j]==1)
- feature[10]+=1.0;
- }
- for(i=0; i<20; i++)
- {
- if(image[i*width+12]==1)
- feature[11]+=1.0;
- }
- for(i=0; i<20; i++)
- {
- if(image[i*width+24]==1)
- feature[12]+=1.0;
- }
- }
- // 识别函数,第一个参数为LoadCharLib读出的数组,
- //第二个参数为LoadCharLib的返回值(即样本个数),
- //将上面获得的特征值传入第三个参数,返回为识别结果
- CString CDipView::Recognize(sample* sa, int num, double* feature)
- {
- int j;
- double min=100000.0;
- CString Result;
- for(int i=0;i<num;i++)
- {
- double diff = 0.0;
- for(j=0; j<9; j++)
- {
- diff += fabs(feature[j] - sa[num].feature[j]);
- }
- for(j=9; j<13; j++)
- {
- diff += fabs(feature[j] - sa[num].feature[j])*9;
- }
- if(diff < min)
- {
- min = diff;
- Result.Format("%s",sa[num].trueClass);
- }
- }
- return Result;
- }*/
- // 字符识别
- /*void CDipView::GetCharacter()
- {
- //CDipDoc *pDoc=GetDocument();
- //int width,height;
- //width=pDoc->ImgWidth;
- //height=pDoc->ImgHeight;
- //sample mysa[500];
- // double myfeature[13];
- // int num;
- // CString result[10];
- //BYTE*Img;
- //int row=0;
- //int col=0;
- //int x=-1;
- //int y=-1;
- //int w=0;
- //int h=0;
- //int area=0;
- //for(area=0;area<10;area++);
- //{
- // if(cRects[area].w>0)
- // {
- // x=cRects[area].x;
- // y=cRects[area].y;
- // w=cRects[area].w;
- // h=cRects[area].h;
- // Img=new BYTE[w*h];
- // for(row=0;row<h;row++)
- // {
- // for(col=0;col<w;col++)
- // {
- // // Img[row*w+col]=pDoc->ImgData[y*width+x];
- // }
- // }
- //// //num=LoadCharLib(mysa); //获取样本库保存到mysa[500]中
- //// //Zoom(Img,w,h); //对切割出的图象进行大小归一化
- //// //ThinImage(Img,w,h); //对大小归一化后的图象进行细化
- //// //GetFeature(Img,w,h,myfeature,13); //图象细化以后就可以提取特征了
- //// //result[area]=Recognize(mysa,num,myfeature);
- // }
- //}
- //delete []mysa;
- //delete []myfeature;
- //delete []result;
- }*/
- void CDipView::OnCharacterRecg()
- {
- CMainFrame* MainFrame=(CMainFrame*)this->GetParent()->GetParent();
- CCharView* pchview=(CCharView*)MainFrame->m_wndSplitter.GetPane(0,1);
- CDigitClass digitTest;
- CString classResult;
- CString tempstr;
- CString strInfo, strTemp;
- int recgpos=1;
- for(int k=0;k<CharacterNum;k++)
- {
- if ((float) cDatas[k].h/cDatas[k].w>4)
- {
- if (recgpos!=1&&recgpos<8)
- {
- classResult=classResult+"1";
- recgpos++;
- }
- continue;
- }
- for(int x=0;x<cDatas[k].h;x++)
- {
- for(int y=0;y<cDatas[k].w;y++)
- {
- digitTest.digitarray[y][x]=cDatas[k].Img[x*cDatas[k].w+y];
- }
- }
- digitTest.digitHeight=cDatas[k].h;
- digitTest.digitWidth=cDatas[k].w;
- digitTest.FixSize();
- digitTest.BinaryDigit();
- //digitTest.MarrBinary();
- digitTest.ThinDigit_1();
- pchview->m_result.SetSel(0,-1);
- pchview->m_result.ReplaceSel("");
- CString strInfo, strTemp;
- strInfo.Format("");
- int i,j;
- for(i=0; i<digitTest.digitHeight; i++)
- {
- for(j=0; j<digitTest.digitWidth; j++)
- {
- if(digitTest.digitarray[j][i] == 1)
- strInfo += "■";
- else
- strInfo += " ";
- }
- strInfo += "rn";
- }
- pchview->m_result.SetSel(0,-1);
- pchview->m_result.ReplaceSel(strInfo);
- // AfxMessageBox("hello");
- digitTest.GetFeature();
- if (recgpos==1)
- {
- double min=100000.0;
- POSITION pos=hanList.GetHeadPosition();
- while(pos!=NULL)
- {
- Sample sa;
- sa=hanList.GetNext(pos);
- double diff = 0.0;
- for(j=0; j<9; j++)
- {
- diff += fabs(digitTest.feature[j] - sa.feature[j]);
- }
- for(j=9; j<13; j++)
- {
- diff += fabs(digitTest.feature[j] - sa.feature[j])*9;
- }
- if(diff < min)
- {
- min = diff;
- tempstr.Format("%s",sa.trueClass);
- }
- }
- classResult=classResult+tempstr;
- }
- if (recgpos==2)
- {
- double temp[13];
- double result1[26];
- bool t=0;
- for (i=0;i<13;i++)
- {
- temp[i]=digitTest.feature[i]/15;
- }
- char_bp.Identify(temp,13,result1,26);
- for(i=0;i<26;i++)
- {
- if (ABS(result1[i]-1)<0.1)
- {
- tempstr.Format("%c",i+'A');
- classResult=classResult+tempstr;
- t=1;
- }
- }
- if(t!=1)
- classResult=classResult+'?';
- }
- // strTemp.Format("%d", classResult);
- if (recgpos==3)
- {
- double temp[13];
- double result1[36];
- bool t=0;
- for (i=0;i<13;i++)
- {
- temp[i]=digitTest.feature[i]/15;
- }
- char_num_bp.Identify(temp,13,result1,36);
- for(i=0;i<36;i++)
- {
- if (ABS(result1[i]-1)<0.2)
- {
- if(i<=9)
- {
- tempstr.Format("%c",i+'0');
- classResult=classResult+tempstr;
- t=1;
- }
- else
- {
- tempstr.Format("%c",i+'A'-10);
- classResult=classResult+tempstr;
- t=1;
- }
- // tempstr.Format("%c",i);
- }
- }
- if(t!=1)
- classResult=classResult+'?';
- }
- if (recgpos>3&&recgpos<8)
- {
- double temp[13];
- double result1[10];
- bool t=0;
- for (i=0;i<13;i++)
- {
- temp[i]=digitTest.feature[i]/15;
- }
- char_num_bp.Identify(temp,13,result1,10);
- for(i=0;i<10;i++)
- {
- if (ABS(result1[i]-1)<0.1)
- {
- tempstr.Format("%c",i+'0');
- classResult=classResult+tempstr;
- t=1;
- }
- }
- if(t!=1)
- classResult=classResult+'?';
- }
- // strInfo += "nr识别结果为: ";
- // strInfo += classResult;
- recgpos++;
- // pchview->m_result.SetSel(0,-1);
- // pchview->m_result.ReplaceSel(strInfo);
- }
- strInfo += "nr识别结果为: ";
- strInfo += classResult;
- pchview->m_result.SetSel(0,-1);
- pchview->m_result.ReplaceSel(strInfo);
- }
- void CDipView::OnTrainfromvehicle()
- {
- OnLocate();
- OnVSplit();
- CMainFrame* MainFrame=(CMainFrame*)this->GetParent()->GetParent();
- CCharView* pchview=(CCharView*)MainFrame->m_wndSplitter.GetPane(0,1);
- CDigitClass digitTrain;
- CRecvChar dlg;
- CString m_class;
- for(int k=0;k<CharacterNum;k++)
- {
- for(int x=0;x<cDatas[k].h;x++)
- {
- for(int y=0;y<cDatas[k].w;y++)
- {
- digitTrain.digitarray[y][x]=cDatas[k].Img[x*cDatas[k].w+y];
- }
- }
- digitTrain.digitHeight=cDatas[k].h;
- digitTrain.digitWidth=cDatas[k].w;
- digitTrain.FixSize();
- digitTrain.BinaryDigit();
- digitTrain.ThinDigit_1();
- pchview->m_result.SetSel(0,-1);
- pchview->m_result.ReplaceSel("");
- CString strInfo, strTemp;
- strInfo.Format("");
- int i,j;
- for(i=0; i<digitTrain.digitHeight; i++)
- {
- for(j=0; j<digitTrain.digitWidth; j++)
- {
- if(digitTrain.digitarray[j][i] == 1)
- strInfo += "■";
- else
- strInfo += " ";
- }
- strInfo += "rn";
- }
- pchview->m_result.SetSel(0,-1);
- pchview->m_result.ReplaceSel(strInfo);
- if(dlg.DoModal()==IDOK)
- {
- m_class=dlg.m_char;
- m_class.TrimLeft();
- m_class.TrimRight();
- digitTrain.GetFeature();
- Sample temp;
- for(i=0; i<13; i++)
- temp.feature[i] = digitTrain.feature[i];
- memcpy(temp.trueClass,(const char*) m_class,3*sizeof(char));
- if(temp.trueClass[1]==' ')
- {
- if (temp.trueClass[0]>='0'&&temp.trueClass[0]<='9')
- {
- temp.serialnum=numList.GetCount();
- numList.AddTail(temp);
- }
- if (temp.trueClass[0]>='A'&&temp.trueClass[0]<='Z')
- {
- temp.serialnum=charList.GetCount();
- charList.AddTail(temp);
- }
- }
- else if(temp.trueClass[2]==' ')
- {
- temp.serialnum=hanList.GetCount();
- hanList.AddTail(temp);
- }
- }
- }
- }
- void CDipView::OnSave()
- {
- CFile char_file,num_file,han_file;
- if(char_file.Open(".\chdata.ch",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite)==0)
- {
- AfxMessageBox("打开字符文件失败");
- }
- try
- {
- Sample sampleTemp;
- char_file.SeekToEnd();
- if(char_ConnectPos!=NULL)
- {
- while(char_ConnectPos!=NULL)
- {
- sampleTemp=charList.GetNext(char_ConnectPos);
- char_file.Write(&sampleTemp, sizeof(sample));
- }
- char_ConnectPos=charList.GetTailPosition();
- }
- else
- {
- // Sample sampleTemp;
- POSITION pos=charList.GetHeadPosition();
- while(pos!=NULL)
- {
- sampleTemp=charList.GetNext(pos);
- char_file.Write(&sampleTemp, sizeof(sample));
- }
- char_ConnectPos=charList.GetTailPosition();
- }
- }
- catch(CFileException *e){
- //Alert user to error
- e->Delete();
- }//end try-catch
- char_file.Close();
- if(num_file.Open(".\numdata.num",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite)==0)
- {
- AfxMessageBox("打开数字文件失败");
- }
- try
- {
- Sample sampleTemp;
- num_file.SeekToEnd();
- if(num_ConnectPos!=NULL)
- {
- while(num_ConnectPos!=NULL)
- {
- sampleTemp=numList.GetNext(num_ConnectPos);
- num_file.Write(&sampleTemp, sizeof(sample));
- }
- num_ConnectPos=numList.GetTailPosition();
- }
- else
- {
- // Sample sampleTemp;
- POSITION pos=numList.GetHeadPosition();
- while(pos!=NULL)
- {
- sampleTemp=numList.GetNext(pos);
- num_file.Write(&sampleTemp, sizeof(sample));
- }
- num_ConnectPos=numList.GetTailPosition();
- }
- }
- catch(CFileException *e){
- //Alert user to error
- e->Delete();
- }//end try-catch
- num_file.Close();
- if(han_file.Open(".\handata.han",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite)==0)
- {
- AfxMessageBox("打开汉字文件失败");
- }
- try
- {
- Sample sampleTemp;
- han_file.SeekToEnd();
- if(han_ConnectPos!=NULL)
- {
- while(han_ConnectPos!=NULL)
- {
- sampleTemp=hanList.GetNext(han_ConnectPos);
- han_file.Write(&sampleTemp, sizeof(sample));
- }
- han_ConnectPos=hanList.GetTailPosition();
- }
- else
- {
- // Sample sampleTemp;
- POSITION pos=hanList.GetHeadPosition();
- while(pos!=NULL)
- {
- sampleTemp=hanList.GetNext(pos);
- han_file.Write(&sampleTemp, sizeof(sample));
- }
- han_ConnectPos=hanList.GetTailPosition();
- }
- }
- catch(CFileException *e){
- //Alert user to error
- e->Delete();
- }//end try-catch
- han_file.Close();
- }
- void CDipView::OnLoad()
- {
- if (charList.GetCount()!=0||numList.GetCount()!=0||hanList.GetCount()!=0)
- {
- int nReturn;
- nReturn=
- AfxMessageBox("训练样本不为空,现在读取会覆盖这些样本,确认覆盖吗?",MB_YESNO);
- if(nReturn==IDNO)
- return;
- }
- charList.RemoveAll();
- numList.RemoveAll();
- hanList.RemoveAll();
- CFile char_file,num_file,han_file;
- if(char_file.Open(".\chdata.ch",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite)==0)
- {
- AfxMessageBox("打开字符文件失败,您最好退出程序");
- }
- try
- {
- Sample sampleTemp;
- char_file.SeekToBegin();
- DWORD dwBytesRemaining=char_file.GetLength();
- while(dwBytesRemaining)
- {
- UINT nBytesRead=char_file.Read(&sampleTemp,sizeof(sample));
- charList.AddTail(sampleTemp);
- dwBytesRemaining-=nBytesRead;
- }
- CString s;
- s.Format("共读取字符数据%d个",charList.GetCount());
- AfxMessageBox(s);
- }
- catch(CFileException *e){
- e->ReportError();
- e->Delete();
- }
- char_file.Close();
- char_ConnectPos=charList.GetTailPosition();
- if(num_file.Open(".\numdata.num",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite)==0)
- {
- AfxMessageBox("打开数字文件失败,您最好退出程序");
- }
- try
- {
- Sample sampleTemp;
- num_file.SeekToBegin();
- DWORD dwBytesRemaining=num_file.GetLength();
- while(dwBytesRemaining)
- {
- UINT nBytesRead=num_file.Read(&sampleTemp,sizeof(sample));
- numList.AddTail(sampleTemp);
- dwBytesRemaining-=nBytesRead;
- }
- CString s;
- s.Format("共读取数字数据%d个",numList.GetCount());
- AfxMessageBox(s);
- }
- catch(CFileException *e){
- e->ReportError();
- e->Delete();
- }
- num_file.Close();
- num_ConnectPos=numList.GetTailPosition();
- if(han_file.Open(".\handata.han",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite)==0)
- {
- AfxMessageBox("打开汉字文件失败,您最好退出程序");
- }
- try
- {
- Sample sampleTemp;
- han_file.SeekToBegin();
- DWORD dwBytesRemaining=han_file.GetLength();
- while(dwBytesRemaining)
- {
- UINT nBytesRead=han_file.Read(&sampleTemp,sizeof(sample));
- hanList.AddTail(sampleTemp);
- dwBytesRemaining-=nBytesRead;
- }
- CString s;
- s.Format("共读取汉字数据%d个",hanList.GetCount());
- AfxMessageBox(s);
- }
- catch(CFileException *e){
- e->ReportError();
- e->Delete();
- }
- han_file.Close();
- han_ConnectPos=hanList.GetTailPosition();
- }
- void CDipView::OnChange()
- {
- CFile cf;
- if(cf.Open(".\mydata.dat",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite)==0)
- {
- AfxMessageBox("打开文件失败,n您最好退出程序");
- }
- try
- {
- Sample sampleTemp;
- cf.SeekToBegin();
- DWORD dwBytesRemaining=cf.GetLength();
- while(dwBytesRemaining)
- {
- UINT nBytesRead=cf.Read(&sampleTemp,sizeof(sample));
- if(sampleTemp.trueClass[1]==' ')
- {
- if (sampleTemp.trueClass[0]>='0'&&sampleTemp.trueClass[0]<='9')
- {
- numList.AddTail(sampleTemp);
- }
- if (sampleTemp.trueClass[0]>='A'&&sampleTemp.trueClass[0]<='Z')
- {
- sampleTemp.serialnum=sampleTemp.serialnum-32;
- charList.AddTail(sampleTemp);
- }
- }
- else if(sampleTemp.trueClass[2]==' ')
- {
- sampleTemp.serialnum=sampleTemp.serialnum-48;
- hanList.AddTail(sampleTemp);
- }
- dwBytesRemaining-=nBytesRead;
- }
- // CString s;
- // s.Format("共读取数据%d个,最后一个的序列号为%d",
- // TemplateList.GetCount(),sampleTemp.serialnum);
- // AfxMessageBox(s);
- }
- catch(CFileException *e){
- e->ReportError();
- e->Delete();
- }
- cf.Close();
- }
- void CDipView::OnTrain()
- {
- Sample temp;
- Sample sa;
- double target[36];
- POSITION pos;
- m_pdlg=new CTraining;
- m_pdlg->Create(IDD_TRAINING);
- m_pdlg->m_progress.SetRange32(0,2000);
- m_pdlg->ShowWindow(SW_SHOW);
- for (int num=0;num<2000;num++)
- {
- pos=charList.GetHeadPosition();
- while(pos!=NULL)
- {
- temp=charList.GetNext(pos);
- for(int i=0; i<13; i++)
- sa.feature[i] = temp.feature[i]/15;
- double eo=1,eh=1;
- if(temp.trueClass[1]==' ')
- {
- memset(target,0,36*sizeof(double));
- target[map(&temp.trueClass[0])-10]=1;
- char_bp.Train(sa.feature,13,target,26,&eo,&eh);
- }
- }
- m_pdlg->m_output.SetWindowText("正在训练字母网络,请稍候……");
- m_pdlg->m_progress.SetPos(num);
- }
- // bp.Save("bp.dat");
- for (num=0;num<2000;num++)
- {
- pos=numList.GetHeadPosition();
- while(pos!=NULL)
- {
- temp=numList.GetNext(pos);
- for(int i=0; i<13; i++)
- sa.feature[i] = temp.feature[i]/15;
- double eo=1,eh=1;
- if(temp.trueClass[1]==' ')
- {
- memset(target,0,36*sizeof(double));
- target[map(&temp.trueClass[0])]=1;
- num_bp.Train(sa.feature,13,target,10,&eo,&eh);
- }
- }
- m_pdlg->m_output.SetWindowText("正在训练数字网络,请稍候……");
- m_pdlg->m_progress.SetPos(num);
- }
- // bp.Save("bp.dat");
- for (num=0;num<2000;num++)
- {
- pos=charList.GetHeadPosition();
- while(pos!=NULL)
- {
- temp=charList.GetNext(pos);
- for(int i=0; i<13; i++)
- sa.feature[i] = temp.feature[i]/15;
- double eo=1,eh=1;
- if(temp.trueClass[1]==' ')
- {
- memset(target,0,36*sizeof(double));
- target[map(&temp.trueClass[0])]=1;
- char_num_bp.Train(sa.feature,13,target,36,&eo,&eh);
- }
- }
- pos=numList.GetHeadPosition();
- while(pos!=NULL)
- {
- temp=numList.GetNext(pos);
- for(int i=0; i<13; i++)
- sa.feature[i] = temp.feature[i]/15;
- double eo=1,eh=1;
- if(temp.trueClass[1]==' ')
- {
- memset(target,0,36*sizeof(double));
- target[map(&temp.trueClass[0])]=1;
- char_num_bp.Train(sa.feature,13,target,36,&eo,&eh);
- }
- }
- m_pdlg->m_output.SetWindowText("正在训练字母、数字网络,请稍候……");
- m_pdlg->m_progress.SetPos(num);
- }
- // bp.Save("bp.dat");
- m_pdlg->DestroyWindow();
- }
- int CDipView::map(char *character)
- {
- if(*character>='0'&&*character<='9')
- return *character-'0';
- if(*character>='A'&&*character<='Z')
- return *character-'A'+10;
- }
- void CDipView::OnSavebp()
- {
- char_bp.Save(".\char.bp");
- num_bp.Save(".\num.bp");
- char_num_bp.Save(".\char_num.bp");
- }
- void CDipView::OnReadbp()
- {
- char_bp.Read(".\char.bp");
- num_bp.Read(".\num.bp");
- char_num_bp.Read(".\char_num.bp");
- }
English
