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

下載本文檔

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

文檔簡介

1、資料內(nèi)容僅供您學(xué)習(xí)參考,如有不當(dāng)或者侵權(quán),請聯(lián)系改正或者刪除。手寫數(shù)字識別系統(tǒng)的設(shè)計與實現(xiàn)摘要 本手寫數(shù)字識別系統(tǒng)是一個以VISUAL STUDIO C+ 6.0為編譯環(huán)境, 使用MFC進(jìn)行圖形圖像界面開發(fā)的系統(tǒng)。主要功能是經(jīng)過在點擊手寫數(shù)字識別菜單下的繪制數(shù)字標(biāo)簽彈出的繪制數(shù)字窗口中完成數(shù)字的手寫, 在此窗口中能夠進(jìn)行數(shù)字的保存及清屏, 然后經(jīng)過文件菜單中的打開標(biāo)簽打開所繪制的數(shù)字, 從而進(jìn)行數(shù)字的預(yù)處理, 其中包括灰度化及二值化處理, 然后進(jìn)行特征提取, 最后實現(xiàn)數(shù)字的識別。本系統(tǒng)的界面設(shè)計友好, 流程正確, 功能也較為完善。實驗結(jié)果表明, 本系統(tǒng)具有較高的識別率。關(guān)鍵詞: 繪制數(shù)字;預(yù)處

2、理;特征提取;特征庫;數(shù)字識別目 錄 TOC o 1-3 h z u HYPERLINK l _Toc 前言 PAGEREF _Toc h 1 HYPERLINK l _Toc 概述 PAGEREF _Toc h 2 HYPERLINK l _Toc 1 需求分析 PAGEREF _Toc h 4 HYPERLINK l _Toc 1.1 功能需求分析 PAGEREF _Toc h 4 HYPERLINK l _Toc 1.2 性能需求分析 PAGEREF _Toc h 4 HYPERLINK l _Toc 1.3 數(shù)據(jù)需求分析 PAGEREF _Toc h 5 HYPERLINK l _To

3、c 1.4 相關(guān)軟件介紹 PAGEREF _Toc h 5 HYPERLINK l _Toc 2 手寫數(shù)字識別系統(tǒng)的設(shè)計與基本原理 PAGEREF _Toc h 6 HYPERLINK l _Toc 2.1 系統(tǒng)整體功能模塊設(shè)計 PAGEREF _Toc h 6 HYPERLINK l _Toc 2.2 手寫數(shù)字識別系統(tǒng)的基本原理 PAGEREF _Toc h 6 HYPERLINK l _Toc 2.2.1 數(shù)字圖像的繪制 PAGEREF _Toc h 6 HYPERLINK l _Toc 2.2.2 圖像的預(yù)處理 PAGEREF _Toc h 6 HYPERLINK l _Toc 2.2.

4、3 圖像的特征提取 PAGEREF _Toc h 7 HYPERLINK l _Toc 2.2.4 特征庫的建立 PAGEREF _Toc h 8 HYPERLINK l _Toc 2.2.5 圖像數(shù)字的識別 PAGEREF _Toc h 8 HYPERLINK l _Toc 3 手寫數(shù)字識別系統(tǒng)程序設(shè)計 PAGEREF _Toc h 8 HYPERLINK l _Toc 3.1 數(shù)字圖像的繪制 PAGEREF _Toc h 8 HYPERLINK l _Toc 3.2數(shù)字的特征提取 PAGEREF _Toc h 15 HYPERLINK l _Toc 3.3 模板特征庫的建立 PAGEREF

5、 _Toc h 18 HYPERLINK l _Toc 3.4 數(shù)字的識別 PAGEREF _Toc h 20 HYPERLINK l _Toc 總結(jié) PAGEREF _Toc h 23 HYPERLINK l _Toc 致謝 PAGEREF _Toc h 24 HYPERLINK l _Toc 參考文獻(xiàn) PAGEREF _Toc h 25前言自上世紀(jì)六十年代以來, 計算機視覺與圖像處理越來越受到人們的關(guān)注, 并逐漸成為一門重要的學(xué)科領(lǐng)域。而作為它們的研究對象的數(shù)字圖像, 也因為它含有研究目標(biāo)的豐富信息而成為越來越重要的研究對象。圖像識別的目標(biāo)是用計算機自動完成某些信息的處理, 用來替代人工去

