版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
手寫數(shù)字辨認系統(tǒng)設計與實現(xiàn)摘要本手寫數(shù)字辨認系統(tǒng)是一種以VISUALSTUDIOC++6.0為編譯環(huán)境,使用MFC進行圖形圖像界面開發(fā)系統(tǒng)。重要功能是通過在點擊手寫數(shù)字辨認菜單下繪制數(shù)字標簽彈出繪制數(shù)字窗口中完畢數(shù)字手寫,在此窗口中可以進行數(shù)字保存及清屏,然后通過文獻菜單中打開標簽打開所繪制數(shù)字,從而進行數(shù)字預解決,其中涉及灰度化及二值化解決,然后進行特性提取,最后實現(xiàn)數(shù)字辨認。本系統(tǒng)界面設計和諧,流程對的,功能也較為完善。實驗成果表白,本系統(tǒng)具備較高辨認率。核心詞:繪制數(shù)字;預解決;特性提取;特性庫;數(shù)字辨認目錄前言 1概述 21需求分析 41.1功能需求分析 41.2性能需求分析 41.3數(shù)據(jù)需求分析 51.4有關軟件簡介 52手寫數(shù)字辨認系統(tǒng)設計與基本原理 62.1系統(tǒng)整體功能模塊設計 62.2手寫數(shù)字辨認系統(tǒng)基本原理 62.2.1數(shù)字圖像繪制 62.2.2圖像預解決 62.2.3圖像特性提取 72.2.4特性庫建立 82.2.5圖像數(shù)字辨認 83手寫數(shù)字辨認系統(tǒng)程序設計 83.1數(shù)字圖像繪制 83.2數(shù)字特性提取 153.3模板特性庫建立 183.4數(shù)字辨認 20總結 23道謝 24參照文獻 25前言自上世紀六十年代以來,計算機視覺與圖像解決越來越受到人們關注,并逐漸成為一門重要學科領域。而作為它們研究對象數(shù)字圖像,也由于它具有研究目的豐富信息而成為越來越重要研究對象。圖像辨認目的是用計算機自動完畢某些信息解決,用來代替人工去解決圖像分類及辨認任務。手寫數(shù)字辨認是圖像辨認學科下一種分支,是圖像解決和模式辨認領域研究課題之一,由于其具備很強實用性始終是近年來研究熱點。由于手寫體數(shù)字隨意性很大,例如,筆畫粗細,字體大小,傾斜等等都直接影響到字符對的辨認,因此手寫體數(shù)字辨認是一種很有挑戰(zhàn)性課題。在過去數(shù)十年中,研究者們提出了許多辨認辦法,獲得了較大成果。手寫體數(shù)字辨認實用性很強,在大規(guī)模數(shù)據(jù)記錄(如例行年檢,人口普查),財務,稅務,郵件分揀等等應用領域中均有遼闊應用前景。本課題擬研究手寫體數(shù)字辨認理論和辦法,開發(fā)一種小型手寫體數(shù)字辨認系統(tǒng)。在研究手寫體數(shù)字辨認理論和辦法基本上,開發(fā)這樣一種小型手寫體數(shù)字辨認系統(tǒng)需要完畢如下重要方面研究與設計工作:手寫數(shù)字繪制問題、數(shù)字預解決問題、特性提取問題、特性庫建立問題、數(shù)字辨認問題。概述此手寫數(shù)字辨認系統(tǒng)需要實現(xiàn)手寫數(shù)字繪制功能、手寫數(shù)字特性提取功能、數(shù)字模板特性庫建立功能以及手寫數(shù)字辨認功能。在近幾年國內外對手寫數(shù)字辨認系統(tǒng)研究已經(jīng)獲得了進展,某些新理論例如基于Hopfield神經(jīng)網(wǎng)絡、基于小波技術、基于BP神經(jīng)網(wǎng)絡以及支持向量機研究應用在建立手寫數(shù)字辨認系統(tǒng)平臺,并且在多數(shù)數(shù)據(jù)庫中獲得了較好測試成果。但是當前依然存在亟需進一步研究解決問題:1)辨認精確度需要達到較好水平2)辨認效率要達到很高水平。數(shù)字辨認輸入數(shù)據(jù)普通是很大,而高精度與高速度是互相矛盾。這些難點存在因素是:1)數(shù)字筆劃簡樸,并且其筆劃差別相對較小,字形相差不大,使得精確區(qū)別某些數(shù)字有某些困難;2)數(shù)字雖然只有10種,且筆劃簡樸,但同一數(shù)字寫法卻千差萬別,全世界各個國家各個地區(qū)人都在用,則其書寫上帶有區(qū)域特性,很難做出可以兼顧世界各種寫法、辨認率極高通用性數(shù)字辨認系統(tǒng)。3)特性庫訓練不夠,導致辨認率不高。手寫數(shù)字辨認研究不但存在很大應用價值,由于手寫數(shù)字辨認自身特點,對它研究也存在著重要理論價值:1)阿拉伯數(shù)字作為唯一被世界各國通用符號,因此對手寫體數(shù)字辨認研究基本上與文化背景無關,各地研究工作者可以說是基于同一平臺開展工作,有助于研究比較和探討。2)手寫數(shù)字辨認應用廣泛,如稅表系統(tǒng),銀行支票自動解決和郵政編碼自動辨認等。在此前,這些工作需要大量手工錄入,投入人力物力都相對較多,并且勞動強度較大。為了適應無紙化辦公需要,大大提高工作效率,研究實現(xiàn)手寫數(shù)字辨認系統(tǒng)是必要要做。3)由于數(shù)字類別只有0-9共10個,比其她字符辨認率較高,可將其用于驗證新理論或做進一步分析研究。許多機器學習和模式辨認領域新理論和算法都是先用手寫數(shù)字辨認進行檢查,驗證其理論有效性,然后才會將其應用到更為復雜領域當中。在這方面典型例子就是人工神經(jīng)網(wǎng)絡和支持向量機。4)手寫數(shù)字辨認辦法很容易將其推廣到其他某些有關問題上,如對英文之類拼音文字辨認。事實上,有許多學者就是把數(shù)字和英文字母辨認放在一起研究。在過去數(shù)幾年中,研究者提出了許許多多辨認辦法,按提取數(shù)字特性不同,可以將這些辦法分為兩類:基于構造特性辦法和基于記錄特性辦法。記錄特性普通涉及點密度測量、矩、特性區(qū)域等;構造特性普通涉及圓、端點、交叉點、筆劃、輪廓等,普通來說,兩類特性各有優(yōu)勢。例如,使用記錄特性分類器易于訓練,并且對于使用記錄特性分類器,在給定訓練集上可以得到相對較高辨認率;而構造特性重要長處之一是能描述字符構造,在辨認過程中能有效地結合幾何和構造知識,因而可以得到可靠性較高辨認成果。在本次設計中使用是記錄特性?;谝陨纤觯敬萎厴I(yè)設計課題為手寫數(shù)字辨認系統(tǒng)設計與實現(xiàn)。其功能是將人工手繪數(shù)字圖像轉換成可編輯文本信息。該系統(tǒng)涉及手寫數(shù)字繪制模塊、圖像預解決模塊、特性提取模塊、訓練模塊和辨認模塊。涉及模式辨認、圖像解決、人工智能、記錄學、心理學和計算機科學等有關內容。通過對圖像解決和辨認算法進行不斷地研究和實踐,以減少誤識率和拒識率。本文重要簡介手寫數(shù)字辨認系統(tǒng)設計與實現(xiàn),一方面需要理解手寫數(shù)字辨認系統(tǒng)現(xiàn)階段發(fā)展狀況和研究現(xiàn)狀,然后對系統(tǒng)進行分析,重要從功能需求分析、性能需求分析、數(shù)據(jù)需求分析和有關軟件簡介四方面入手,從而使得對系統(tǒng)有初步結識,然后對系統(tǒng)整體設計模塊進行簡介,進而對系統(tǒng)各個功能模塊詳細設計原理進行詳細簡介,之后對本次所設計出系統(tǒng)進行簡介并對有關代碼進行闡明,最后總結本系統(tǒng)優(yōu)缺陷及此后工作展望等,整篇文章通俗易懂,條理清晰,可以使讀者輕松閱讀,并理解實現(xiàn)過程。1需求分析綜合顧客在實際應用中需求,對系統(tǒng)運作流程進行了整頓,并通過對流程分析得出了如下需求分析。1.1功能需求分析依照對顧客需求分析,系統(tǒng)應包括如下功能:數(shù)字繪制在繪制數(shù)字窗口中實現(xiàn)數(shù)字手寫,并對其坐標值進行保存,運用復位按鈕可實現(xiàn)數(shù)字清除工作。數(shù)字預解決在手寫數(shù)字圖像辨認系統(tǒng)中,圖像預解決跟普通圖像系統(tǒng)不同,咱們不需要對圖像進行灰度化解決、去噪解決等基本操作,咱們運用程序保存坐標值就可以對生成一張二值化圖像,相稱于圖像解決系統(tǒng)二值化解決。特性提取在第二步中咱們得到了手寫數(shù)字二值化圖像,進行特性提取前需要對此圖像數(shù)據(jù)區(qū)域進行定位,在程序中咱們遍歷此二值化圖像,找到手寫數(shù)字區(qū)域上、下、左、右邊界,重新生成一張數(shù)字圖片,運用新生成數(shù)字圖片提成8*8區(qū)域,記錄每個區(qū)域目的像素個數(shù)和整個社區(qū)域像素個數(shù),計算目的像素個數(shù)與整個社區(qū)域像素比值,得到64個特性值,作為這個手寫數(shù)字特性值。特性庫訓練咱們需要訓練一種特性庫,作為辨認原則。系統(tǒng)中咱們手寫一種數(shù)字提取出它特性值,再輸入此手寫數(shù)字,將數(shù)字與這些特性值相相應存儲到特性庫里面,特性庫咱們使用是Access數(shù)據(jù)庫,字段是數(shù)字及這個數(shù)字所相應所有特性值。特性庫越豐富,辨認率越高。數(shù)字辨認在手寫數(shù)字辨認中,咱們用法是模板匹配法,其實質就是提取出手寫數(shù)字特性值,運用這些特性值與特性庫數(shù)字特性值進行比對,找出待辨認數(shù)字特性值與特性庫里存儲特性值最接近數(shù)字,作為辨認成果。1.2性能需求分析對的性:依照手寫數(shù)字辨認系統(tǒng)設計流程,流程中每個環(huán)節(jié)在系統(tǒng)中都必要有所體現(xiàn),以保證程序對的性。精準性:依照手寫數(shù)字辨認系統(tǒng)應用領域,該系統(tǒng)辨認成果必要有很高辨認精度,這樣才干真正實現(xiàn)該系統(tǒng)價值。效率性:依照該系統(tǒng)應用領域可知,系統(tǒng)一旦投入應用需要解決大量數(shù)據(jù),因此對系統(tǒng)解決速度也有很高規(guī)定。1.3數(shù)據(jù)需求分析依照手寫數(shù)字辨認系統(tǒng)設計環(huán)節(jié)可知該系統(tǒng)采用是模板匹配法進行手寫體數(shù)字辨認。模板匹配法是圖像辨認中最具備代表性辦法之一。它是將從待辨認圖像提取若干特性量與模板相應特性量進行比較,計算圖像和模板特性量之間距離,用最小距離法鑒定所屬類。而模板匹配普通需要事先建立原則模板庫。這里,模板庫中原則模板是數(shù)字樣本特性向量。特性庫存儲是運用Access數(shù)據(jù)庫,并且運用MFCADO技術連接數(shù)據(jù)庫,不需要進行硬件配備。數(shù)據(jù)庫如圖1.1所示。圖1.1數(shù)據(jù)庫1.4有關軟件簡介本課題是基于VisualC++6.0,它是Microsoft公司開發(fā)VisualStudio集成開發(fā)環(huán)境中功能最為強大、代碼效率最高開發(fā)工共。運用VisualC++6.0可以兩種方式編寫Win32應用程序,一種方式是基于WindowsAPIC編程方式,另一種是基于MFCC++編程方式。本系統(tǒng)采用是基于MFC編程方式。2手寫數(shù)字辨認系統(tǒng)設計與基本原理2.1系統(tǒng)整體功能模塊設計整體模塊如圖2.1所示:數(shù)字圖像繪制數(shù)字圖像繪制訓練特性庫二值化解決特性提取數(shù)字辨認主界面圖2.1整體模塊2.2手寫數(shù)字辨認系統(tǒng)基本原理下面分別簡介各某些工作基本原理:2.2.1數(shù)字圖像繪制手寫數(shù)字繪制功能實現(xiàn)方案是:通過VisualC++中CStatic控件來建立畫布,用MFC中封裝類CDC實現(xiàn)手寫數(shù)字功能。在對話框中,響應鼠標事件消息,分別是鼠標按下事件MouseDown,鼠標移動事件MouseMove,鼠標抬起事件MouseUp,判斷當前鼠標點與否在CStatic控件上,在話程序將此點坐標值保存。手寫數(shù)字繪制開始是鼠標按下事件,結束是以左鼠標抬起為標志。2.2.2圖像預解決圖像預解決是為了突出手寫體數(shù)字特性。在本次設計中重要涉及:圖像二值化解決。圖像二值化解決就是將圖像上像素點灰度值設立為0或255,也就是將整個圖像呈現(xiàn)出明顯黑白效果。在手寫數(shù)字辨認系統(tǒng)中,咱們在VC可視化編程界面中在一種固定大小控件中手寫了一種數(shù)字,在程序中獲得只是以這個控件左上角為原點一系列坐標。在內存中咱們開辟一種大小跟這個控件區(qū)域大小相似二維數(shù)組(以像素為單位,即生成一張圖片長跟寬跟這個矩形區(qū)域相等),這樣內存中圖像數(shù)據(jù)區(qū)域二維數(shù)組就跟手寫區(qū)域坐標相似,咱們再取出手寫區(qū)域坐標值,將這些坐標值相應到圖像圖像數(shù)據(jù)區(qū)域中,并且將它灰度值置為255(白色),將圖像數(shù)據(jù)區(qū)域其他坐標值下灰度值置為0(黑色),這樣咱們就得到了一張手寫數(shù)字二值化圖像。在數(shù)字圖像解決中,二值圖像占有非常重要地位,圖像二值化有助于圖像進一步解決,使圖像變得簡樸,并且數(shù)據(jù)量減小,能凸顯出感興趣目的輪廓。2.2.3圖像特性提取若直接把預解決后數(shù)據(jù)作為輸入量,進行分類計算時數(shù)據(jù)時數(shù)據(jù)量大,同步由于手寫字體多樣化及圖像自身和預解決過程中附帶某些干擾影響,對系統(tǒng)容錯能力規(guī)定較高。特性提取目就是從分析數(shù)字拓撲構造入手,把它某些構造特性提取出來,使數(shù)字位移、大小變化、字形畸形等干擾相對較小,也就是把那些反映數(shù)字特性核心信息提供應系統(tǒng),這樣就等于間接地增長了系統(tǒng)容錯能力,并且通過特性提取后數(shù)據(jù)量也大大減少了,這樣就提高了辨認效率。手寫數(shù)字辨認特性提取極大限度地影響著分類器設計和性能,以及辨認效果和效率。為了保證所規(guī)定分類辨認對的率和節(jié)約資源,但愿根據(jù)至少特性達到所規(guī)定分類辨認對的率。在進行手寫數(shù)字辨認過程中,特性提取應遵循如下原則:特性應能盡量包括字符有用信息。特性提取辦法應簡樸并且提取迅速。各個特性之間有關性應盡量小。特性數(shù)量盡量少。特性應有較好抗干擾能力。考慮到算法實時性、迅速性和精確性,在本次設計中采用是一種簡樸模板法對待測樣本進行特性提取。環(huán)節(jié)為:1、搜索數(shù)據(jù)區(qū)域,找出手寫體數(shù)字上下左右邊界。2、將搜索到數(shù)字區(qū)域平提成8*8共64個社區(qū)域。3、計算8*8每一種社區(qū)域中白色像素所占比例,即用每一種社區(qū)域內白色像素個數(shù)除以該社區(qū)域面積總數(shù)(總像素數(shù)),即得特性值,第一行8個比例值是特性前8特性值,第二行相應著特性9~16個,以此類推。2.2.4特性庫建立在手寫數(shù)字辨認系統(tǒng)中,咱們一方面要建立一種特性庫,咱們手寫一種數(shù)字,并且獲得這個數(shù)字特性值,然后再想程序輸入這個數(shù)字,在程序中將此輸入數(shù)字與所有特性值相相應,作為模板庫一條記錄,初始化模板庫之后,就可以對手寫數(shù)字進行辨認,在辨認過程中咱們不斷豐富模板庫,如果手寫數(shù)字辨認成功則不需要將此數(shù)字存儲到模板庫中,如果辨認失敗就需要將此數(shù)字存儲到模板庫中,這樣咱們模板庫將越來越豐富。2.2.5圖像數(shù)字辨認在手寫數(shù)字圖像特性提取結束后,即可進行數(shù)字辨認。這也是手寫數(shù)字辨認系統(tǒng)設計最后一種環(huán)節(jié),在本次設計中采用模板匹配法進行手寫體數(shù)字辨認。模板匹配法是圖像辨認中最具備代表性辦法之一。它是將從待辨認圖像提取若干特性量與模板相應特性量進行比較,計算圖像和模板特性量之間距離,用最小距離法鑒定所屬類。模板匹配普通事先建立原則模板庫。這里,模板庫中原則模板是數(shù)字樣本特性向量。詳細過程是:對于一種待測試樣本X,計算X和訓練集中某樣本Xj(0<j<m,m為訓練集中樣本數(shù))之間距離。循環(huán)計算待測樣本和訓練集中各已知樣本之間距離,比較所有距離值,找出距離待測樣本近來已知樣本,其中所相應樣本所屬類別就是待測樣本X所屬類別。3手寫數(shù)字辨認系統(tǒng)程序設計本次設計使用VisualC++語言來實現(xiàn)該系統(tǒng),其顧客界面分別簡介如下:3.1數(shù)字圖像繪制運營程序后得到系統(tǒng)初始界面,如圖3.1所示。在繪圖區(qū)域通過響應鼠標事件來完畢手寫數(shù)字繪制問題,如圖3.2所示,通過 CPen創(chuàng)立對象pen并進行有關值設立如pen(PS_SOLID,3,RGB(0,0,255))可以創(chuàng)立出不同顏色和粗細畫筆,消息響應事件是通過函數(shù)OnLButtonDown(UINTnFlags,CPointpoint)、OnMouseMove(UINTnFlags,CPointpoint)、OnLButtonUp(UINTnFlags,CPointpoint)來實現(xiàn)。手寫數(shù)字繪制過程中通過建立堆棧即可實現(xiàn)手寫數(shù)字保存,所用函數(shù)為AddPointStack(constCPoint&point)。繪制數(shù)字后還可以對所繪制數(shù)字進行清除,通過函數(shù)OnButtonRset()即可實現(xiàn),點擊系統(tǒng)會面上復位按鈕即可實現(xiàn)此功能。點擊顯示按鈕即可得到二值化后黑白圖像,如圖3.3所示。圖3.1系統(tǒng)初始界面圖3.2手寫數(shù)字繪制圖3.3二值化成果詳細實當代碼為:1.手寫數(shù)字繪制voidCNumShiBieDlg::OnLButtonDown(UINTnFlags,CPointpoint){ CRectrect,rect1,rect2; CStringstr; this->GetClientRect(rect); m_ctlDrawNum.GetClientRect(rect1);//這個函數(shù)獲得坐標是相對于屏幕左上角而言,此矩形保存值都是相對于屏幕左上角而言 //m_DrawNum.GetClientRect(rect2);//此函數(shù)坐標是相對于本窗體客戶區(qū)而言,左上角坐標為(0,0) ::ClientToScreen(this->m_hWnd,&point); ::ScreenToClient(m_ctlDrawNum.m_hWnd,&point);//注意這里轉換,先將窗口坐標轉換成屏幕坐標,再將此坐標轉換成畫圖控件坐標系統(tǒng), str.Format("%d%d",point.x,point.y); //這樣得到點就是以畫圖控件為坐標系統(tǒng)了,既是左上角(0,0)開始,到(w,h) if(rect1.PtInRect(point)) { bBegin=true;//此參數(shù)擬定手寫數(shù)字開始 this->AddPointStack(point);//將數(shù)字開始點保存到堆棧中,相稱于保存是數(shù)字像素點在原始圖像中坐標值 //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指向是最后一種結點后一種空結點 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;//按位補齊,寬一定要是4倍數(shù)//windows下規(guī)定,位圖行像素個數(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; }//這個循環(huán)之后,xleft記錄了手寫數(shù)字區(qū)域最左邊像素點x坐標,ytop記錄了最上邊像素點y坐標 //xrigth記錄了最右邊點x坐標,ybottom記錄了最下邊點y坐標,這樣就可以得到數(shù)字區(qū)域寬跟長,以像素為單位 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;//注意坐標變量y才是表達圖像第幾行像素 } //鼠標走過點坐標值即是數(shù)字像素在數(shù)據(jù)矩陣中坐標值,這樣咱們把鼠標走過所有坐標值相應到圖像數(shù)據(jù)坐標值中灰度值設立成255,而背景色置為白 //這樣相稱于,將手寫數(shù)字區(qū)域當成一張數(shù)字圖片,將其從第一行到最后一行數(shù)據(jù)順序讀到內存中,因此咱們顯示時,一定要將此圖片數(shù)據(jù)區(qū)域按行轉置 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ù)據(jù)區(qū)域最后一行,而最后一行像素在位圖//文獻數(shù)據(jù)區(qū)域矩陣中是存儲在第一行,因此平時咱們讀取了一種位圖之后,讀取到像素值,與咱們實際看到圖像像素是按行倒置 //并且當咱們用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; 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ū)域矩形最左上角坐標,這里完畢了坐標系統(tǒng)轉換 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ù)字特性提取是為了更好實現(xiàn)數(shù)字辨認,在此是通過提取所繪制數(shù)字像素特性即如前面所簡介用目的像素個數(shù)除以這個社區(qū)域內總得像素個數(shù)成果作為此區(qū)域特性值,共可得到64個特性值。在此通過在函數(shù)Get64Feature(BYTE*pd,intw,inth)中調用函數(shù)GetOneFeature(intbrow,interow,intbcol,intecol,BYTE*pdata,intw)來實現(xiàn)數(shù)字特性提取功能。詳細實當代碼為:1.得到64個區(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個單元格 while(j<8)//j=0闡明是第一行單元格像素,依次類推 { intcc=0;//記錄一行方格內單元格個數(shù),共8個方格因此循環(huán)8次 while(cc<8) { pFeature[jishu++]=this->GetOneFeature(j*hc,(j+1)*hc,cc*wc,(cc+1)*wc,pd,w); cc++;//此時已經(jīng)記錄完一種單元格像素 } j++;//此時已經(jīng)記錄完一行單元格內像素 } }//if((w%8==0)&&(h%8==0)) elseif((h%8!=0)&&(w%8==0)) { inthc1=h%8;//行不是8倍數(shù),最上面那一行單元格單獨考慮 inthc=(h-hc1)/8; intwc=w/8; intjishu=0; intj=0;//列方向上共8個單元格 while(j<8)//j=0闡明是第一行單元格像素,依次類推 { intcc=0;//記錄一行方格內單元格個數(shù),共8個方格因此循環(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++;//此時已經(jīng)記錄完一行單元格內像素 } }//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個單元格 while(j<8)//j=0闡明是第一行單元格像素,依次類推 { intcc=0;//記錄一行方格內單元格個數(shù),共8個方格因此循環(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++;//此時已經(jīng)記錄完一行單元格內像素 } }/*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個單元格 while(j<8)//j=0闡明是第一行單元格像素,依次類推 { intcc=0;//記錄一行方格內單元格個數(shù),共8個方格因此循環(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++;//此時已經(jīng)記錄完一行單元格內像素 } }/*elseif((w%8!=0)&&(h%8!=0))*/ returnpFeature;}2.得到每個社區(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模板特性庫建立點擊系統(tǒng)界面上訓練按鈕即可實現(xiàn)特性庫建立,訓練次數(shù)越多特性庫越豐富,辨認成果就越精確。在此系統(tǒng)特性庫是存儲在Access數(shù)據(jù)庫中,如圖3.4所示。在此運用MFCADO技術連接數(shù)據(jù)庫,并且建立記錄集對象并通過函數(shù)OnButtonInitialize()來實現(xiàn)特性庫訓練。圖3.4特性庫詳細實當代碼為: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.訓練特性庫voidCNumShiBieDlg::OnButtonInitialize()//先顯示圖片再按此按鈕訓練{ //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ù)字辨認點擊系統(tǒng)界面上特性辨認按鈕即可實現(xiàn)手寫數(shù)字辨認,此系統(tǒng)重要是通過函數(shù)OnButton64shibie()來實現(xiàn)手寫數(shù)字辨認,辨認過程即和Access數(shù)據(jù)庫連接后把所繪制數(shù)字64個特性值與模板庫里面每個特性值進行比較,得出它們之間距離,哪一種距離最短則相相應模板庫里面數(shù)字即為辨認成果,辨認成果會通過彈出對話框來顯示,如圖3.5所示。圖3.5辨認成果詳細實當代碼為:voidCNumShiBieDlg::OnButton64shibie(){ //TODO:Addyourcontrolnotificationhandlercodehere intw=0,h=0; BYTE*pdata=this->GetNumData(&w,&h); double*pfeature=this->Get64Feature(pdata,w,h);//獲得64個特性值 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); //運用MFCADO技術連接數(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)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度車輛維修后安全性能評估與優(yōu)化改進合同
- 二零二五年度能源管理派遣員工服務合同
- 2025年度二零二五年度汽車抵押權回購合同樣本
- 2025年度附條件附條件房地產(chǎn)基金投資居間代理合同
- 2025年度汽車銷售經(jīng)紀人聘用合同
- 2025年度購房意向協(xié)議及新能源車輛充電樁安裝合同
- 二零二五年度消防工程設計咨詢與評審合同
- 2025年度電子產(chǎn)品批量采購合同甲方質量責任書
- 2025年農(nóng)作物種植科技示范工程總包合同
- 2025年壁櫥柜設計安裝合同
- EPC項目階段劃分及工作結構分解方案
- 《跨學科實踐活動4 基于特定需求設計和制作簡易供氧器》教學設計
- 術后病人燙傷不良事件PDCA循環(huán)分析
- 金字塔原理完整版本
- 隧道配電設備安裝與調試方案
- 2024年河北省中考數(shù)學試題(含答案解析)
- 新租賃準則(2024版)
- 家禽呼吸系統(tǒng)認知
- 《社區(qū)康復》課件-第九章 言語障礙患者的社區(qū)康復實踐
- 凸優(yōu)化在經(jīng)濟學與金融學中的應用
- 家譜、宗譜頒譜慶典講話
評論
0/150
提交評論