手寫數(shù)字識別系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)樣本_第1頁
手寫數(shù)字識別系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)樣本_第2頁
手寫數(shù)字識別系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)樣本_第3頁
手寫數(shù)字識別系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)樣本_第4頁
手寫數(shù)字識別系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)樣本_第5頁
已閱讀5頁,還剩32頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

手寫數(shù)字辨認(rèn)系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)摘要本手寫數(shù)字辨認(rèn)系統(tǒng)是一種以VISUALSTUDIOC++6.0為編譯環(huán)境,使用MFC進(jìn)行圖形圖像界面開發(fā)系統(tǒng)。重要功能是通過在點(diǎn)擊手寫數(shù)字辨認(rèn)菜單下繪制數(shù)字標(biāo)簽彈出繪制數(shù)字窗口中完畢數(shù)字手寫,在此窗口中可以進(jìn)行數(shù)字保存及清屏,然后通過文獻(xiàn)菜單中打開標(biāo)簽打開所繪制數(shù)字,從而進(jìn)行數(shù)字預(yù)解決,其中涉及灰度化及二值化解決,然后進(jìn)行特性提取,最后實(shí)現(xiàn)數(shù)字辨認(rèn)。本系統(tǒng)界面設(shè)計(jì)和諧,流程對的,功能也較為完善。實(shí)驗(yàn)成果表白,本系統(tǒng)具備較高辨認(rèn)率。核心詞:繪制數(shù)字;預(yù)解決;特性提取;特性庫;數(shù)字辨認(rèn)目錄前言 1概述 21需求分析 41.1功能需求分析 41.2性能需求分析 41.3數(shù)據(jù)需求分析 51.4有關(guān)軟件簡介 52手寫數(shù)字辨認(rèn)系統(tǒng)設(shè)計(jì)與基本原理 62.1系統(tǒng)整體功能模塊設(shè)計(jì) 62.2手寫數(shù)字辨認(rèn)系統(tǒng)基本原理 62.2.1數(shù)字圖像繪制 62.2.2圖像預(yù)解決 62.2.3圖像特性提取 72.2.4特性庫建立 82.2.5圖像數(shù)字辨認(rèn) 83手寫數(shù)字辨認(rèn)系統(tǒng)程序設(shè)計(jì) 83.1數(shù)字圖像繪制 83.2數(shù)字特性提取 153.3模板特性庫建立 183.4數(shù)字辨認(rèn) 20總結(jié) 23道謝 24參照文獻(xiàn) 25前言自上世紀(jì)六十年代以來,計(jì)算機(jī)視覺與圖像解決越來越受到人們關(guān)注,并逐漸成為一門重要學(xué)科領(lǐng)域。而作為它們研究對象數(shù)字圖像,也由于它具有研究目的豐富信息而成為越來越重要研究對象。圖像辨認(rèn)目的是用計(jì)算機(jī)自動(dòng)完畢某些信息解決,用來代替人工去解決圖像分類及辨認(rèn)任務(wù)。手寫數(shù)字辨認(rèn)是圖像辨認(rèn)學(xué)科下一種分支,是圖像解決和模式辨認(rèn)領(lǐng)域研究課題之一,由于其具備很強(qiáng)實(shí)用性始終是近年來研究熱點(diǎn)。由于手寫體數(shù)字隨意性很大,例如,筆畫粗細(xì),字體大小,傾斜等等都直接影響到字符對的辨認(rèn),因此手寫體數(shù)字辨認(rèn)是一種很有挑戰(zhàn)性課題。在過去數(shù)十年中,研究者們提出了許多辨認(rèn)辦法,獲得了較大成果。手寫體數(shù)字辨認(rèn)實(shí)用性很強(qiáng),在大規(guī)模數(shù)據(jù)記錄(如例行年檢,人口普查),財(cái)務(wù),稅務(wù),郵件分揀等等應(yīng)用領(lǐng)域中均有遼闊應(yīng)用前景。本課題擬研究手寫體數(shù)字辨認(rèn)理論和辦法,開發(fā)一種小型手寫體數(shù)字辨認(rèn)系統(tǒng)。在研究手寫體數(shù)字辨認(rèn)理論和辦法基本上,開發(fā)這樣一種小型手寫體數(shù)字辨認(rèn)系統(tǒng)需要完畢如下重要方面研究與設(shè)計(jì)工作:手寫數(shù)字繪制問題、數(shù)字預(yù)解決問題、特性提取問題、特性庫建立問題、數(shù)字辨認(rèn)問題。概述此手寫數(shù)字辨認(rèn)系統(tǒng)需要實(shí)現(xiàn)手寫數(shù)字繪制功能、手寫數(shù)字特性提取功能、數(shù)字模板特性庫建立功能以及手寫數(shù)字辨認(rèn)功能。在近幾年國內(nèi)外對手寫數(shù)字辨認(rèn)系統(tǒng)研究已經(jīng)獲得了進(jìn)展,某些新理論例如基于Hopfield神經(jīng)網(wǎng)絡(luò)、基于小波技術(shù)、基于BP神經(jīng)網(wǎng)絡(luò)以及支持向量機(jī)研究應(yīng)用在建立手寫數(shù)字辨認(rèn)系統(tǒng)平臺,并且在多數(shù)數(shù)據(jù)庫中獲得了較好測試成果。但是當(dāng)前依然存在亟需進(jìn)一步研究解決問題:1)辨認(rèn)精確度需要達(dá)到較好水平2)辨認(rèn)效率要達(dá)到很高水平。數(shù)字辨認(rèn)輸入數(shù)據(jù)普通是很大,而高精度與高速度是互相矛盾。這些難點(diǎn)存在因素是:1)數(shù)字筆劃簡樸,并且其筆劃差別相對較小,字形相差不大,使得精確區(qū)別某些數(shù)字有某些困難;2)數(shù)字雖然只有10種,且筆劃簡樸,但同一數(shù)字寫法卻千差萬別,全世界各個(gè)國家各個(gè)地區(qū)人都在用,則其書寫上帶有區(qū)域特性,很難做出可以兼顧世界各種寫法、辨認(rèn)率極高通用性數(shù)字辨認(rèn)系統(tǒng)。3)特性庫訓(xùn)練不夠,導(dǎo)致辨認(rèn)率不高。手寫數(shù)字辨認(rèn)研究不但存在很大應(yīng)用價(jià)值,由于手寫數(shù)字辨認(rèn)自身特點(diǎn),對它研究也存在著重要理論價(jià)值:1)阿拉伯?dāng)?shù)字作為唯一被世界各國通用符號,因此對手寫體數(shù)字辨認(rèn)研究基本上與文化背景無關(guān),各地研究工作者可以說是基于同一平臺開展工作,有助于研究比較和探討。2)手寫數(shù)字辨認(rèn)應(yīng)用廣泛,如稅表系統(tǒng),銀行支票自動(dòng)解決和郵政編碼自動(dòng)辨認(rèn)等。在此前,這些工作需要大量手工錄入,投入人力物力都相對較多,并且勞動(dòng)強(qiáng)度較大。為了適應(yīng)無紙化辦公需要,大大提高工作效率,研究實(shí)現(xiàn)手寫數(shù)字辨認(rèn)系統(tǒng)是必要要做。3)由于數(shù)字類別只有0-9共10個(gè),比其她字符辨認(rèn)率較高,可將其用于驗(yàn)證新理論或做進(jìn)一步分析研究。許多機(jī)器學(xué)習(xí)和模式辨認(rèn)領(lǐng)域新理論和算法都是先用手寫數(shù)字辨認(rèn)進(jìn)行檢查,驗(yàn)證其理論有效性,然后才會將其應(yīng)用到更為復(fù)雜領(lǐng)域當(dāng)中。在這方面典型例子就是人工神經(jīng)網(wǎng)絡(luò)和支持向量機(jī)。4)手寫數(shù)字辨認(rèn)辦法很容易將其推廣到其他某些有關(guān)問題上,如對英文之類拼音文字辨認(rèn)。事實(shí)上,有許多學(xué)者就是把數(shù)字和英文字母辨認(rèn)放在一起研究。在過去數(shù)幾年中,研究者提出了許許多多辨認(rèn)辦法,按提取數(shù)字特性不同,可以將這些辦法分為兩類:基于構(gòu)造特性辦法和基于記錄特性辦法。記錄特性普通涉及點(diǎn)密度測量、矩、特性區(qū)域等;構(gòu)造特性普通涉及圓、端點(diǎn)、交叉點(diǎn)、筆劃、輪廓等,普通來說,兩類特性各有優(yōu)勢。例如,使用記錄特性分類器易于訓(xùn)練,并且對于使用記錄特性分類器,在給定訓(xùn)練集上可以得到相對較高辨認(rèn)率;而構(gòu)造特性重要長處之一是能描述字符構(gòu)造,在辨認(rèn)過程中能有效地結(jié)合幾何和構(gòu)造知識,因而可以得到可靠性較高辨認(rèn)成果。在本次設(shè)計(jì)中使用是記錄特性?;谝陨纤?,本次畢業(yè)設(shè)計(jì)課題為手寫數(shù)字辨認(rèn)系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)。其功能是將人工手繪數(shù)字圖像轉(zhuǎn)換成可編輯文本信息。該系統(tǒng)涉及手寫數(shù)字繪制模塊、圖像預(yù)解決模塊、特性提取模塊、訓(xùn)練模塊和辨認(rèn)模塊。涉及模式辨認(rèn)、圖像解決、人工智能、記錄學(xué)、心理學(xué)和計(jì)算機(jī)科學(xué)等有關(guān)內(nèi)容。通過對圖像解決和辨認(rèn)算法進(jìn)行不斷地研究和實(shí)踐,以減少誤識率和拒識率。本文重要簡介手寫數(shù)字辨認(rèn)系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn),一方面需要理解手寫數(shù)字辨認(rèn)系統(tǒng)現(xiàn)階段發(fā)展?fàn)顩r和研究現(xiàn)狀,然后對系統(tǒng)進(jìn)行分析,重要從功能需求分析、性能需求分析、數(shù)據(jù)需求分析和有關(guān)軟件簡介四方面入手,從而使得對系統(tǒng)有初步結(jié)識,然后對系統(tǒng)整體設(shè)計(jì)模塊進(jìn)行簡介,進(jìn)而對系統(tǒng)各個(gè)功能模塊詳細(xì)設(shè)計(jì)原理進(jìn)行詳細(xì)簡介,之后對本次所設(shè)計(jì)出系統(tǒng)進(jìn)行簡介并對有關(guān)代碼進(jìn)行闡明,最后總結(jié)本系統(tǒng)優(yōu)缺陷及此后工作展望等,整篇文章通俗易懂,條理清晰,可以使讀者輕松閱讀,并理解實(shí)現(xiàn)過程。1需求分析綜合顧客在實(shí)際應(yīng)用中需求,對系統(tǒng)運(yùn)作流程進(jìn)行了整頓,并通過對流程分析得出了如下需求分析。1.1功能需求分析依照對顧客需求分析,系統(tǒng)應(yīng)包括如下功能:數(shù)字繪制在繪制數(shù)字窗口中實(shí)現(xiàn)數(shù)字手寫,并對其坐標(biāo)值進(jìn)行保存,運(yùn)用復(fù)位按鈕可實(shí)現(xiàn)數(shù)字清除工作。數(shù)字預(yù)解決在手寫數(shù)字圖像辨認(rèn)系統(tǒng)中,圖像預(yù)解決跟普通圖像系統(tǒng)不同,咱們不需要對圖像進(jìn)行灰度化解決、去噪解決等基本操作,咱們運(yùn)用程序保存坐標(biāo)值就可以對生成一張二值化圖像,相稱于圖像解決系統(tǒng)二值化解決。特性提取在第二步中咱們得到了手寫數(shù)字二值化圖像,進(jìn)行特性提取前需要對此圖像數(shù)據(jù)區(qū)域進(jìn)行定位,在程序中咱們遍歷此二值化圖像,找到手寫數(shù)字區(qū)域上、下、左、右邊界,重新生成一張數(shù)字圖片,運(yùn)用新生成數(shù)字圖片提成8*8區(qū)域,記錄每個(gè)區(qū)域目的像素個(gè)數(shù)和整個(gè)社區(qū)域像素個(gè)數(shù),計(jì)算目的像素個(gè)數(shù)與整個(gè)社區(qū)域像素比值,得到64個(gè)特性值,作為這個(gè)手寫數(shù)字特性值。特性庫訓(xùn)練咱們需要訓(xùn)練一種特性庫,作為辨認(rèn)原則。系統(tǒng)中咱們手寫一種數(shù)字提取出它特性值,再輸入此手寫數(shù)字,將數(shù)字與這些特性值相相應(yīng)存儲到特性庫里面,特性庫咱們使用是Access數(shù)據(jù)庫,字段是數(shù)字及這個(gè)數(shù)字所相應(yīng)所有特性值。特性庫越豐富,辨認(rèn)率越高。數(shù)字辨認(rèn)在手寫數(shù)字辨認(rèn)中,咱們用法是模板匹配法,其實(shí)質(zhì)就是提取出手寫數(shù)字特性值,運(yùn)用這些特性值與特性庫數(shù)字特性值進(jìn)行比對,找出待辨認(rèn)數(shù)字特性值與特性庫里存儲特性值最接近數(shù)字,作為辨認(rèn)成果。1.2性能需求分析對的性:依照手寫數(shù)字辨認(rèn)系統(tǒng)設(shè)計(jì)流程,流程中每個(gè)環(huán)節(jié)在系統(tǒng)中都必要有所體現(xiàn),以保證程序?qū)Φ男?。精?zhǔn)性:依照手寫數(shù)字辨認(rèn)系統(tǒng)應(yīng)用領(lǐng)域,該系統(tǒng)辨認(rèn)成果必要有很高辨認(rèn)精度,這樣才干真正實(shí)現(xiàn)該系統(tǒng)價(jià)值。效率性:依照該系統(tǒng)應(yīng)用領(lǐng)域可知,系統(tǒng)一旦投入應(yīng)用需要解決大量數(shù)據(jù),因此對系統(tǒng)解決速度也有很高規(guī)定。1.3數(shù)據(jù)需求分析依照手寫數(shù)字辨認(rèn)系統(tǒng)設(shè)計(jì)環(huán)節(jié)可知該系統(tǒng)采用是模板匹配法進(jìn)行手寫體數(shù)字辨認(rèn)。模板匹配法是圖像辨認(rèn)中最具備代表性辦法之一。它是將從待辨認(rèn)圖像提取若干特性量與模板相應(yīng)特性量進(jìn)行比較,計(jì)算圖像和模板特性量之間距離,用最小距離法鑒定所屬類。而模板匹配普通需要事先建立原則模板庫。這里,模板庫中原則模板是數(shù)字樣本特性向量。特性庫存儲是運(yùn)用Access數(shù)據(jù)庫,并且運(yùn)用MFCADO技術(shù)連接數(shù)據(jù)庫,不需要進(jìn)行硬件配備。數(shù)據(jù)庫如圖1.1所示。圖1.1數(shù)據(jù)庫1.4有關(guān)軟件簡介本課題是基于VisualC++6.0,它是Microsoft公司開發(fā)VisualStudio集成開發(fā)環(huán)境中功能最為強(qiáng)大、代碼效率最高開發(fā)工共。運(yùn)用VisualC++6.0可以兩種方式編寫Win32應(yīng)用程序,一種方式是基于WindowsAPIC編程方式,另一種是基于MFCC++編程方式。本系統(tǒng)采用是基于MFC編程方式。2手寫數(shù)字辨認(rèn)系統(tǒng)設(shè)計(jì)與基本原理2.1系統(tǒng)整體功能模塊設(shè)計(jì)整體模塊如圖2.1所示:數(shù)字圖像繪制數(shù)字圖像繪制訓(xùn)練特性庫二值化解決特性提取數(shù)字辨認(rèn)主界面圖2.1整體模塊2.2手寫數(shù)字辨認(rèn)系統(tǒng)基本原理下面分別簡介各某些工作基本原理:2.2.1數(shù)字圖像繪制手寫數(shù)字繪制功能實(shí)現(xiàn)方案是:通過VisualC++中CStatic控件來建立畫布,用MFC中封裝類CDC實(shí)現(xiàn)手寫數(shù)字功能。在對話框中,響應(yīng)鼠標(biāo)事件消息,分別是鼠標(biāo)按下事件MouseDown,鼠標(biāo)移動(dòng)事件MouseMove,鼠標(biāo)抬起事件MouseUp,判斷當(dāng)前鼠標(biāo)點(diǎn)與否在CStatic控件上,在話程序?qū)⒋它c(diǎn)坐標(biāo)值保存。手寫數(shù)字繪制開始是鼠標(biāo)按下事件,結(jié)束是以左鼠標(biāo)抬起為標(biāo)志。2.2.2圖像預(yù)解決圖像預(yù)解決是為了突出手寫體數(shù)字特性。在本次設(shè)計(jì)中重要涉及:圖像二值化解決。圖像二值化解決就是將圖像上像素點(diǎn)灰度值設(shè)立為0或255,也就是將整個(gè)圖像呈現(xiàn)出明顯黑白效果。在手寫數(shù)字辨認(rèn)系統(tǒng)中,咱們在VC可視化編程界面中在一種固定大小控件中手寫了一種數(shù)字,在程序中獲得只是以這個(gè)控件左上角為原點(diǎn)一系列坐標(biāo)。在內(nèi)存中咱們開辟一種大小跟這個(gè)控件區(qū)域大小相似二維數(shù)組(以像素為單位,即生成一張圖片長跟寬跟這個(gè)矩形區(qū)域相等),這樣內(nèi)存中圖像數(shù)據(jù)區(qū)域二維數(shù)組就跟手寫區(qū)域坐標(biāo)相似,咱們再取出手寫區(qū)域坐標(biāo)值,將這些坐標(biāo)值相應(yīng)到圖像圖像數(shù)據(jù)區(qū)域中,并且將它灰度值置為255(白色),將圖像數(shù)據(jù)區(qū)域其他坐標(biāo)值下灰度值置為0(黑色),這樣咱們就得到了一張手寫數(shù)字二值化圖像。在數(shù)字圖像解決中,二值圖像占有非常重要地位,圖像二值化有助于圖像進(jìn)一步解決,使圖像變得簡樸,并且數(shù)據(jù)量減小,能凸顯出感興趣目的輪廓。2.2.3圖像特性提取若直接把預(yù)解決后數(shù)據(jù)作為輸入量,進(jìn)行分類計(jì)算時(shí)數(shù)據(jù)時(shí)數(shù)據(jù)量大,同步由于手寫字體多樣化及圖像自身和預(yù)解決過程中附帶某些干擾影響,對系統(tǒng)容錯(cuò)能力規(guī)定較高。特性提取目就是從分析數(shù)字拓?fù)錁?gòu)造入手,把它某些構(gòu)造特性提取出來,使數(shù)字位移、大小變化、字形畸形等干擾相對較小,也就是把那些反映數(shù)字特性核心信息提供應(yīng)系統(tǒng),這樣就等于間接地增長了系統(tǒng)容錯(cuò)能力,并且通過特性提取后數(shù)據(jù)量也大大減少了,這樣就提高了辨認(rèn)效率。手寫數(shù)字辨認(rèn)特性提取極大限度地影響著分類器設(shè)計(jì)和性能,以及辨認(rèn)效果和效率。為了保證所規(guī)定分類辨認(rèn)對的率和節(jié)約資源,但愿根據(jù)至少特性達(dá)到所規(guī)定分類辨認(rèn)對的率。在進(jìn)行手寫數(shù)字辨認(rèn)過程中,特性提取應(yīng)遵循如下原則:特性應(yīng)能盡量包括字符有用信息。特性提取辦法應(yīng)簡樸并且提取迅速。各個(gè)特性之間有關(guān)性應(yīng)盡量小。特性數(shù)量盡量少。特性應(yīng)有較好抗干擾能力??紤]到算法實(shí)時(shí)性、迅速性和精確性,在本次設(shè)計(jì)中采用是一種簡樸模板法對待測樣本進(jìn)行特性提取。環(huán)節(jié)為:1、搜索數(shù)據(jù)區(qū)域,找出手寫體數(shù)字上下左右邊界。2、將搜索到數(shù)字區(qū)域平提成8*8共64個(gè)社區(qū)域。3、計(jì)算8*8每一種社區(qū)域中白色像素所占比例,即用每一種社區(qū)域內(nèi)白色像素個(gè)數(shù)除以該社區(qū)域面積總數(shù)(總像素?cái)?shù)),即得特性值,第一行8個(gè)比例值是特性前8特性值,第二行相應(yīng)著特性9~16個(gè),以此類推。2.2.4特性庫建立在手寫數(shù)字辨認(rèn)系統(tǒng)中,咱們一方面要建立一種特性庫,咱們手寫一種數(shù)字,并且獲得這個(gè)數(shù)字特性值,然后再想程序輸入這個(gè)數(shù)字,在程序中將此輸入數(shù)字與所有特性值相相應(yīng),作為模板庫一條記錄,初始化模板庫之后,就可以對手寫數(shù)字進(jìn)行辨認(rèn),在辨認(rèn)過程中咱們不斷豐富模板庫,如果手寫數(shù)字辨認(rèn)成功則不需要將此數(shù)字存儲到模板庫中,如果辨認(rèn)失敗就需要將此數(shù)字存儲到模板庫中,這樣咱們模板庫將越來越豐富。2.2.5圖像數(shù)字辨認(rèn)在手寫數(shù)字圖像特性提取結(jié)束后,即可進(jìn)行數(shù)字辨認(rèn)。這也是手寫數(shù)字辨認(rèn)系統(tǒng)設(shè)計(jì)最后一種環(huán)節(jié),在本次設(shè)計(jì)中采用模板匹配法進(jìn)行手寫體數(shù)字辨認(rèn)。模板匹配法是圖像辨認(rèn)中最具備代表性辦法之一。它是將從待辨認(rèn)圖像提取若干特性量與模板相應(yīng)特性量進(jìn)行比較,計(jì)算圖像和模板特性量之間距離,用最小距離法鑒定所屬類。模板匹配普通事先建立原則模板庫。這里,模板庫中原則模板是數(shù)字樣本特性向量。詳細(xì)過程是:對于一種待測試樣本X,計(jì)算X和訓(xùn)練集中某樣本Xj(0<j<m,m為訓(xùn)練集中樣本數(shù))之間距離。循環(huán)計(jì)算待測樣本和訓(xùn)練集中各已知樣本之間距離,比較所有距離值,找出距離待測樣本近來已知樣本,其中所相應(yīng)樣本所屬類別就是待測樣本X所屬類別。3手寫數(shù)字辨認(rèn)系統(tǒng)程序設(shè)計(jì)本次設(shè)計(jì)使用VisualC++語言來實(shí)現(xiàn)該系統(tǒng),其顧客界面分別簡介如下:3.1數(shù)字圖像繪制運(yùn)營程序后得到系統(tǒng)初始界面,如圖3.1所示。在繪圖區(qū)域通過響應(yīng)鼠標(biāo)事件來完畢手寫數(shù)字繪制問題,如圖3.2所示,通過 CPen創(chuàng)立對象pen并進(jìn)行有關(guān)值設(shè)立如pen(PS_SOLID,3,RGB(0,0,255))可以創(chuàng)立出不同顏色和粗細(xì)畫筆,消息響應(yīng)事件是通過函數(shù)OnLButtonDown(UINTnFlags,CPointpoint)、OnMouseMove(UINTnFlags,CPointpoint)、OnLButtonUp(UINTnFlags,CPointpoint)來實(shí)現(xiàn)。手寫數(shù)字繪制過程中通過建立堆棧即可實(shí)現(xiàn)手寫數(shù)字保存,所用函數(shù)為AddPointStack(constCPoint&point)。繪制數(shù)字后還可以對所繪制數(shù)字進(jìn)行清除,通過函數(shù)OnButtonRset()即可實(shí)現(xiàn),點(diǎn)擊系統(tǒng)會面上復(fù)位按鈕即可實(shí)現(xiàn)此功能。點(diǎn)擊顯示按鈕即可得到二值化后黑白圖像,如圖3.3所示。圖3.1系統(tǒng)初始界面圖3.2手寫數(shù)字繪制圖3.3二值化成果詳細(xì)實(shí)當(dāng)代碼為:1.手寫數(shù)字繪制voidCNumShiBieDlg::OnLButtonDown(UINTnFlags,CPointpoint){ CRectrect,rect1,rect2; CStringstr; this->GetClientRect(rect); m_ctlDrawNum.GetClientRect(rect1);//這個(gè)函數(shù)獲得坐標(biāo)是相對于屏幕左上角而言,此矩形保存值都是相對于屏幕左上角而言 //m_DrawNum.GetClientRect(rect2);//此函數(shù)坐標(biāo)是相對于本窗體客戶區(qū)而言,左上角坐標(biāo)為(0,0) ::ClientToScreen(this->m_hWnd,&point); ::ScreenToClient(m_ctlDrawNum.m_hWnd,&point);//注意這里轉(zhuǎn)換,先將窗口坐標(biāo)轉(zhuǎn)換成屏幕坐標(biāo),再將此坐標(biāo)轉(zhuǎn)換成畫圖控件坐標(biāo)系統(tǒng), str.Format("%d%d",point.x,point.y); //這樣得到點(diǎn)就是以畫圖控件為坐標(biāo)系統(tǒng)了,既是左上角(0,0)開始,到(w,h) if(rect1.PtInRect(point)) { bBegin=true;//此參數(shù)擬定手寫數(shù)字開始 this->AddPointStack(point);//將數(shù)字開始點(diǎn)保存到堆棧中,相稱于保存是數(shù)字像素點(diǎn)在原始圖像中坐標(biāo)值 //AfxMessageBox(str); } CDialog::OnLButtonDown(nFlags,point);}voidCNumShiBieDlg::OnMouseMove(UINTnFlags,CPointpoint){ //TODO:Addyourmessagehandlercodehereand/orcalldefault CRectrect; CStringstr; m_ctlDrawNum.GetClientRect(rect); ::ClientToScreen(m_hWnd,&point); ::ScreenToClient(m_ctlDrawNum.m_hWnd,&point); str.Format("%d%d",point.x,point.y); CPenpen(PS_SOLID,3,RGB(0,0,255)); pDC=m_ctlDrawNum.GetDC(); CPen*pOldPen; pOldPen=pDC->SelectObject(&pen); if(rect.PtInRect(point)&&bBegin) { if(this->AddPointStack(point)) { CPointbefPoint=*(stuPoint.p+stuPoint.cur-2); CPointcurPoint=*(stuPoint.p+stuPoint.cur-1); pDC->MoveTo(befPoint.x,befPoint.y); pDC->LineTo(curPoint.x,curPoint.y); } } CDialog::OnMouseMove(nFlags,point);}voidCNumShiBieDlg::OnLButtonUp(UINTnFlags,CPointpoint){ //TODO:Addyourmessagehandlercodehereand/orcalldefault CRectrect; m_ctlDrawNum.GetClientRect(rect); ::ClientToScreen(this->m_hWnd,&point); ::ScreenToClient(m_ctlDrawNum.m_hWnd,&point); if(rect.PtInRect(point)) { bBegin=false; if(this->AddPointStack(point)) { CPointbefPoint=*(stuPoint.p+stuPoint.cur-2); CPointcurPoint=*(stuPoint.p+stuPoint.cur-1); pDC->MoveTo(befPoint.x,befPoint.y); pDC->LineTo(curPoint.x,curPoint.y); } } CDialog::OnLButtonUp(nFlags,point);}2.手寫數(shù)字存儲boolCNumShiBieDlg::AddPointStack(constCPoint&point){ CStringstr; boolb=false; if(stuPoint.cur!=stuPoint.size) { *(stuPoint.p+stuPoint.cur)=point; stuPoint.cur+=1;//cur指向是最后一種結(jié)點(diǎn)后一種空結(jié)點(diǎn) b=true; } else { b=false; AfxMessageBox("棧滿溢出"); } returnb;}3.手寫數(shù)字清除voidCNumShiBieDlg::OnButtonRset(){ //TODO:Addyourcontrolnotificationhandlercodehere this->Invalidate(); stuPoint.cur=0; if(stuPoint.p!=NULL) deletestuPoint.p; stuPoint.p=newCPoint[stuPoint.size];}4.二值化后顯示voidCNumShiBieDlg::OnButtonShownum(){ //TODO:Addyourcontrolnotificationhandlercodehere CRectrect; m_ctlDrawNum.GetClientRect(rect); intw=0,h=0; w=rect.Width(); h=rect.Height(); if(w%4!=0) w=w+4-w%4;//按位補(bǔ)齊,寬一定要是4倍數(shù)//windows下規(guī)定,位圖行像素個(gè)數(shù)必要是4倍數(shù) intxleft=w,ytop=h,xrigth=0,ybottom=0; for(inti1=0;i1<stuPoint.cur;i1++) { CPointpoint; point=*(stuPoint.p+i1); if(xleft>point.x) xleft=point.x; if(ytop>point.y) ytop=point.y; if(xrigth<point.x) xrigth=point.x; if(ybottom<point.y) ybottom=point.y; }//這個(gè)循環(huán)之后,xleft記錄了手寫數(shù)字區(qū)域最左邊像素點(diǎn)x坐標(biāo),ytop記錄了最上邊像素點(diǎn)y坐標(biāo) //xrigth記錄了最右邊點(diǎn)x坐標(biāo),ybottom記錄了最下邊點(diǎn)y坐標(biāo),這樣就可以得到數(shù)字區(qū)域?qū)捀L,以像素為單位 unsignedchar*pdata=newunsignedchar[w*h*3]; ::memset(pdata,0,w*h*3); for(inti=0;i<stuPoint.cur;i++) { CPointpoint=*(stuPoint.p+i); intx=point.x; inty=point.y; pdata[(y*w+x)*3]=255; pdata[(y*w+x)*3+1]=255; pdata[(y*w+x)*3+2]=255;//注意坐標(biāo)變量y才是表達(dá)圖像第幾行像素 } //鼠標(biāo)走過點(diǎn)坐標(biāo)值即是數(shù)字像素在數(shù)據(jù)矩陣中坐標(biāo)值,這樣咱們把鼠標(biāo)走過所有坐標(biāo)值相應(yīng)到圖像數(shù)據(jù)坐標(biāo)值中灰度值設(shè)立成255,而背景色置為白 //這樣相稱于,將手寫數(shù)字區(qū)域當(dāng)成一張數(shù)字圖片,將其從第一行到最后一行數(shù)據(jù)順序讀到內(nèi)存中,因此咱們顯示時(shí),一定要將此圖片數(shù)據(jù)區(qū)域按行轉(zhuǎn)置 unsignedchar*ppdata=newunsignedchar[w*h*3]; ::memcpy(ppdata,pdata,w*h*3); for(i=0;i<h;i++) for(intj=0;j<w;j++) { ppdata[((h-i-1)*w+j)*3]=pdata[(i*w+j)*3]; ppdata[((h-i-1)*w+j)*3+1]=pdata[(i*w+j)*3+1]; ppdata[((h-i-1)*w+j)*3+2]=pdata[(i*w+j)*3+2]; }//注意,windows中普通位圖是倒向位圖,也就是說咱們實(shí)際看到圖像中,第一行像素值在文獻(xiàn)中存儲在位圖數(shù)據(jù)區(qū)域最后一行,而最后一行像素在位圖//文獻(xiàn)數(shù)據(jù)區(qū)域矩陣中是存儲在第一行,因此平時(shí)咱們讀取了一種位圖之后,讀取到像素值,與咱們實(shí)際看到圖像像素是按行倒置 //并且當(dāng)咱們用StretchDibits函數(shù)顯示位圖時(shí),數(shù)據(jù)區(qū)域指針一定要給成按行倒置位圖數(shù)據(jù)矩陣 xleft=xleft-1; ytop=ytop-1; xrigth=xrigth+1; ybottom=ybottom+1;//將四周擴(kuò)展了一排像素 nw=xrigth-xleft+1; nh=ybottom-ytop+1; if(nw%4!=0) nw=nw+4-nw%4; unsignedchar*pnum=newunsignedchar[nw*nh]; pnumzheng=newunsignedchar[nw*nh]; ::memset(pnum,0,nw*nh); for(i=0;i<stuPoint.cur;i++) { CPointpoint; point=*(stuPoint.p+i); intx,y; x=point.x-xleft; y=point.y-ytop;//(xleft,ytop)相稱于生成手寫數(shù)字區(qū)域矩形最左上角坐標(biāo),這里完畢了坐標(biāo)系統(tǒng)轉(zhuǎn)換 pnum[y*nw+x]=255; //pnum[(y*nw+x)*3+1]=255; //pnum[(y*nw+x)*3+2]=255; } for(i=0;i<nh;i++) for(intj=0;j<nw;j++) { pnumzheng[(nh-i-1)*nw+j]=pnum[i*nw+j];//8bit級圖像指針 //pnumzheng[((nh-i-1)*nw+j)*3+1]=pnum[(i*nw+j)*3+1]; //pnumzheng[((nh-i-1)*nw+j)*3+2]=pnum[(i*nw+j)*3+2]; } BYTE*p=BitTo24Bit(pnumzheng,nw,nh); binfo.biSize=sizeof(BITMAPINFOHEADER);binfo.biWidth=nw;binfo.biHeight=nh; binfo.biPlanes=1;binfo.biBitCount=24;binfo.biCompression=BI_RGB; binfo.biSizeImage=nw*nh*3; binfo.biXPelsPerMeter=0; binfo.biYPelsPerMeter=0;binfo.biClrUsed=0;binfo.biClrImportant=0; HDChdc=::GetDC(m_ctlShowNum.m_hWnd); ::SetStretchBltMode(hdc,HALFTONE); ::StretchDIBits(hdc, 0,0, nw,nh, 0,0, nw, nh, p, (LPBITMAPINFO)&binfo, DIB_RGB_COLORS, SRCCOPY );}3.2數(shù)字特性提取數(shù)字特性提取是為了更好實(shí)現(xiàn)數(shù)字辨認(rèn),在此是通過提取所繪制數(shù)字像素特性即如前面所簡介用目的像素個(gè)數(shù)除以這個(gè)社區(qū)域內(nèi)總得像素個(gè)數(shù)成果作為此區(qū)域特性值,共可得到64個(gè)特性值。在此通過在函數(shù)Get64Feature(BYTE*pd,intw,inth)中調(diào)用函數(shù)GetOneFeature(intbrow,interow,intbcol,intecol,BYTE*pdata,intw)來實(shí)現(xiàn)數(shù)字特性提取功能。詳細(xì)實(shí)當(dāng)代碼為:1.得到64個(gè)區(qū)域特性值double*CNumShiBieDlg::Get64Feature(BYTE*pd,intw,inth){ double*pFeature=newdouble[64]; if((w%8==0)&&(h%8==0)) { inthc=h/8; intwc=w/8; intjishu=0; intj=0;//列方向上共8個(gè)單元格 while(j<8)//j=0闡明是第一行單元格像素,依次類推 { intcc=0;//記錄一行方格內(nèi)單元格個(gè)數(shù),共8個(gè)方格因此循環(huán)8次 while(cc<8) { pFeature[jishu++]=this->GetOneFeature(j*hc,(j+1)*hc,cc*wc,(cc+1)*wc,pd,w); cc++;//此時(shí)已經(jīng)記錄完一種單元格像素 } j++;//此時(shí)已經(jīng)記錄完一行單元格內(nèi)像素 } }//if((w%8==0)&&(h%8==0)) elseif((h%8!=0)&&(w%8==0)) { inthc1=h%8;//行不是8倍數(shù),最上面那一行單元格單獨(dú)考慮 inthc=(h-hc1)/8; intwc=w/8; intjishu=0; intj=0;//列方向上共8個(gè)單元格 while(j<8)//j=0闡明是第一行單元格像素,依次類推 { intcc=0;//記錄一行方格內(nèi)單元格個(gè)數(shù),共8個(gè)方格因此循環(huán)8次 while(cc<8) { if(j==0) pFeature[jishu++]=this->GetOneFeature(0,hc1,cc*wc,(cc+1)*wc,pd,w); else pFeature[jishu++]=this->GetOneFeature(hc1+(j-1)*hc,hc1+j*hc,cc*wc,(cc+1)*wc,pd,w); cc++; } j++;//此時(shí)已經(jīng)記錄完一行單元格內(nèi)像素 } }//elseif((h%8!=0)&&(w%8==0)) elseif((w%8!=0)&&(h%8==0))//行是8倍數(shù),列不是8倍數(shù) { inthc=h/8; intwc1=w%8; intwc=(w-wc1)/8; intjishu=0; intj=0;//列方向上共8個(gè)單元格 while(j<8)//j=0闡明是第一行單元格像素,依次類推 { intcc=0;//記錄一行方格內(nèi)單元格個(gè)數(shù),共8個(gè)方格因此循環(huán)8次 while(cc<8) { if(cc==0) pFeature[jishu++]=this->GetOneFeature(j*hc,(j+1)*hc,0,wc1,pd,w); else pFeature[jishu++]=this->GetOneFeature(j*hc,(j+1)*hc,wc1+(cc-1)*wc,wc1+cc*wc,pd,w); cc++; } j++;//此時(shí)已經(jīng)記錄完一行單元格內(nèi)像素 } }/*elseif((w%8!=0)&&(h%8==0))*/ elseif((w%8!=0)&&(h%8!=0)) { inthc1=h%8; inthc=(h-hc1)/8; intwc1=w%8; intwc=(w-wc1)/8; intjishu=0; intj=0;//列方向上共8個(gè)單元格 while(j<8)//j=0闡明是第一行單元格像素,依次類推 { intcc=0;//記錄一行方格內(nèi)單元格個(gè)數(shù),共8個(gè)方格因此循環(huán)8次 while(cc<8) { if(j==0&&cc==0) pFeature[jishu++]=this->GetOneFeature(0,hc1,0,wc1,pd,w); elseif(j==0&&cc!=0) pFeature[jishu++]=this->GetOneFeature(0,hc1,wc1+(cc-1)*wc,wc1+cc*wc,pd,w); elseif(j!=0&&cc==0) pFeature[jishu++]=this->GetOneFeature(hc1+(j-1)*hc1,hc1+j*hc1,0,wc1,pd,w); else pFeature[jishu++]=this->GetOneFeature(hc1+(j-1)*hc1,hc1+j*hc1,wc1+(cc-1)*wc,wc1+cc*wc,pd,w); cc++; } j++;//此時(shí)已經(jīng)記錄完一行單元格內(nèi)像素 } }/*elseif((w%8!=0)&&(h%8!=0))*/ returnpFeature;}2.得到每個(gè)社區(qū)域特性值doubleCNumShiBieDlg::GetOneFeature(intbrow,interow,intbcol,intecol,BYTE*pdata,intw){ intpixAim=0; intpixSum=0; for(inti=brow;i<erow;i++) for(intj=bcol;j<ecol;j++) if(pdata[i*w+j]==255) pixAim++; else pixSum++; doubledf; df=(double)pixAim/(double)pixSum; returndf;}3.3模板特性庫建立點(diǎn)擊系統(tǒng)界面上訓(xùn)練按鈕即可實(shí)現(xiàn)特性庫建立,訓(xùn)練次數(shù)越多特性庫越豐富,辨認(rèn)成果就越精確。在此系統(tǒng)特性庫是存儲在Access數(shù)據(jù)庫中,如圖3.4所示。在此運(yùn)用MFCADO技術(shù)連接數(shù)據(jù)庫,并且建立記錄集對象并通過函數(shù)OnButtonInitialize()來實(shí)現(xiàn)特性庫訓(xùn)練。圖3.4特性庫詳細(xì)實(shí)當(dāng)代碼為:1.連接數(shù)據(jù)庫CStringstrSql; strSql="select*fromFeature64"; m_rsetPtr.CreateInstance(__uuidof(Recordset)); m_rsetPtr->Open(_bstr_t(strSql),m_connPtr.GetInterfacePtr(),adOpenStatic,adLockOptimistic,adCmdText);2.訓(xùn)練特性庫voidCNumShiBieDlg::OnButtonInitialize()//先顯示圖片再按此按鈕訓(xùn)練{ //TODO:Addyourcontrolnotificationhandlercodehere UpdateData(true); intnum=m_nNum; _ConnectionPtrconnPtr; _RecordsetPtrrsetPtr; intw=0,h=0; BYTE*pdata=this->GetNumData(&w,&h); if(w<8) { AfxMessageBox("圖片過小"); return; } double*pFeature=this->Get64Feature(pdata,w,h); connPtr.CreateInstance(__uuidof(Connection)); try { connPtr->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=Feature.mdb",_T(""),_T(""),adModeUnknown); } catch(_com_errore) { AfxMessageBox(e.ErrorMessage()); } CStringstrSql; strSql="select*fromFeature64"; rsetPtr.CreateInstance(__uuidof(Recordset)); rsetPtr->Open(_bstr_t(strSql),connPtr.GetInterfacePtr(),adOpenStatic,adLockOptimistic,adCmdText); intcount=0; if(!rsetPtr->BOF) { while(!rsetPtr->adoEOF) { count++; rsetPtr->MoveNext(); } } else count=0; try { rsetPtr->MoveLast(); rsetPtr->AddNew(); rsetPtr->PutCollect("Item",(long)++count); rsetPtr->PutCollect("Num",(long)num); for(intx=0;x<64;x++) { CStringtemp,strdata; temp.Format("Feature%d",x+1); strdata.Format("%f",pFeature[x]); rsetPtr->PutCollect(_bstr_t(temp),_bstr_t(strdata)); } rsetPtr->Update(); } catch(_com_errore) { AfxMessageBox(e.ErrorMessage()); } rsetPtr->Close(); rsetPtr=NULL; connPtr->Close(); connPtr=NULL; AfxMessageBox("初始化成功!");}3.4數(shù)字辨認(rèn)點(diǎn)擊系統(tǒng)界面上特性辨認(rèn)按鈕即可實(shí)現(xiàn)手寫數(shù)字辨認(rèn),此系統(tǒng)重要是通過函數(shù)OnButton64shibie()來實(shí)現(xiàn)手寫數(shù)字辨認(rèn),辨認(rèn)過程即和Access數(shù)據(jù)庫連接后把所繪制數(shù)字64個(gè)特性值與模板庫里面每個(gè)特性值進(jìn)行比較,得出它們之間距離,哪一種距離最短則相相應(yīng)模板庫里面數(shù)字即為辨認(rèn)成果,辨認(rèn)成果會通過彈出對話框來顯示,如圖3.5所示。圖3.5辨認(rèn)成果詳細(xì)實(shí)當(dāng)代碼為:voidCNumShiBieDlg::OnButton64shibie(){ //TODO:Addyourcontrolnotificationhandlercodehere intw=0,h=0; BYTE*pdata=this->GetNumData(&w,&h); double*pfeature=this->Get64Feature(pdata,w,h);//獲得64個(gè)特性值 m_connPtr.CreateInstance(__uuidof(Connection)); try { m_connPtr->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=Feature.mdb",_T(""),_T(""),adModeUnknown); } catch(_com_errore) { AfxMessageBox(e.ErrorMessage()); } CStringstrSql; strSql="select*fromFeature64"; m_rsetPtr.CreateInstance(__uuidof(Recordset)); m_rsetPtr->Open(_bstr_t(strSql),m_connPtr.GetInterfacePtr(),adOpenStatic,adLockOptimistic,adCmdText); //運(yùn)用MFCADO技術(shù)連接數(shù)據(jù)庫,并且建立記錄集對象。 intcount=0;// double*df=newdouble[64]; _variant_tva; if(!m_rsetPtr->BOF) { while(!m_rsetPtr->adoEOF) { count++; m_rsetPtr->MoveNext(); } } else count=0; if(count>0) { _variant_tvar; FNUM*pN=newFNUM[count]; m_rsetPtr->MoveFirst(); count=0; while(!m_rsetPtr->adoEOF) { var=m_rse

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論