基于VC手写数字识别程序设计_毕业论文设计.docx

上传人:小飞机 文档编号:4957916 上传时间:2023-05-26 格式:DOCX 页数:31 大小:143.09KB
返回 下载 相关 举报
基于VC手写数字识别程序设计_毕业论文设计.docx_第1页
第1页 / 共31页
基于VC手写数字识别程序设计_毕业论文设计.docx_第2页
第2页 / 共31页
基于VC手写数字识别程序设计_毕业论文设计.docx_第3页
第3页 / 共31页
基于VC手写数字识别程序设计_毕业论文设计.docx_第4页
第4页 / 共31页
基于VC手写数字识别程序设计_毕业论文设计.docx_第5页
第5页 / 共31页
点击查看更多>>
资源描述

《基于VC手写数字识别程序设计_毕业论文设计.docx》由会员分享,可在线阅读,更多相关《基于VC手写数字识别程序设计_毕业论文设计.docx(31页珍藏版)》请在三一办公上搜索。

1、基于VC手写数字识别程序设计目录1、摘要12、原理22.1、图像的二值化处理22.2、模板匹配法22.3、图像的特征提取33、系统设计43.1、主界面43.2、图像绘制63.3、特征提取63.4、学习73.5、识别83.6、清除94、系统调试95、心得体会116、参考文献12附录:131、摘要自上世纪六十年代以来,计算机视觉与图像处理越来越受到人们的关注,并逐渐成为一门重要的学科领域。而作为它们的研究对象的数字图像,也因为它含有研究目标的丰富信息而成为越来越重要的研究对象。图像识别的目标是用计算机自动完成某些信息的处理,用来替代人工去处理图像分类及识别的任务。手写数字识别是图像识别学科下的一个

2、分支,是图像处理和模式识别领域研究的课题之一,由于其具有很强的实用性一直是多年来的研究热点。由于手写体数字的随意性很大,例如,笔画的粗细,字体的大小,倾斜等等都直接影响到字符的正确识别,所以手写体数字识别是一个很有挑战性的课题。在过去的数十年中,研究者们提出了许多的识别方法,取得了较大的成果。手写体数字识别实用性很强,在大规模数据统计(如例行年检,人口普查),财务,税务,邮件分拣等等应用领域中都有广阔的应用前景。本课题拟研究手写体数字识别的理论和方法,开发一个小型的手写体数字识别系统。本次设计主要完成以下几个工作:手写数字绘制问题、数字的预处理问题、特征提取问题、特征库的建立问题、数字识别问题

3、。关键词:绘制数字;预处理;特征提取;特征库;数字识别2、原理本次设计主要用到图像的二值化处理、图像特征提取和模板匹配法三个知识点,下面将对这三个知识点进行简单介绍:2.1、图像的二值化处理图像的二值化处理就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果。在手写数字识别系统中,我们在VC可视化编程界面中在一个固定大小的控件中手写了一个数字,在程序中获得的只是以这个控件左上角为原点的一系列坐标。在内存中我们开辟一个大小跟这个控件区域大小相同的二维数组(以像素为单位,即生成一张图片的长跟宽跟这个矩形区域相等),这样内存中图像的数据区域的二维数组就跟手写区域的坐标相

4、同,我们再取出手写区域的坐标值,将这些坐标值对应到图像图像数据区域中,并且将它的灰度值置为255(白色),将图像数据区域的其它坐标值下的灰度值置为0(黑色),这样我们就得到了一张手写数字的二值化图像。在数字图像处理中,二值图像占有非常重要的地位,图像的二值化有利于图像的进一步处理,使图像变得简单,而且数据量减小,能凸显出感兴趣的目标的轮廓。2.2、模板匹配法模板匹配法是图像识别中最具有代表性的方法之一。它是将从待识别的图像提取的若干特征量与模板对应的特征量进行比较,计算图像和模板特征量之间的距离,用最小距离法判定所属类。模板匹配通常事先建立标准模板库。这里,模板库中的标准模板是数字样本的特征向