6、處理圖像分類及識別的任務(wù)。手寫數(shù)字識別是圖像識別學(xué)科下的一個分支, 是圖像處理和模式識別領(lǐng)域研究的課題之一, 由于其具有很強的實用性一直是多年來的研究熱點。由于手寫體數(shù)字的隨意性很大, 例如, 筆畫的粗細(xì), 字體的大小, 傾斜等等都直接影響到字符的正確識別, 因此手寫體數(shù)字識別是一個很有挑戰(zhàn)性的課題。在過去的數(shù)十年中, 研究者們提出了許多的識別方法, 取得了較大的成果。手寫體數(shù)字識別實用性很強, 在大規(guī)模數(shù)據(jù)統(tǒng)計(如例行年檢, 人口普查), 財務(wù), 稅務(wù), 郵件分揀等等應(yīng)用領(lǐng)域中都有廣闊的應(yīng)用前景。本課題擬研究手寫體數(shù)字識別的理論和方法, 開發(fā)一個小型的手寫體數(shù)字識別系統(tǒng)。在研究手寫體數(shù)字識別

7、理論和方法的基礎(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ò)以及支持向量機的研究應(yīng)用在建立手寫數(shù)字識別系統(tǒng)平臺, 而且在多數(shù)數(shù)據(jù)庫中取得了較好的測試結(jié)果??墒钱?dāng)前依然存在亟需深入研究解決的問題: 1)

8、 識別的準(zhǔn)確度需要達(dá)到較好的水平2) 識別的效率要達(dá)到很高的水平。數(shù)字識別輸入的數(shù)據(jù)一般是很大的, 而高精度與高速度是相互矛盾。這些難點存在的原因是: 1) 數(shù)字的筆劃簡單, 而且其筆劃差別相對較小, 字形相差不大, 使得準(zhǔn)確區(qū)分某些數(shù)字有一些困難; 2) 數(shù)字雖然只有10 種, 且筆劃簡單, 但同一數(shù)字寫法卻千差萬別, 全世界的各個國家各個地區(qū)的人都在用, 則其書寫上帶有區(qū)域特性, 很難做出能夠兼顧世界各種寫法的、 識別率極高的通用性數(shù)字識別系統(tǒng)。3)特征庫的訓(xùn)練不夠, 導(dǎo)致識別率不高。手寫數(shù)字識別的研究不但存在很大的應(yīng)用價值, 由于手寫數(shù)字識別本身的特點, 對它的研究也存在著重要的理論價值

9、: 1) 阿拉伯?dāng)?shù)字作為唯一被世界各國通用的符號, 因此對手寫體數(shù)字識別的研究基本上與文化背景無關(guān), 各地的研究工作者能夠說是基于同一平臺開展工作的, 有利于研究的比較和探討。2) 手寫數(shù)字識別應(yīng)用廣泛, 如稅表系統(tǒng), 銀行支票自動處理和郵政編碼自動識別等。在以前, 這些工作需要大量的手工錄入, 投入的人力物力都相對較多, 而且勞動強度較大。為了適應(yīng)無紙化辦公的需要, 大大提高工作效率, 研究實現(xiàn)手寫數(shù)字識別系統(tǒng)是必須要做的。3) 由于數(shù)字類別只有0-9共10 個, 比其它字符識別率較高, 可將其用于驗證新的理論或做深入的分析研究。許多機器學(xué)習(xí)和模式識別領(lǐng)域的新理論和算法都是先用手寫數(shù)字識別進(jìn)

