OpenCV手寫數字字元識別 基於k近鄰演算法

2021-07-23 09:47:52 字數 2994 閱讀 7452



本程式主要參照**,《基於opencv的離線手寫字元識別技術》實現了,對於手寫阿拉伯數字的識別工作。識別工作分為三大步驟:預處理,特徵提取,分類識別。預處理過程主要找到影象的roi部分子影象並進行大小的歸一化處理,特徵提取將影象轉化為特徵向量,分類識別採用k-近鄰分類方法進行分類處理,最後根據分類結果完成識別工作。

程式採用microsoft visual studio 2010與opencv2.4.4在windows 7-64位旗艦版系統下開發完成。並在windows xp-32位系統下測試可用。

主流程圖

細化流程圖:

1.   預處理

預處理的過程就是找到影象的roi區域的過程,如下圖所示:

首先找到數字的邊界框,然後大小歸一化數字,主要流程如下圖所示:

主要**:

iplimage

preprocessing(iplimage*imgsrc,int

new_width,int

new_height)

2.   特徵提取

在拿到roi影象減少了資訊量之後,就可以直接用作為向量矩陣作為輸入:

void

basicocr::getdata()

//process file

prs_image =preprocessing(src_image,size,size); //

生成訓練矩陣,每個影象作為乙個向量

cvgetrow(trainclasses, &row,i*train_samples +j);

cvset(&row,cvrealscalar(i));

//set data

cvgetrow(traindata, &row,i*train_samples +j);

iplimage*img = cvcreateimage(cvsize( size, size ),

ipl_depth_32f, 1 );

//轉換換

8 bits image to 32

位浮點數取值區間為

[0,1]

//scale = 0.0039215 = 1/255; 

cvconvertscale(&prs_image,img, 0.0039215, 0);

cvgetsubrect(img, &data,cvrect(0,0,size,size));

cvmat

row_header, *row1;

//convert data matrix sizexsize to vecor

row1 =cvreshape( &data, &row_header, 0, 1 );

cvcopy(row1, &row,null); }

} }3.   分類識別

識別方法採用knn近鄰分類法。這個演算法首先貯藏所有的訓練樣本,然後通過分析(包括選舉,計算加權和等方式)乙個新樣本周圍k個最近鄰以給出該樣本的相應值。這種方法有時候被稱作「基於樣本的學習」,即為了**,我們對於給定的輸入搜尋最近的已知其相應的特徵向量。

k最近鄰(k-nearest neighbor,knn)分類演算法,是乙個理論上比較成熟的方法,也是最簡單的機器學習演算法之一。該方法的思路是:如果乙個樣本在特徵空間中的k個最相似(即特徵空間中最鄰近)的樣本中的大多數屬於某乙個類別,則該樣本也屬於這個類別。knn演算法中,所選擇的鄰居都是已經正確分類的物件。該方法在定類決策上只依據最鄰近的乙個或者幾個樣本的類別來決定待分樣本所屬的類別。 knn方法雖然從原理上也依賴於極限定理,但在類別決策時,只與極少量的相鄰樣本有關。由於knn方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來確定所屬類別的,因此對於類域的交叉或重疊較多的待分樣本集來說,knn方法較其他方法更為適合。

識別工作主要有以下幾個步驟:

1. 初始化機器學習演算法,及其訓練

knn=new cvknearest( traindata, trainclasses, 0, false, k );

因為traindata, trainclasses資料已得到。訓練在cvknearest演算法初始化中已經完成

2. 識別

獲取識別測試的資料,testdata

result=knn->find_nearest(testdata,k,0,0,nearest,0);

result為返回的識別的結果

4.   實驗結果

在knn引數k=5,子影象向量大小選取128*128畫素,訓練樣本50副,測試樣本50副,系統誤識率為7.4%。對於使用者手寫阿拉伯數字2的識別結果為2,識別比較準確。

5.   未來的工作

本程式主要參照網上的一些例項完成了部署跟實驗工作,雖然僅僅完成了手寫阿拉伯數字的識別工作,但是字元識別的一些原理工作都是相同的,未來能夠從一下幾個方面進行提高:

1.      提高程式的識別準確率,從一些文獻實現的結果來看,簡單的模型結合大量的訓練樣本,往往效果比複雜的模型結合少量訓練樣本實現的效果好。

2.      擴充套件程式的功能,從實現簡單的字元到最終實現識別手寫漢字等。

8.手寫字元識別的複雜版本,這個增加了一些opengl技術,程式比較複雜

手寫字元識別

個人認為,主要原因在於資料的收集較為困難,合成的方式不是很適合手寫字元的生成。第二,手寫字元存在過分和粘連等各種情況,但是現階段的技術而言,只要資料足夠,可以採用lstm ctc的方式去解決,不單獨獲取單個字元,而是直接採用行識別。手寫字元識別要想使用到產品中,關鍵還是要找好具體的業務點,比如,個人...

opencv 手寫選擇題閱卷 二 字元識別

opencv 手寫選擇題閱卷 二 字元識別 基本步驟 一,識別函式接受一般64x64的灰度影象 二,二值化並反色為黑底白字 三,找出字元的最小包圍矩形,並大小歸一化為32x32 四,計算影象的hog特徵 五,用svm分類器對hog特徵進行識別,從而確定當前影象屬於abcd還是空白 整個識別 還是比較...

使用kNN實現手寫字元識別

首先,我們的資料集分為訓練集和測試集,訓練集中含有將近2000個資料文件 在這個文件中將乙個32 32的向量圖 故為了在計算機中進行處理,我們需要先開啟檔案,迴圈讀出檔案前32行,並將每行的頭32個字元值儲存在numpy陣列中,最後返回陣列,如下 def img2vector filename re...