进行识别前图像预处理//BP神经网络字符识别函数定义#include "dibapi.h"#include <iostream>#include <deque>#include <math.h>using namespace std;typedef deque<CRect> CRectLink; typedef deque<HDIB> HDIBLink; //声明一些必要的全局变量int w_sample=8;int h_sample=16;bool fileloaded;bool gyhinfoinput;bool gyhfinished;int digicount;int m_lianXuShu;CRectLink m_charRectCopy; CRectLink m_charRect;HDIBLink m_dibRect;HDIBLink m_dibRectCopy;HDIB m_hDIB;CString strPathName;CString strPathNameSave;/********************************functiondeclaration*************************************///清楚屏幕void ClearAll(CDC* pDC);//在屏幕上显示位图void DisplayDIB(CDC* pDC,HDIB hDIB);//对分割后的位图进行尺寸标准归一化void StdDIBbyRect(HDIB hDIB, int tarWidth, int tarHeight); //整体斜率调整void SlopeAdjust(HDIB hDIB);//去除离散噪声点void RemoveScatterNoise(HDIB hDIB);//梯度锐化void GradientSharp(HDIB hDIB);//画框void DrawFrame(CDC* pDC,HDIB hDIB, CRectLink charRect,unsigned int linewidth,COLORREF color);//将灰度图二值化void ConvertGrayToWhiteBlack(HDIB hDIB);//将256色位图转为灰度图void Convert256toGray(HDIB hDIB);//细化void Thinning(HDIB hDIB);//对位图进行分割.返回一个存储着每块分割区域的链表CRectLink CharSegment(HANDLE hDIB);//紧缩、重排调整HDIB AutoAlign(HDIB hDIB);//判断是否是离散噪声点bool DeleteScaterJudge(LPSTR lpDIBBits,WORD lLineBytes, LPBYTE lplab, int lWidth, int lHeight, int x, int y, CPoint lab[], int lianXuShu);//对图像进行模板操作HDIB Template(HDIB hDIB,double * tem ,int tem_w,int tem_h,double xishu);//对图像进行中值滤波HDIB MidFilter(HDIB hDIB,int tem_w,int tem_h);//对图像进行直方图均衡void Equalize(HDIB hDIB);/***********************************implementation************* ************************//***********************************************************************函数名称:DisplayDIB参数:CDC* pDC -指向当前设备上下文(Divice Context)的指针HDIB hDIB -要显示的位图的句柄****************************************************************** ****/void DisplayDIB(CDC* pDC,HDIB hDIB){BYTE* lpDIB=(BYTE*)::GlobalLock((HGLOBAL)hDIB); // 获取DIB宽度和高度int cxDIB = ::DIBWidth((char*) lpDIB);int cyDIB = ::DIBHeight((char*)lpDIB);CRect rcDIB,rcDest;rcDIB.top = rcDIB.left = 0;rcDIB.right = cxDIB;rcDIB.bottom = cyDIB;//设置目标客户区输出大小尺寸rcDest = rcDIB;//CDC* pDC=GetDC();ClearAll(pDC);//在客户区显示图像//for(int ii=0;ii<10;ii++)::PaintDIB(pDC->m_hDC,rcDest,hDIB,rcDIB,NULL); ::GlobalUnlock((HGLOBAL)hDIB);}void ClearAll(CDC *pDC){CRect rect;//GetClientRect(&rect);rect.left =0;rect.top =0;rect.right =2000;rect.bottom=1000;CPen pen;pen.CreatePen (PS_SOLID,1,RGB(255,255,255)); pDC->SelectObject (&pen);pDC->Rectangle (&rect);::DeleteObject (pen);}/********************************************* 函数名称:* AutoAlign()** 参数:* HDIB hDIB -原图像的句柄** 返回值* HDIB -紧缩排列后的新图像的句柄** 功能:* 将经过了标准化处理的字符进行规整的排列,以方便下一步的处理** 说明:* 紧缩排列的操作必须在标准化操作之后进行*********************************************************/HDIB AutoAlign(HDIB hDIB){//指向图像的指针BYTE* lpDIB=(BYTE*)::GlobalLock ((HGLOBAL)hDIB); //指向象素起始位置的指针BYTE* lpDIBBits=(BYTE*)::FindDIBBits ((char*)lpDIB);//指向象素的指针BYTE* lpSrc;//获取图像的宽度LONG lWidth=::DIBWidth ((char*)lpDIB);//获取图像的高度LONG lHeight=::DIBHeight ((char*)lpDIB);//获取标准化的宽度int w=m_charRect.front ().Width() ;//获取标准化的高度int h=m_charRect.front ().Height() ;//建立一个新的图像正好能够将标准化的字符并排放置HDIB hNewDIB=::NewDIB (digicount*w,h,8);//指向新的图像的指针BYTE*lpNewDIB=(BYTE*) ::GlobalLock((HGLOBAL)hNewDIB);//指向象素起始位置的指针BYTE*lpNewDIBBits=(BYTE*)::FindDIBBits((char*)lpNewDIB); //指向象素的指针BYTE* lpDst=lpNewDIBBits;//计算原图像每行的字节数LONG lLineBytes=(lWidth+3)/4*4;//计算新图像每行的字节数LONG lLineBytesnew =(digicount*w+3)/4*4; //将新的图像初始化为白色memset(lpDst,(BYTE)255,lLineBytesnew * h); //映射操作的坐标变量int i_src,j_src;//循环变量int i,j;//统计字符个数的变量int counts=0;//存放位置信息的结构体CRect rect,rectnew;//清空一个新的链表来存放新的字符位置信息m_charRectCopy.clear ();//从头至尾逐个扫描原链表的各个结点while(!m_charRect.empty() ){//从表头上得到一个矩形框rect=m_charRect.front ();//将这个矩形框从链表上删除m_charRect.pop_front ();//计算新的矩形框的位置信息//左边界rectnew.left =counts*w;//右边界rectnew.right =(counts+1)*w;//上边界rectnew.top =0;//下边界rectnew.bottom =h;//将获得的新的矩形框插入到新的链表中m_charRectCopy.push_back (rectnew);//将原矩形框内的象素映射到新的矩形框中for(i=0;i<h;i++){for(j=counts*w;j<(counts+1)*w;j++){//计算映射坐标i_src=rect.top +i;j_src=rect.left +j-counts*w;//进行象素的映射lpSrc=(BYTE *)lpDIBBits + lLineBytes * i_src + j_src; lpDst=(BYTE *)lpNewDIBBits + lLineBytesnew * i + j;*lpDst=*lpSrc;}}//字符个数加1counts++;}//将获得的新的链表复制到原链表中,以方便下一次的调用m_charRect=m_charRectCopy;//解除锁定::GlobalUnlock (hDIB);::GlobalUnlock (hNewDIB);return hNewDIB;}/*************************************************** 函数名称:* ThinnerHilditch** 参数:* void* image -二值化图像矩阵前景色为1背景色为0* unsigned longlx -图像的宽度* unsigned longly -图像的高度** 返回值* 无**函数功能:* 对输入的图像进行细化,输出细化后的图像***********************************************************/ void 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{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;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]&& amp;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[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;}elsef[kk21] = -1;}}}while(shori);free(g);}/*************************************************** 函数名称:* ThinnerRosenfeld** 参数:* void* image -二值化图像矩阵前景色为1背景色为0* unsigned longlx -图像的宽度* unsigned longly -图像的高度** 返回值* 无**函数功能:* 对输入的图像进行细化,输出细化后的图像***********************************************************/void ThinnerRosenfeld(void *image, unsigned long lx, unsigned long ly){char *f, *g;char n[10];char a[5] = {0, -1, 1, 0, 0};char b[5] = {0, 0, 0, 1, -1};char nrnd, cond, n48, n26, n24, n46, n68, n82, n123, n345, n567, n781;short k, shori;unsigned long i, j;long ii, jj, kk, kk1, kk2, kk3, size;size = (long)lx * (long)ly;g = (char *)malloc(size);if(g==NULL){printf("error in alocating mmeory!\n");return;}f = (char *)image;for(kk=0l; kk<size; kk++){g[kk] = f[kk];}do{shori = 0;for(k=1; k<=4; k++){for(i=1; i<lx-1; i++){ii = i + a[k];for(j=1; j<ly-1; j++){kk = i*ly + j;if(!f[kk])continue;jj = j + b[k];kk1 = ii*ly + jj;if(f[kk1])continue;kk1 = kk - ly -1;kk2 = kk1 + 1;kk3 = kk2 + 1;n[3] = f[kk1];n[2] = f[kk2];n[1] = f[kk3];kk1 = kk - 1;kk3 = kk + 1;n[4] = f[kk1];n[8] = f[kk3];kk1 = kk + ly - 1;kk2 = kk1 + 1;kk3 = kk2 + 1;n[5] = f[kk1];n[6] = f[kk2];n[7] = f[kk3];nrnd = n[1] + n[2] + n[3] + n[4] +n[5] + n[6] + n[7] + n[8]; if(nrnd<=1)continue;cond = 0;n48 = n[4] + n[8];n26 = n[2] + n[6];n24 = n[2] + n[4];n46 = n[4] + n[6];n68 = n[6] + n[8];n82 = n[8] + n[2];n123 = n[1] + n[2] + n[3];n345 = n[3] + n[4] + n[5];n567 = n[5] + n[6] + n[7];n781 = n[7] + n[8] + n[1];。