10、行檢驗, 驗證其理論的有效性, 然后才會將其應(yīng)用到更為復(fù)雜的領(lǐng)域當(dāng)中。在這方面的典型例子就是人工神經(jīng)網(wǎng)絡(luò)和支持向量機。4) 手寫數(shù)字的識別方法很容易將其推廣到其它一些相關(guān)的問題上, 如對英文之類拼音文字的識別。事實上, 有許多學(xué)者就是把數(shù)字和英文字母的識別放在一起研究的。在過去的數(shù)幾年中, 研究者提出了許許多多的識別方法, 按提取的數(shù)字特征的不同, 能夠?qū)⑦@些方法分為兩類: 基于結(jié)構(gòu)特征的方法和基于統(tǒng)計特征的方法。統(tǒng)計特征一般包括點密度的測量、 矩、 特征區(qū)域等; 結(jié)構(gòu)特征一般包括圓、 端點、 交叉點、 筆劃、 輪廓等, 一般來說, 兩類特征各有優(yōu)勢。例如, 使用統(tǒng)計特征的分類器易于訓(xùn)練, 而

11、且對于使用統(tǒng)計特征的分類器, 在給定的訓(xùn)練集上能夠得到相對較高的識別率; 而結(jié)構(gòu)特征的主要優(yōu)點之一是能描述字符的結(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é)和計算機科學(xué)等相關(guān)內(nèi)容。經(jīng)過對圖像處理和識別算法進(jìn)行不斷地研究和實踐, 以降低誤識率和拒識率。本文主要介紹手寫數(shù)字

12、識別系統(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)缺點及今后工作展望等, 整篇文章通俗易懂, 條理清晰, 能夠使讀者輕松閱讀, 并理解實現(xiàn)過程。1 需求分析綜合用戶在實際應(yīng)用中的需求, 對系統(tǒng)的運作流程進(jìn)行了整理, 并經(jīng)過對流程的分析得出了如下的需求分析。1.1 功能需求分

13、析根據(jù)對用戶需求的分析, 系統(tǒng)應(yīng)包含以下功能: 數(shù)字的繪制在繪制數(shù)字的窗口中實現(xiàn)數(shù)字的手寫, 并對其坐標(biāo)值進(jìn)行保存, 利用復(fù)位按鈕可實現(xiàn)數(shù)字的清除工作。數(shù)字的預(yù)處理在手寫數(shù)字圖像識別系統(tǒng)中, 圖像的預(yù)處理跟一般圖像系統(tǒng)不同, 我們不需要對圖像進(jìn)行灰度化處理、 去噪處理等基本操作, 我們利用程序保存的坐標(biāo)值就能夠?qū)ι梢粡埗祷瘓D像, 相當(dāng)于圖像處理系統(tǒng)的二值化處理。特征的提取在第二步中我們得到了手寫數(shù)字的二值化圖像, 進(jìn)行特征提取前需要對此圖像的數(shù)據(jù)區(qū)域進(jìn)行定位, 在程序中我們遍歷此二值化圖像, 找到手寫數(shù)字區(qū)域的上、 下、 左、 右邊界, 重新生成一張數(shù)字圖片, 利用新生成的數(shù)字圖片分成8*

14、8的區(qū)域, 統(tǒng)計每個區(qū)域的目標(biāo)像素個數(shù)和整個小區(qū)域像素個數(shù), 計算目標(biāo)像素個數(shù)與整個小區(qū)域像素的比值, 得到64個特征值, 作為這個手寫數(shù)字的特征值。特征庫的訓(xùn)練我們需要訓(xùn)練一個特征庫, 作為識別的標(biāo)準(zhǔn)。系統(tǒng)中我們手寫一個數(shù)字提取出它的特征值, 再輸入此手寫數(shù)字, 將數(shù)字與這些特征值相對應(yīng)存儲到特征庫里面, 特征庫我們使用的是Access數(shù)據(jù)庫, 字段是數(shù)字及這個數(shù)字所對應(yīng)所有特征值。特征庫越豐富, 識別率越高。數(shù)字識別在手寫數(shù)字識別中, 我們使用的方法是模板匹配法, 其實質(zhì)就是提取出手寫數(shù)字的特征值, 利用這些特征值與特征庫的數(shù)字的特征值進(jìn)行比對, 找出待識別數(shù)字特征值與特征庫里存儲的特征值

