




已閱讀5頁,還剩22頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
手寫數(shù)字識別系統(tǒng)的設(shè)計與實現(xiàn)摘要 本手寫數(shù)字識別系統(tǒng)是一個以VISUAL STUDIO C+ 6.0為編譯環(huán)境,使用MFC進(jìn)行圖形圖像界面開發(fā)的系統(tǒng)。主要功能是通過在點(diǎn)擊手寫數(shù)字識別菜單下的繪制數(shù)字標(biāo)簽彈出的繪制數(shù)字窗口中完成數(shù)字的手寫,在此窗口中可以進(jìn)行數(shù)字的保存及清屏,然后通過文件菜單中的打開標(biāo)簽打開所繪制的數(shù)字,從而進(jìn)行數(shù)字的預(yù)處理,其中包括灰度化及二值化處理,然后進(jìn)行特征提取,最后實現(xiàn)數(shù)字的識別。本系統(tǒng)的界面設(shè)計友好,流程正確,功能也較為完善。實驗結(jié)果表明,本系統(tǒng)具有較高的識別率。關(guān)鍵詞:繪制數(shù)字;預(yù)處理;特征提取;特征庫;數(shù)字識別目 錄前言1概述21 需求分析41.1 功能需求分析41.2 性能需求分析41.3 數(shù)據(jù)需求分析51.4 相關(guān)軟件介紹52 手寫數(shù)字識別系統(tǒng)的設(shè)計與基本原理62.1 系統(tǒng)整體功能模塊設(shè)計62.2 手寫數(shù)字識別系統(tǒng)的基本原理62.2.1 數(shù)字圖像的繪制62.2.2 圖像的預(yù)處理62.2.3 圖像的特征提取72.2.4 特征庫的建立82.2.5 圖像數(shù)字的識別83 手寫數(shù)字識別系統(tǒng)程序設(shè)計83.1 數(shù)字圖像的繪制83.2數(shù)字的特征提取153.3 模板特征庫的建立183.4 數(shù)字的識別20總結(jié)23致謝24參考文獻(xiàn)25前言自上世紀(jì)六十年代以來,計算機(jī)視覺與圖像處理越來越受到人們的關(guān)注,并逐漸成為一門重要的學(xué)科領(lǐng)域。而作為它們的研究對象的數(shù)字圖像,也因為它含有研究目標(biāo)的豐富信息而成為越來越重要的研究對象。圖像識別的目標(biāo)是用計算機(jī)自動完成某些信息的處理,用來替代人工去處理圖像分類及識別的任務(wù)。手寫數(shù)字識別是圖像識別學(xué)科下的一個分支,是圖像處理和模式識別領(lǐng)域研究的課題之一,由于其具有很強(qiáng)的實用性一直是多年來的研究熱點(diǎn)。由于手寫體數(shù)字的隨意性很大,例如,筆畫的粗細(xì),字體的大小,傾斜等等都直接影響到字符的正確識別,所以手寫體數(shù)字識別是一個很有挑戰(zhàn)性的課題。在過去的數(shù)十年中,研究者們提出了許多的識別方法,取得了較大的成果。手寫體數(shù)字識別實用性很強(qiáng),在大規(guī)模數(shù)據(jù)統(tǒng)計(如例行年檢,人口普查),財務(wù),稅務(wù),郵件分揀等等應(yīng)用領(lǐng)域中都有廣闊的應(yīng)用前景。本課題擬研究手寫體數(shù)字識別的理論和方法,開發(fā)一個小型的手寫體數(shù)字識別系統(tǒng)。在研究手寫體數(shù)字識別理論和方法的基礎(chǔ)上,開發(fā)這樣一個小型的手寫體數(shù)字識別系統(tǒng)需要完成以下主要方面的研究與設(shè)計工作: 手寫數(shù)字繪制的問題、數(shù)字的預(yù)處理問題、特征提取問題、特征庫的建立問題、數(shù)字識別問題。概述此手寫數(shù)字識別系統(tǒng)的需要實現(xiàn)手寫數(shù)字的繪制功能、手寫數(shù)字的特征提取功能、數(shù)字的模板特征庫的建立功能以及手寫數(shù)字的識別功能。在近幾年國內(nèi)外對手寫數(shù)字識別系統(tǒng)的研究已經(jīng)取得了進(jìn)展,一些新的理論例如基于Hopfield 神經(jīng)網(wǎng)絡(luò)、基于小波技術(shù)、基于BP 神經(jīng)網(wǎng)絡(luò)以及支持向量機(jī)的研究應(yīng)用在建立手寫數(shù)字識別系統(tǒng)平臺,并且在多數(shù)數(shù)據(jù)庫中取得了較好的測試結(jié)果。但是目前仍然存在亟需深入研究解決的問題:1) 識別的準(zhǔn)確度需要達(dá)到較好的水平2) 識別的效率要達(dá)到很高的水平。數(shù)字識別輸入的數(shù)據(jù)通常是很大的,而高精度與高速度是相互矛盾。這些難點(diǎn)存在的原因是:1) 數(shù)字的筆劃簡單,而且其筆劃差別相對較小,字形相差不大,使得準(zhǔn)確區(qū)分某些數(shù)字有一些困難;2) 數(shù)字雖然只有10 種,且筆劃簡單,但同一數(shù)字寫法卻千差萬別,全世界的各個國家各個地區(qū)的人都在用,則其書寫上帶有區(qū)域特性,很難做出可以兼顧世界各種寫法的、識別率極高的通用性數(shù)字識別系統(tǒng)。3)特征庫的訓(xùn)練不夠,導(dǎo)致識別率不高。手寫數(shù)字識別的研究不僅存在很大的應(yīng)用價值,由于手寫數(shù)字識別本身的特點(diǎn),對它的研究也存在著重要的理論價值:1) 阿拉伯?dāng)?shù)字作為唯一被世界各國通用的符號,所以對手寫體數(shù)字識別的研究基本上與文化背景無關(guān),各地的研究工作者可以說是基于同一平臺開展工作的,有利于研究的比較和探討。2) 手寫數(shù)字識別應(yīng)用廣泛,如稅表系統(tǒng),銀行支票自動處理和郵政編碼自動識別等。在以前,這些工作需要大量的手工錄入,投入的人力物力都相對較多,而且勞動強(qiáng)度較大。為了適應(yīng)無紙化辦公的需要,大大提高工作效率,研究實現(xiàn)手寫數(shù)字識別系統(tǒng)是必須要做的。3) 由于數(shù)字類別只有0-9共10 個,比其他字符識別率較高,可將其用于驗證新的理論或做深入的分析研究。許多機(jī)器學(xué)習(xí)和模式識別領(lǐng)域的新理論和算法都是先用手寫數(shù)字識別進(jìn)行檢驗,驗證其理論的有效性,然后才會將其應(yīng)用到更為復(fù)雜的領(lǐng)域當(dāng)中。在這方面的典型例子就是人工神經(jīng)網(wǎng)絡(luò)和支持向量機(jī)。4) 手寫數(shù)字的識別方法很容易將其推廣到其它一些相關(guān)的問題上,如對英文之類拼音文字的識別。事實上,有許多學(xué)者就是把數(shù)字和英文字母的識別放在一起研究的。在過去的數(shù)幾年中,研究者提出了許許多多的識別方法,按提取的數(shù)字特征的不同,可以將這些方法分為兩類:基于結(jié)構(gòu)特征的方法和基于統(tǒng)計特征的方法。統(tǒng)計特征通常包括點(diǎn)密度的測量、矩、特征區(qū)域等;結(jié)構(gòu)特征通常包括圓、端點(diǎn)、交叉點(diǎn)、筆劃、輪廓等,一般來說,兩類特征各有優(yōu)勢。例如,使用統(tǒng)計特征的分類器易于訓(xùn)練,而且對于使用統(tǒng)計特征的分類器,在給定的訓(xùn)練集上能夠得到相對較高的識別率;而結(jié)構(gòu)特征的主要優(yōu)點(diǎn)之一是能描述字符的結(jié)構(gòu),在識別過程中能有效地結(jié)合幾何和結(jié)構(gòu)的知識,因此能夠得到可靠性較高的識別結(jié)果。在此次的設(shè)計中使用的是統(tǒng)計特征?;谝陨纤?,本次畢業(yè)設(shè)計課題為手寫數(shù)字識別系統(tǒng)的設(shè)計與實現(xiàn)。其功能是將人工手繪的數(shù)字圖像轉(zhuǎn)換成可編輯的文本信息。該系統(tǒng)包括手寫數(shù)字繪制模塊、圖像預(yù)處理模塊、特征提取模塊、訓(xùn)練模塊和識別模塊。涉及模式識別、圖像處理、人工智能、統(tǒng)計學(xué)、心理學(xué)和計算機(jī)科學(xué)等相關(guān)內(nèi)容。通過對圖像處理和識別算法進(jìn)行不斷地研究和實踐,以降低誤識率和拒識率。本文主要介紹手寫數(shù)字識別系統(tǒng)的設(shè)計與實現(xiàn),首先需要了解手寫數(shù)字識別系統(tǒng)現(xiàn)階段的發(fā)展情況和研究現(xiàn)狀,然后對系統(tǒng)進(jìn)行分析,主要從功能需求分析、性能需求分析、數(shù)據(jù)需求分析和相關(guān)軟件介紹四方面入手,從而使得對系統(tǒng)有初步的認(rèn)識,然后對系統(tǒng)的整體設(shè)計模塊進(jìn)行介紹,進(jìn)而對系統(tǒng)的各個功能模塊具體的設(shè)計原理進(jìn)行詳細(xì)介紹,之后對本次所設(shè)計出的系統(tǒng)進(jìn)行介紹并對相關(guān)代碼進(jìn)行說明,最后總結(jié)本系統(tǒng)的優(yōu)缺點(diǎn)及今后工作展望等,整篇文章通俗易懂,條理清晰,可以使讀者輕松閱讀,并理解實現(xiàn)過程。1 需求分析綜合用戶在實際應(yīng)用中的需求,對系統(tǒng)的運(yùn)作流程進(jìn)行了整理,并通過對流程的分析得出了如下的需求分析。1.1 功能需求分析根據(jù)對用戶需求的分析,系統(tǒng)應(yīng)包含以下功能:1) 數(shù)字的繪制在繪制數(shù)字的窗口中實現(xiàn)數(shù)字的手寫,并對其坐標(biāo)值進(jìn)行保存,利用復(fù)位按鈕可實現(xiàn)數(shù)字的清除工作。2) 數(shù)字的預(yù)處理在手寫數(shù)字圖像識別系統(tǒng)中,圖像的預(yù)處理跟一般圖像系統(tǒng)不同,我們不需要對圖像進(jìn)行灰度化處理、去噪處理等基本操作,我們利用程序保存的坐標(biāo)值就可以對生成一張二值化圖像,相當(dāng)于圖像處理系統(tǒng)的二值化處理。3) 特征的提取在第二步中我們得到了手寫數(shù)字的二值化圖像,進(jìn)行特征提取前需要對此圖像的數(shù)據(jù)區(qū)域進(jìn)行定位,在程序中我們遍歷此二值化圖像,找到手寫數(shù)字區(qū)域的上、下、左、右邊界,重新生成一張數(shù)字圖片,利用新生成的數(shù)字圖片分成8*8的區(qū)域,統(tǒng)計每個區(qū)域的目標(biāo)像素個數(shù)和整個小區(qū)域像素個數(shù),計算目標(biāo)像素個數(shù)與整個小區(qū)域像素的比值,得到64個特征值,作為這個手寫數(shù)字的特征值。4) 特征庫的訓(xùn)練我們需要訓(xùn)練一個特征庫,作為識別的標(biāo)準(zhǔn)。系統(tǒng)中我們手寫一個數(shù)字提取出它的特征值,再輸入此手寫數(shù)字,將數(shù)字與這些特征值相對應(yīng)存儲到特征庫里面,特征庫我們使用的是Access數(shù)據(jù)庫,字段是數(shù)字及這個數(shù)字所對應(yīng)所有特征值。特征庫越豐富,識別率越高。5) 數(shù)字識別在手寫數(shù)字識別中,我們使用的方法是模板匹配法,其實質(zhì)就是提取出手寫數(shù)字的特征值,利用這些特征值與特征庫的數(shù)字的特征值進(jìn)行比對,找出待識別數(shù)字特征值與特征庫里存儲的特征值最接近的數(shù)字,作為識別結(jié)果。1.2 性能需求分析1) 正確性:根據(jù)手寫數(shù)字識別系統(tǒng)的設(shè)計流程,流程中的每個步驟在系統(tǒng)中都必須有所體現(xiàn),以保證程序的正確性。2) 精確性:根據(jù)手寫數(shù)字識別系統(tǒng)的應(yīng)用領(lǐng)域,該系統(tǒng)的識別結(jié)果必須有很高的識別精度,這樣才能真正的實現(xiàn)該系統(tǒng)的價值。3) 效率性:根據(jù)該系統(tǒng)的應(yīng)用領(lǐng)域可知,系統(tǒng)一旦投入應(yīng)用需要處理大量的數(shù)據(jù),所以對系統(tǒng)的處理速度也有很高的要求。1.3 數(shù)據(jù)需求分析根據(jù)手寫數(shù)字識別系統(tǒng)的設(shè)計步驟可知該系統(tǒng)采用的是模板匹配法進(jìn)行手寫體數(shù)字識別。模板匹配法是圖像識別中最具有代表性的方法之一。它是將從待識別的圖像提取的若干特征量與模板對應(yīng)的特征量進(jìn)行比較,計算圖像和模板特征量之間的距離,用最小距離法判定所屬類。而模板匹配通常需要事先建立標(biāo)準(zhǔn)模板庫。這里,模板庫中的標(biāo)準(zhǔn)模板是數(shù)字樣本的特征向量。特征庫的存儲是利用Access數(shù)據(jù)庫,并且利用MFC ADO技術(shù)連接數(shù)據(jù)庫,不需要進(jìn)行硬件配置。數(shù)據(jù)庫如圖1.1所示。圖1.1 數(shù)據(jù)庫1.4 相關(guān)軟件介紹本課題是基于Visual C+6.0的,它是Microsoft公司開發(fā)的Visual Studio集成開發(fā)環(huán)境中功能最為強(qiáng)大、代碼效率最高的開發(fā)工共。利用VisualC+6.0可以兩種方式編寫Win32應(yīng)用程序,一種方式是基于Windows API的C編程方式,另一種是基于MFC的C+編程方式。本系統(tǒng)采用的是基于MFC的編程方式。2 手寫數(shù)字識別系統(tǒng)的設(shè)計與基本原理2.1 系統(tǒng)整體功能模塊設(shè)計整體模塊如圖2.1所示:數(shù)字圖像的繪制訓(xùn)練特征庫二值化處理特征提取數(shù)字識別主界面圖2.1 整體模塊2.2 手寫數(shù)字識別系統(tǒng)的基本原理下面分別介紹各部分工作的基本原理:2.2.1 數(shù)字圖像的繪制手寫數(shù)字繪制功能的實現(xiàn)方案是:通過Visual C+中的CStatic控件來建立畫布,用MFC中的封裝類CDC實現(xiàn)手寫數(shù)字功能。在對話框中,響應(yīng)鼠標(biāo)事件的消息,分別是鼠標(biāo)按下事件MouseDown,鼠標(biāo)移動事件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è)計中主要包括:圖像二值化處理。圖像的二值化處理就是將圖像上的像素點(diǎn)的灰度值設(shè)置為0或255,也就是將整個圖像呈現(xiàn)出明顯的黑白效果。在手寫數(shù)字識別系統(tǒng)中,我們在VC可視化編程界面中在一個固定大小的控件中手寫了一個數(shù)字,在程序中獲得的只是以這個控件左上角為原點(diǎn)的一系列坐標(biāo)。在內(nèi)存中我們開辟一個大小跟這個控件區(qū)域大小相同的二維數(shù)組(以像素為單位,即生成一張圖片的長跟寬跟這個矩形區(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ù)量減小,能凸顯出感興趣的目標(biāo)的輪廓。2.2.3 圖像的特征提取若直接把預(yù)處理后的數(shù)據(jù)作為輸入量,進(jìn)行分類計算時數(shù)據(jù)時數(shù)據(jù)量大,同時由于手寫字體的多樣化及圖像本身和預(yù)處理過程中附帶的某些干擾的影響,對系統(tǒng)的容錯能力要求較高。特征提取的目的就是從分析數(shù)字的拓?fù)浣Y(jié)構(gòu)入手,把它的某些結(jié)構(gòu)特征提取出來,使數(shù)字的位移、大小變化、字形畸形等干擾相對較小,也就是把那些反映數(shù)字特征的關(guān)鍵信息提供給系統(tǒng),這樣就等于間接地增加了系統(tǒng)的容錯能力,而且經(jīng)過特征提取后數(shù)據(jù)量也大大減少了,這樣就提高了識別的效率。手寫數(shù)字識別的特征提取極大程度地影響著分類器的設(shè)計和性能,以及識別的效果和效率。為了保證所要求的分類識別的正確率和節(jié)省資源,希望依據(jù)最少的特征達(dá)到所要求的分類識別的正確率。在進(jìn)行手寫數(shù)字識別的過程中,特征提取應(yīng)遵循以下原則:1) 特征應(yīng)能盡量包含字符的有用信息。2) 特征的提取方法應(yīng)簡單而且提取快速。3) 各個特征之間的相關(guān)性應(yīng)盡可能小。4) 特征數(shù)量盡可能少。5) 特征應(yīng)有較好的抗干擾能力??紤]到算法的實時性、快速性和準(zhǔn)確性,在此次設(shè)計中采用的是一種簡單的模板法對待測樣本進(jìn)行特征提取。步驟為:1、搜索數(shù)據(jù)區(qū)域,找出手寫體數(shù)字的上下左右邊界。2、將搜索到的數(shù)字區(qū)域平分成8*8共64個小區(qū)域。3、計算8*8的每一個小區(qū)域中白色像素所占比例,即用每一個小區(qū)域內(nèi)的白色像素個數(shù)除以該小區(qū)域的面積總數(shù)(總像素數(shù)),即得特征值,第一行的8個比例值是特征的前8特征值,第二行對應(yīng)著特征的916個,以此類推。2.2.4 特征庫的建立在手寫數(shù)字識別系統(tǒng)中,我們首先要建立一個特征庫,我們手寫一個數(shù)字,并且取得這個數(shù)字的特征值,然后再想程序輸入這個數(shù)字,在程序中將此輸入數(shù)字與所有特征值相對應(yīng),作為模板庫的一條記錄,初始化模板庫之后,就可以對手寫數(shù)字進(jìn)行識別,在識別的過程中我們不斷的豐富模板庫,如果手寫數(shù)字識別成功則不需要將此數(shù)字存儲到模板庫中,如果識別失敗就需要將此數(shù)字存儲到模板庫中,這樣我們的模板庫將越來越豐富。2.2.5 圖像數(shù)字的識別 在手寫數(shù)字圖像特征提取結(jié)束后,即可進(jìn)行數(shù)字的識別。這也是手寫數(shù)字識別系統(tǒng)設(shè)計的最后一個環(huán)節(jié),在本次設(shè)計中采用模板匹配法進(jìn)行手寫體數(shù)字識別。模板匹配法是圖像識別中最具有代表性的方法之一。它是將從待識別的圖像提取的若干特征量與模板對應(yīng)的特征量進(jìn)行比較,計算圖像和模板特征量之間的距離,用最小距離法判定所屬類。模板匹配通常事先建立標(biāo)準(zhǔn)模板庫。這里,模板庫中的標(biāo)準(zhǔn)模板是數(shù)字樣本的特征向量。具體過程是:對于一個待測試的樣本X,計算X和訓(xùn)練集中的某樣本Xj(0jGetClientRect(rect);m_ctlDrawNum.GetClientRect(rect1); /這個函數(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)保存到堆棧中,相當(dāng)于保存的是數(shù)字像素點(diǎn)在原始圖像中的坐標(biāo)值/AfxMessageBox(str);CDialog:OnLButtonDown(nFlags, point);void CNumShiBieDlg:OnMouseMove(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultCRect rect;CString str;m_ctlDrawNum.GetClientRect(rect);:ClientToScreen(m_hWnd,&point);:ScreenToClient(m_ctlDrawNum.m_hWnd,&point);str.Format(%d %d,point.x,point.y);CPen pen(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)CPoint befPoint = *(stuPoint.p+stuPoint.cur-2);CPoint curPoint = *(stuPoint.p+stuPoint.cur-1);pDC-MoveTo(befPoint.x,befPoint.y);pDC-LineTo(curPoint.x,curPoint.y);CDialog:OnMouseMove(nFlags, point);void CNumShiBieDlg:OnLButtonUp(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultCRect rect;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)CPoint befPoint = *(stuPoint.p+stuPoint.cur-2);CPoint curPoint = *(stuPoint.p+stuPoint.cur-1);pDC-MoveTo(befPoint.x,befPoint.y);pDC-LineTo(curPoint.x,curPoint.y);CDialog:OnLButtonUp(nFlags, point);2.手寫數(shù)字的存儲bool CNumShiBieDlg:AddPointStack(const CPoint &point)CString str;bool b = false;if(stuPoint.cur!=stuPoint.size)*(stuPoint.p+stuPoint.cur) = point;stuPoint.cur += 1; /cur指向的是最后一個結(jié)點(diǎn)的后一個空結(jié)點(diǎn)b = true;elseb=false;AfxMessageBox(棧滿溢出);return b;3.手寫數(shù)字的清除void CNumShiBieDlg:OnButtonRset() / TODO: Add your control notification handler code herethis-Invalidate();stuPoint.cur = 0;if(stuPoint.p!=NULL)delete stuPoint.p;stuPoint.p = new CPointstuPoint.size;4.二值化后的顯示void CNumShiBieDlg:OnButtonShownum() / TODO: Add your control notification handler code hereCRect rect;m_ctlDrawNum.GetClientRect(rect);int w = 0 ,h = 0;w = rect.Width();h = rect.Height();if(w%4!=0)w = w+4-w%4; /按位補(bǔ)齊,寬一定要是4的倍數(shù)/windows下規(guī)定,位圖的行的像素個數(shù)必須是4的倍數(shù)int xleft=w , ytop= h, xrigth=0 ,ybottom=0;for(int i1 = 0; i1 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; /這個循環(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ū)域的寬跟長,以像素為單位unsigned char * pdata=new unsigned charw*h*3;:memset(pdata,0,w*h*3);for(int i=0;istuPoint.cur;i+)CPoint point = *(stuPoint.p+i);int x = point.x;int y = 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才是表示圖像的第幾行像素/鼠標(biāo)走過的點(diǎn)的坐標(biāo)值即是數(shù)字像素在數(shù)據(jù)矩陣中的坐標(biāo)值,這樣我們把鼠標(biāo)走過的所有坐標(biāo)值對應(yīng)到圖像數(shù)據(jù)的坐標(biāo)值中的灰度值設(shè)置成255,而背景色置為白/這樣相當(dāng)于,將手寫數(shù)字區(qū)域當(dāng)成一張數(shù)字圖片,將其從第一行到最后一行的數(shù)據(jù)順序讀到內(nèi)存中,所以我們顯示時,一定要將此圖片數(shù)據(jù)區(qū)域按行轉(zhuǎn)置unsigned char * ppdata = new unsigned charw*h*3;:memcpy(ppdata,pdata,w*h*3);for(i = 0 ; i h ; i+)for(int j = 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ù)據(jù)區(qū)域的最后一行的,而最后一行像素在位圖/文件數(shù)據(jù)區(qū)域矩陣中是存儲在第一行的,所以平時我們讀取了一個位圖之后,讀取到的像素值,與我們實際看到的圖像的像素是按行倒置的/并且當(dāng)我們用StretchDibits函數(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;unsigned char* pnum = new unsigned charnw*nh;pnumzheng = new unsigned charnw*nh;:memset(pnum,0,nw*nh);for(i = 0 ;i stuPoint.cur ;i+)CPoint point;point = *(stuPoint.p+i);int x , y;x = point.x - xleft;y = point.y - ytop; /(xleft,ytop)相當(dāng)于生成的手寫數(shù)字區(qū)域矩形最左上角的坐標(biāo),這里完成了坐標(biāo)系統(tǒng)的轉(zhuǎn)換pnumy*nw+x = 255;/pnum(y*nw+x)*3+1 = 255;/pnum(y*nw+x)*3+2 = 255;for(i = 0 ;i nh ;i+)for(int j = 0 ; j nw ;j+)pnumzheng(nh-i-1)*nw+j = pnumi*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;HDC hdc = :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ù)字特征的提取是為了更好的實現(xiàn)數(shù)字的識別,在此是通過提取所繪制數(shù)字的像素特征即如前面所介紹的用目標(biāo)像素個數(shù)除以這個小區(qū)域內(nèi)總得像素個數(shù)的結(jié)果作為此區(qū)域的特征值,共可得到64個特征值。在此通過在函數(shù)Get64Feature(BYTE *pd, int w, int h)中調(diào)用函數(shù)GetOneFeature(int brow, int erow, int bcol, int ecol , BYTE * pdata ,int w)來實現(xiàn)數(shù)字特征的提取功能。具體實現(xiàn)代碼為:1.得到64個區(qū)域的特征值double* CNumShiBieDlg:Get64Feature(BYTE *pd, int w, int h)double *pFeature = new double64;if(w%8=0) & (h%8=0)int hc = h/8;int wc = w/8;int jishu = 0;int j = 0; /列的方向上共8個單元格while(j 8)/j = 0說明是第一行的單元格像素,依次類推int cc = 0 ; /記錄一行方格內(nèi)的單元格個數(shù),共8個方格所以循環(huán)8次while(cc GetOneFeature(j*hc , (j+1)*hc , cc*wc ,(cc+1)*wc , pd ,w);cc+;/此時已經(jīng)統(tǒng)計完一個單元格的像素j+ ; /此時已經(jīng)統(tǒng)計完一行單元格內(nèi)的像素/if(w%8=0) & (h%8=0)else if(h%8!=0)&(w%8=0)int hc1 = h%8; /行不是8的倍數(shù),最上面那一行單元格單獨(dú)考慮int hc = (h-hc1)/8;int wc = w/8;int jishu = 0;int j = 0; /列的方向上共8個單元格while(j 8)/j = 0說明是第一行的單元格像素,依次類推int cc = 0 ; /記錄一行方格內(nèi)的單元格個數(shù),共8個方格所以循環(huán)8次while(cc GetOneFeature(0 , hc1 , cc*wc , (cc+1)*wc,pd ,w);elsepFeaturejishu+ = this-GetOneFeature(hc1+(j-1)*hc , hc1+j*hc ,cc*wc , (cc+1)*wc , pd ,w);cc+;j+ ; /此時已經(jīng)統(tǒng)計完一行單元格內(nèi)的像素/else if(h%8!=0)&(w%8=0)else if(w%8!=0)&(h%8=0) /行是8的倍數(shù),列不是8的倍數(shù)int hc = h/8;int wc1 = w%8;int wc = (w-wc1)/8;int jishu = 0;int j = 0; /列的方向上共8個單元格while(j 8)/j = 0說明是第一行的單元格像素,依次類推int cc = 0 ; /記錄一行方格內(nèi)的單元格個數(shù),共8個方格所以循環(huán)8次while(cc GetOneFeature(j*hc , (j+1)*hc , 0 , wc1 , pd ,w);elsepFeaturejishu+ = this-GetOneFeature(j*hc , (j+1)*hc , wc1+(cc-1)*wc ,wc1+cc*wc ,pd ,w);cc+;j+ ; /此時已經(jīng)統(tǒng)計完一行單元格內(nèi)的像素/*else if(w%8!=0)&(h%8=0)*/else if(w%8!=0)&(h%8!=0)int hc1 = h%8;int hc = (h-hc1)/8;int wc1 = w%8;int wc = (w-wc1)/8;int jishu = 0;int j = 0; /列的方向上共8個單元格while(j 8)/j = 0說明是第一行的單元格像素,依次類推int cc = 0 ; /記錄一行方格內(nèi)的單元格個數(shù),共8個方格所以循環(huán)8次while(cc GetOneFeature(0 , hc1 ,0 , wc1 ,pd ,w);else if(j=0&cc!=0)pFeaturejishu+ = this-GetOneFeature(0 ,hc1 ,wc1+(cc-1)*wc ,wc1 + cc*wc , pd ,w);else if(j!=0&cc=0)pFeaturejishu+ = this-GetOneFeature(hc1+(j-1)*hc1 ,hc1+j*hc1 ,0 , wc1 ,pd ,w);elsepFeaturejishu+ = this-GetOneFeature(hc1+(j-1)*hc1 , hc1+j*hc1 , wc1+(cc-1)*wc , wc1+cc*wc ,pd ,w);cc+;j+ ; /此時已經(jīng)統(tǒng)計完一行單元格內(nèi)的像素/*else if(w%8!=0)&(h%8!=0)*/return pFeature;2.得到每個小區(qū)域的特征值double CNumShiBieDlg:GetOneFeature(int brow, int erow, int bcol, int ecol , BYTE * pdata ,int w)int pixAim = 0;int pixSum = 0;for(int i = brow ; i erow ; i+)for(int j = bcol ; j Open(_bstr_t(strSql),m_connPtr.GetInterfacePtr(), adOpenStatic , adLockOptimistic ,adCmdText);2.訓(xùn)練特征庫void CNumShiBieDlg:OnButtonInitialize() /先顯示圖片再按此按鈕 訓(xùn)練/ TODO: Add your control notification handler code hereUpdateData(true);int num = m_nNum;_ConnectionPtr connPtr ;_RecordsetPtr rsetPtr;int w = 0, h = 0;BYTE *pdata = this-GetNumData(&w , &h);if(w Get64Feature(pdata , w ,h);connPtr.CreateInstance(_uuidof(Connection);tryconnPtr-Open(Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Feature.mdb,_T(),_T(),adModeUnknown);catch(_com_error e)AfxMessageBox(e.ErrorMessage();CString strSql;strSql = select * from Feature64 ;rsetPtr.CreateInstance(_uuidof(Recordset);rsetPtr-Open(_bstr_t(strSql),connPtr.GetInterfacePtr(), adOpenStatic , adLockOptimistic ,adCmdText);int count = 0;if(!rsetPtr-BOF)while(!rsetPtr-adoEOF)count+;rsetPtr-MoveNext();elsecount = 0;tryrsetPtr-MoveLast();rsetPtr-AddNew();rsetPtr-PutCollect(Item , (long)+count);rsetPtr-PutCollect(Num,(long)num);for(int x = 0 ; x PutCollect(_bstr_t(temp) , _bstr_t(strdata);rsetPtr-Update();catch(_com_error e)AfxMessageBox(e.ErrorMessage();rsetPtr-Close();rsetPtr = NULL;connPtr-Close();connPtr = NULL;AfxMessageBox(初始化成功!);3.4 數(shù)字的識別點(diǎn)擊系統(tǒng)界面上的特征識別按鈕即可實現(xiàn)手寫數(shù)字的識別,此系統(tǒng)主要是通過函數(shù)OnButton64shibie() 來實現(xiàn)手寫數(shù)字的識別,識別過程即和Access數(shù)據(jù)庫連接后把所繪制數(shù)字的64個特征值與模板庫里面的每個特征值進(jìn)行比較,得出它們之間的距離,哪一個距離最短則相對應(yīng)的模板庫里面的數(shù)字即為識別的結(jié)果,識別結(jié)果會通過彈出對話框來顯示,如圖3.5所示。圖3.5 識別結(jié)果具體實現(xiàn)代碼為:void CNumShiBieDlg:OnButton64shibie() / TODO: Add your control notification handler code hereint w = 0 , h = 0;BYTE *pdata = this-GetNumData(&w , &h);double *pfeature = this-Get64Feature(pdata , w ,h); /取得64個特征值m_connPtr.CreateInstance(_uuidof(Connection);trym_connPtr-Open(Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Feature.mdb,_T(),_T(),adModeU
溫馨提示
- 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)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年初中人教版《物理》九年級全一冊第十八章第二節(jié)“電功率”說課稿
- 3.2 熔化和凝固 說課稿 2025年初中人教版物理八年級上冊
- 共同購房協(xié)議書范本
- 學(xué)校戰(zhàn)略合作協(xié)議
- 物聯(lián)網(wǎng)居間協(xié)議
- 二零二五年度北京市化工原料寄存與倉儲環(huán)境監(jiān)測合同
- 地塊項目基坑工程 投標(biāo)方案(技術(shù)方案)
- 航空運(yùn)輸與服務(wù)系統(tǒng)作業(yè)指導(dǎo)書
- 三農(nóng)產(chǎn)品產(chǎn)銷對接網(wǎng)絡(luò)平臺建設(shè)方案
- 創(chuàng)業(yè)孵化基地入駐條件及運(yùn)營管理辦法匯編
- 蘇教版數(shù)學(xué)一年級下冊(2024)第七單元觀察物體(一)綜合素養(yǎng)測評 A 卷(含答案)
- 2025年中考英語第一次模擬試卷01(廣州專用)(原卷版)
- 2025年甘肅省張掖市民樂縣招聘專業(yè)技術(shù)人員9人(第二期)歷年高頻重點(diǎn)模擬試卷提升(共500題附帶答案詳解)
- 2025年湖北武漢理工大學(xué)學(xué)生輔導(dǎo)員招聘18人歷年高頻重點(diǎn)模擬試卷提升(共500題附帶答案詳解)
- 《石油工程事故案例分析》課件
- 金融科技概論-課件 第十五章 金融科技監(jiān)管與監(jiān)管科技
- 初級咖啡師資格理論考試題及答案
- 2024年09月寧夏寧夏黃河農(nóng)村商業(yè)銀行系統(tǒng)社會招考筆試歷年參考題庫附帶答案詳解
- 招標(biāo)代理機(jī)構(gòu)選取突發(fā)情況應(yīng)急處理預(yù)案
- 深筋膜徒手松解療法
- 皮膚病學(xué)測試題含參考答案
評論
0/150
提交評論