5、量。具体过程是:对于一个待测试的样本X,计算X和训练集中的某样本Xj(0j程序清单里的特征提取函数,每个特征的提取如图3.3流程图所示:开始求lenth的值求lenend的值求lenfirst的值通过switch语句选出不同水平垂直特征值执行相对应case语句,mytezheng-lenth+1mytezheng-lenth=1求出两个相邻点p和q的距离mytezheng-decon=1,判断相邻两点x、y的大小,分别给出不同的水平垂直特征值0(p1)|(q1)判断1、0两点x、y的大小,分别给出不同的水平垂直特征值mytezheng-lenth=110j=0结束图3.3 特征提取流程图3.4

6、、学习首先点击学习按钮,判断当前写入数值是否已在模板中,随后出现输入学习值对话框,提取特征值,最后存入模板,如图3.4所示:存在不存在结束点击学习按钮判断当前值是否存在模板中显示模板中已存有该值存入模板提取特征值图3.4 学习流程图3.5、识别识别过程就相当于一个查询过程,首先点击识别按钮,然后提取特征值,将特征值与模板一一对比,若有则显示其值,若无则显示无法识别,如图3.5所示:无有显示识别出的值结束显示无法识别逐一对比提取特征值点击识别按钮图3.5 识别流程图3.6、清除清除最为简单,把绘图区域的每个点设置为白点,即二值图像中灰度值都变为255,流程如图3.6所示:结束绘图区每个点设置为白

7、色点击清除按钮图3.6 清除流程图4、系统调试运行程序后,会出现如图所示的图样,然后往绘图区写一个2,然后点击学习按钮,出现如图4.1所示图样,说明所写数字已存在模板中。图4.1 学习调试点击确定后点击清除按钮,再输入一个8,如图4.2所示,这次就跟之前不一样了,说明模板库里没有刚刚写入的数字,然后往两个编辑框里都输入8以后点击OK,这样就完成了学习的功能。图4.2 学习调试点击清除之后,往绘图区写入一个4,如图4.3所示说明识别成功。图4.3 识别调试清除调试只要点击清除按钮,它就会弹出图的样子。识别率如表4.1:数字测试次数正确次数识别率0201680%1201995%2201890%32

8、01890%4201785%5201365%6201680%7201995%820945%9201785%表4.1 识别率统计分析:从表中可以看出8和5较难识别,因为其特征不太好提取,特征比较多样化,所以需要大量的学习,丰富模板库,这样可以提高识别率。5、心得体会本文对基于VC+6.0的手写数字识别系统的基本原理及方法进行了介绍。手写体数字识别是一个极具研究价值的课题,手写数字的样品类别总共只有0一9十类,与其它的大字符集的识别(汉字识别)相比要相对容易。本文所采用的模板匹配分类器既节省时间,简便易行,也可以达到较高地识别效果。但是在系统的设计上由于时间的限制导致系统界面的设计不够美观,特征训

9、练不够导致识别率不够高。手写体数字的特征提取是一个非常复杂的问题,可以考虑在识别的时候使用有监督的识别方法,这样在识别的同时可以更新特征库,这里所说的更新是把导致识别错误的模板替换掉这样出错的几率就会越来越小从而使特征库越来越完善,进一步提高识别的准确度。6、参考文献(1)张立凡等著.手写数字识别系统设计.北京:印刷学院学报,2009年04期.(2)冯伟兴著.Visual C+数字图像模式识别技术详解.北京:机械工业出版社,2010年9月.(3)张宏林著.精通Visual C+数字图像模式识别技术及工程实践.北京:人民邮电出版社,2008年8月.(4)章毓晋著.图像工程(中册)图像分析(第二版

10、).北京:清华大学出版社,2009年7月.(5)谢凤英著.Visual C+ 数字图像处理.北京:电子工业出版社,2008年5月.附录:程序清单:1、初始化程序CPatternView:CPatternView()/ TODO: add construction code heremouseDown=0;/初始化,使得每个点皆为白点for(int i=0;i16;i+)for(int j=0;j16;j+)bitgraphij=0;/初始化,使得坐标序列中的点皆为空点mytime=0;for(i=0;ivalue=-1;mytezheng-lenth=0;mytezheng-lenth1=0;

11、for(i=0;iVHDerectioni=-1;mytezheng-decon=0;/打开保存模板特征量的文件if(cf.Open(mydata.dat,CFile:modeCreate|CFile:modeNoTruncate|CFile:modeReadWrite)=NULL)AfxMessageBox(打开文件失败,n您最好退出程序);2、创建主界面程序void CPatternView:OnDraw(CDC* pDC) CPatternDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/*ASSERT_VALID是一个断定宏,如果pDoc为NU

12、LL就不继续运行*/ TODO: add draw code for native data here/Erase the background/ 创建一个面色刷CBrush Brush (RGB (128, 0 , 0) );/*CBrush是封装了Windows图形设备接口(GDI)中画刷的MFC类,用于构造CBrush对象,然后传给需要画刷的CDC成员函数*/CBrush* pOldBrush = pDC-SelectObject (&Brush);/选择刷到设备上下文/ Get the area that needs to be erased(擦除) .CRect rcClip;/CR

13、ect从tagRECT结构派生而来pDC-GetClipBox (&rcClip);/*该函数得到一个能够完整包含当前可见区域的最小矩形的大小*/Paint the area.pDC- PatBlt (rcClip.left , rcClip.top , rcClip.Width ( ) , rcClip.Height( ) , PATCOPY );/使用当前选入指定设备环境中的刷子绘制给定的矩形区域pDC-SelectObject (pOldBrush );/取消选择刷出设备上下文/三个模拟位图按钮CBitmap bitmapstudy,bitmaprecognize,bitmapclear

14、; /*类CBitmap封装了Windows图形设备接口(GDI)中的位图*/ CDC dcMemory1,dcMemory2,dcMemory3;/*通过CDC对象的成员函数进行所有的绘图*/bitmapstudy.LoadBitmap(IDB_BITMAP_STUDY);/*从模块的可执行文件中加载IDB_BITMAP_STUDY位图资源*/ dcMemory1.CreateCompatibleDC(pDC);/*创建一个与PDC兼容的内存设备上下文环境(DC)*/ dcMemory1.SelectObject(&bitmapstudy);/*选择bitmapstudy到dcMemory1

15、的上下文环境中*/ pDC-BitBlt(220, 20, 50, 20, &dcMemory1, 0, 0, SRCCOPY);/*对&dcMemory1中的像素进行位块转换,以传送到目标设备环境*/ bitmaprecognize.LoadBitmap(IDB_BITMAP_RECOGNIZE); dcMemory2.CreateCompatibleDC(pDC); dcMemory2.SelectObject(&bitmaprecognize); pDC-BitBlt(220, 80, 50, 20, &dcMemory2, 0, 0, SRCCOPY);bitmapclear.Load

16、Bitmap(IDB_BITMAP_CLEAR); dcMemory3.CreateCompatibleDC(pDC); dcMemory3.SelectObject(&bitmapclear); pDC-BitBlt(220, 140, 50, 20, &dcMemory3, 0, 0, SRCCOPY);/画板CBrush BrushBoard (RGB (255, 255 , 255) );/ Select the brush into the device context .pOldBrush = pDC-SelectObject (&BrushBoard);/Paint the ar

17、ea.pDC- PatBlt (8,8,176,240, PATCOPY );/Unselect brush out of device context pDC-SelectObject (pOldBrush );pDC-SetTextColor(RGB(255,255,255);/设置当前环境(HDC)的字体颜色pDC-SetTextAlign(TA_CENTER|TA_TOP);/指定设备环境设置文字对齐标志pDC-SetBkMode(TRANSPARENT);/*TRANSPARENT是使用透明的输出,也就是文字的背景是不改变的*/3、学习程序void CPatternView:OnSt

18、udy(void)/输入数字值的对话框InputDialog inputdlg;cf.SeekToBegin();/定位当前文件指针到文件开头int nFileSize=cf.GetLength();/获取文件长度int i=nFileSize/sizeof(TEZHENG);TEZHENG *temp;temp=(TEZHENG *)malloc(sizeof(TEZHENG);/计算当前画板中数字的特征值GetTeZheng();/首先判断当前的数字类型是否已经在模板中for(int j=0;ji;j+)cf.Read(void *)temp,sizeof(TEZHENG);/从文件cf的

19、当前位置读数据for(int k=0;kVHDerectionk!=mytezheng-VHDerectionk) /判断水平特征break;if(k=15)&(temp-decon=mytezheng-decon)&(temp-lenfirst=mytezheng-lenfirst)&(temp-lenth1=mytezheng-lenth1)&(temp-lenth=mytezheng-lenth)&(temp-lenend=mytezheng-lenend)char s20;sprintf(s,您输入的是:%d,数据已有,temp-value);AfxMessageBox(s);brea

20、k;/说明该数字类型不在模板中if(j=i)if(inputdlg.DoModal()=IDOK)/判断数字输入对话框中的两个数字是否相同if(inputdlg.m_value1!=inputdlg.m_value2)AfxMessageBox(您的输入有误,n请重新输入);/相同,则将新的数字类型写入模板文件中elseGetTeZheng();trymytezheng-value=inputdlg.m_value1;cf.SeekToEnd();/定位当前文件指针到文件尾cf.Write(&mytezheng-value,sizeof(signed char);/将文件数据写入当前文件位置c

21、f.Write(mytezheng-VHDerection,sizeof(signed char)*15);cf.Write(&mytezheng-lenth1,sizeof(signed char);cf.Write(&mytezheng-lenth,sizeof(signed char);cf.Write(&mytezheng-decon,sizeof(signed char);cf.Write(&mytezheng-lenfirst,sizeof(signed char);cf.Write(&mytezheng-lenend,sizeof(signed char);catch(CFile

22、Exception *e)/Alert user to errore-Delete();/end try-catch/end if-else/end if/end ifreturn;4、识别程序void CPatternView:OnRecognize(void) cf.SeekToBegin();int nFileSize=cf.GetLength();int i=nFileSize/sizeof(TEZHENG);TEZHENG *temp;temp=(TEZHENG *)malloc(sizeof(TEZHENG);/计算特征值GetTeZheng();/在模板文件中寻找,是否有与当前特

23、征值相同的for(int j=0;ji;j+)cf.Read(void *)temp,sizeof(TEZHENG);for(int k=0;kVHDerectionk!=mytezheng-VHDerectionk)break;/找到识别结果if(k=15)&(temp-decon=mytezheng-decon)&(temp-lenfirst=mytezheng-lenfirst)&(temp-lenth1=mytezheng-lenth1)&(temp-lenth=mytezheng-lenth)&(temp-lenend=mytezheng-lenend)char s20;sprint

24、f(s,您输入的是:%d,temp-value);AfxMessageBox(s);break;/搜索结束if(j=i)AfxMessageBox(抱歉,无法识别);return;5、清除程序void CPatternView:OnClear(void)CDC *pDC=GetDC();/*检索一指定窗口的客户区域或整个屏幕的显示设备上下文环境的句柄,以后可以在GDI函数中使用该句柄来在设备上下文环境中绘图*/CBrush BrushBoard (RGB (255, 255 , 255) );CBrush pOldBrush;pDC- PatBlt (8,8,176,240, PATCOPY

25、);for(int i=0;i16;i+)for(int j=0;j16;j+)bitgraphij=0;mouseDown=0;mytime=0;for(i=0;ivalue=-1;mytezheng-lenth=0;mytezheng-lenth1=0;for(i=0;iVHDerectioni=-1;mytezheng-decon=0;return;6、特征提取程序void CPatternView:GetTeZheng() int p,q;int i=0;/从第一个点到最后一个点for(int j=0;jlenth1+;if(i=13)AfxMessageBox(内存溢出,呵呵,NUL

26、L,NULL);return;/判断两个相邻点的距离p=(mypointj+1.x-mypointj.x)*(mypointj+1.x-mypointj.x);q=(mypointj+1.y-mypointj.y)*(mypointj+1.y-mypointj.y);/如果不是8连接,则为断裂点或者是写的太快if(p1)|(q1)mytezheng-decon=1;j+;i+;if(j+1mytime-1)AfxMessageBox(您可能写得太快了,呵呵,NULL,NULL);return;if(mypointj+1.xmypointj.x)mytezheng-VHDerectioni=1;

27、else if(mypointj+1.ymypointj.y)mytezheng-VHDerectioni=2;else if(mypointj+1.xVHDerectioni=3;else mytezheng-VHDerectioni=4;mytezheng-lenth=1;/尽量保持目前的方向elseif(j=0)if(mypoint1.xmypoint0.x)mytezheng-VHDerection0=1;else if(mypoint1.ymypoint0.y)mytezheng-VHDerection0=2;else if(mypoint1.xVHDerection0=3;else

28、 mytezheng-VHDerection0=4;mytezheng-lenth=1;/end ifelseswitch(mytezheng-VHDerectioni)case 1:if(mypointj+1.xlenth=1;if(mypointj+1.ymypointj.y)mytezheng-VHDerectioni=2;else if(mypointj+1.yVHDerectioni=4;else mytezheng-VHDerectioni=3;else mytezheng-lenth+;break;case 2:if(mypointj+1.ylenth=1;if(mypointj

29、+1.xVHDerectioni=3;else if(mypointj+1.xmypointj.x)mytezheng-VHDerectioni=1;else mytezheng-VHDerectioni=4;else mytezheng-lenth+;break;case 3:if(mypointj+1.x=mypointj.x)i+;mytezheng-lenth=1;if(mypointj+1.yVHDerectioni=4;else if(mypointj+1.ymypointj.y)mytezheng-VHDerectioni=2;else mytezheng-VHDerection

30、i=1;else mytezheng-lenth+;break;case 4:if(mypointj+1.y=mypointj.y)i+;mytezheng-lenth=1;if(mypointj+1.xmypointj.x)mytezheng-VHDerectioni=1;else if(mypointj+1.xVHDerectioni=3;else mytezheng-VHDerectioni=2;else mytezheng-lenth+;break;default:break;/end switch/end else/end else/end forfor(p=0;p4;p+)for(

31、q=p+1;qmytime;q+)if(mypointp=mypointq)break;if(q=4)mytezheng-lenfirst=2;elsemytezheng-lenfirst=1;for(p=mytime-1;pmytime-6;p-)for(q=p-1;q=0;q-)if(mypointp=mypointq)break;if(q=0)break;if(plenend=2;else mytezheng-lenend=1;if(mytezheng-lenth)0&(mytezheng-lenth)lenth=1;else mytezheng-lenth=2;if(mytezheng

32、-lenth1=4)mytezheng-lenth1=2;else mytezheng-lenth1=1;7、鼠标左键按下程序void CPatternView:OnLButtonDown(UINT nFlags, CPoint point) mouseDown=1;if(point.x=220)&(point.x=20)&(point.y=220)&(point.x=80)&(point.y=220)&(point.x=140)&(point.ySelectClipRgn(&Rgn);/*选择一个区域作为指定设备环境的当前剪切区域*/if(point.x=startX)&(point.x=s

33、tartY)&(point.yLoadStandardCursor(IDC_CROSS);:SetCursor(m_HCross);int i=(point.x-startX)/stepX;int j=(point.y-startY)/stepY;if(mouseDown=1)&(point.x=startX)&(point.x=startY)&(point.ySelectObject (&Brush);pDC-Ellipse(point.x-6,point.y-6,point.x+6,point.y+6);pDC-SelectObject (pOldBrush );/保存数据if(mytime=100)AfxMessageBox(内存溢出(画图时),NULL,NULL);OnClear();if(mytime=0) mypointmytime.x=i;mypointmytime.y=j;ol

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号