15、最接近的數(shù)字, 作為識別結(jié)果。1.2 性能需求分析正確性: 根據(jù)手寫數(shù)字識別系統(tǒng)的設(shè)計流程, 流程中的每個步驟在系統(tǒng)中都必須有所體現(xiàn), 以保證程序的正確性。精確性: 根據(jù)手寫數(shù)字識別系統(tǒng)的應(yīng)用領(lǐng)域, 該系統(tǒng)的識別結(jié)果必須有很高的識別精度, 這樣才能真正的實現(xiàn)該系統(tǒng)的價值。效率性: 根據(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)行比較, 計算圖

16、像和模板特征量之間的距離, 用最小距離法判定所屬類。而模板匹配一般需要事先建立標(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)境中功能最為強大、 代碼效率最高的開發(fā)工共。利用VisualC+6.0能夠兩種方式編寫Win32應(yīng)用程序, 一種方式是基于Windows API的C編程方式, 另一種是基于MFC的C+編程方式。

17、本系統(tǒng)采用的是基于MFC的編程方式。2 手寫數(shù)字識別系統(tǒng)的設(shè)計與基本原理2.1 系統(tǒng)整體功能模塊設(shè)計整體模塊如圖2.1所示: 數(shù)字圖像的繪制數(shù)字圖像的繪制訓(xùn)練特征庫二值化處理特征提取數(shù)字識別主界面圖2.1 整體模塊2.2 手寫數(shù)字識別系統(tǒng)的基本原理下面分別介紹各部分工作的基本原理: 2.2.1 數(shù)字圖像的繪制手寫數(shù)字繪制功能的實現(xiàn)方案是: 經(jīng)過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)點是否

18、在CStatic控件上, 在的話程序?qū)⒋它c的坐標(biāo)值保存。手寫數(shù)字的繪制開始是鼠標(biāo)按下事件, 結(jié)束是以左鼠標(biāo)抬起為標(biāo)志。2.2.2 圖像的預(yù)處理圖像的預(yù)處理是為了突出手寫體數(shù)字的特征。在本次設(shè)計中主要包括: 圖像二值化處理。圖像的二值化處理就是將圖像上的像素點的灰度值設(shè)置為0或255, 也就是將整個圖像呈現(xiàn)出明顯的黑白效果。在手寫數(shù)字識別系統(tǒng)中, 我們在VC可視化編程界面中在一個固定大小的控件中手寫了一個數(shù)字, 在程序中獲得的只是以這個控件左上角為原點的一系列坐標(biāo)。在內(nèi)存中我們開辟一個大小跟這個控件區(qū)域大小相同的二維數(shù)組(以像素為單位, 即生成一張圖片的長跟寬跟這個矩形區(qū)域相等), 這樣內(nèi)存中圖

19、像的數(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)的容錯能力要求較高。特征

20、提取的目的就是從分析數(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)遵循以下原則: 特征應(yīng)能盡量包含字符的有用信息。特征的提取方法應(yīng)簡單而且提取快速。各個特征之間的相關(guān)性應(yīng)盡

21、可能小。特征數(shù)量盡可能少。特征應(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ù)字的特征

22、值, 然后再想程序輸入這個數(shù)字, 在程序中將此輸入數(shù)字與所有特征值相對應(yīng), 作為模板庫的一條記錄, 初始化模板庫之后, 就能夠?qū)κ謱憯?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)行比較, 計算

23、圖像和模板特征量之間的距離, 用最小距離法判定所屬類。模板匹配一般事先建立標(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,&p

24、oint);: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);/這樣得到的點就是以畫圖控件為坐標(biāo)系統(tǒng)了, 既是左上角(0,0)開始, 到(w,h)if(rect1.PtInRect(point)bBegin = true; /此參數(shù)確定手寫數(shù)字開始this-AddPointStack(point); /將數(shù)字開始點保存到堆棧中, 相當(dāng)于保存的是數(shù)字像素點在原始圖像中的坐標(biāo)值/AfxMessageBox

25、(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.Fo

26、rmat(%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(b

27、efPoint.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);:ScreenTo

28、Client(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.

29、手寫數(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é)點的后一個空結(jié)點b = true;elseb=false;AfxMessageBox(棧滿溢出);return b;3.手寫數(shù)字的清除void CNumShiBieDlg:OnButtonRset() / TODO: Add yo

30、ur 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

31、w = 0 ,h = 0;w = rect.Width();h = rect.Height();if(w%4!=0)w = w+4-w%4; /按位補齊, 寬一定要是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 = poi

32、nt.y; /這個循環(huán)之后, xleft記錄了手寫數(shù)字區(qū)域最左邊的像素點的x坐標(biāo), ytop記錄了最上邊的像素點的y的坐標(biāo)/xrigth記錄了最右邊的點的x坐標(biāo),ybottom記錄了最下邊的點的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

33、 = 255;pdata(y*w+x)*3+1 = 255;pdata(y*w+x)*3+2 = 255; /注意坐標(biāo)變量y才是表示圖像的第幾行像素/鼠標(biāo)走過的點的坐標(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

34、(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ū)域矩陣中是存儲在第一行的, 因此平時我們讀取了一個位圖之后, 讀取到的像素值, 與我們實際看到的圖像

35、的像素是按行倒置的/而且當(dāng)我們用StretchDibits函數(shù)顯示位圖時, 數(shù)據(jù)區(qū)域指針一定要給成按行倒置的位圖數(shù)據(jù)矩陣xleft = xleft-1;ytop = ytop-1;xrigth = xrigth + 1;ybottom = ybottom + 1; /將四周擴展了一排像素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(pn

36、um,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

37、-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.biCompre

38、ssion=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ù)字

39、特征的提取是為了更好的實現(xiàn)數(shù)字的識別, 在此是經(jīng)過提取所繪制數(shù)字的像素特征即如前面所介紹的用目標(biāo)像素個數(shù)除以這個小區(qū)域內(nèi)總得像素個數(shù)的結(jié)果作為此區(qū)域的特征值, 共可得到64個特征值。在此經(jīng)過在函數(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,

40、 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)

41、的像素/if(w%8=0) & (h%8=0)else if(h%8!=0)&(w%8=0)int hc1 = h%8; /行不是8的倍數(shù), 最上面那一行單元格單獨考慮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);elsepFeaturejish

42、u+ = 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 ; /記錄一

43、行方格內(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 w

44、c = (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)pFeaturejish

45、u+ = 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

46、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

47、 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;D

48、ata 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 =

49、 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)AfxMessa

50、geBox(e.ErrorMessage();rsetPtr-Close();rsetPtr = NULL;connPtr-Close();connPtr = NULL;AfxMessageBox(初始化成功!);3.4 數(shù)字的識別點擊系統(tǒng)界面上的特征識別按鈕即可實現(xiàn)手寫數(shù)字的識別, 此系統(tǒng)主要是經(jīng)過函數(shù)OnButton64shibie() 來實現(xiàn)手寫數(shù)字的識別, 識別過程即和Access數(shù)據(jù)庫連接后把所繪制數(shù)字的64個特征值與模板庫里面的每個特征值進(jìn)行比較, 得出它們之間的距離, 哪一個距離最短則相對應(yīng)的模板庫里面的數(shù)字即為識別的結(jié)果, 識別結(jié)果會經(jīng)過彈出對話框來顯示, 如圖3.5所示。圖3

51、.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=M

52、icrosoft.Jet.OLEDB.4.0;Data Source=Feature.mdb,_T(),_T(),adModeUnknown);catch(_com_error e)AfxMessageBox(e.ErrorMessage();CString strSql;strSql = select * from Feature64 ;m_rsetPtr.CreateInstance(_uuidof(Recordset);m_rsetPtr-Open(_bstr_t(strSql),m_connPtr.GetInterfacePtr(), adOpenStatic , adLockOpti

53、mistic ,adCmdText);/利用MFCADO技術(shù)連接數(shù)據(jù)庫, 而且建立記錄集對象。int count = 0;/double *df = new double64;_variant_t va;if(!m_rsetPtr-BOF)while(!m_rsetPtr-adoEOF)count+;m_rsetPtr-MoveNext();elsecount = 0;if(count0)_variant_t var; FNUM *pN = new FNUMcount;m_rsetPtr-MoveFirst();count = 0;while(!m_rsetPtr-adoEOF)var = m_rsetPtr-GetCollect(Num);pNcount.num = var.lVal;double d64;for(int

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論