基於KNN的手寫體識別和數碼管數字識別

2021-08-09 15:06:15 字數 1500 閱讀 6312

大神符識別主要有數碼管數字和手寫體數字兩種

數碼管:

1.先進行整副影象的

處理,可以看出數碼管紅色很明顯,所以可以進行影象通道分離,然後對紅色通道二值化

效果: 

2.進行輪廓提取(findcontours),通過大小形狀來濾除小的雜訊

3.由於大神符的打擊需要順序,所以要對提取的輪廓進行排序,排序的方法是通過x座標的大小

4.利用穿線法進行提取後的數碼管字型的識別,所謂穿線法就是在提取的字型的(height/3),(2*height/3),(width/2)位置處畫3條線,然後數交點個數和位置進行分類。

我用的是提取出那三條線位置處的行列矩陣,函式是mat.rowrange(x,x+1) 

判斷的效果 

手寫字型:

1.手寫體的預處理和數碼管差不多,進行二值化,膨脹腐蝕,輪廓提取

2.識別方法用的是knn方法,knn是通過對大量測試資料分類,比如0-9這10種數字各50張分類為10份,貼上標籤0-10,用knn.train(traindata,trainclasses,mat(), false, k );進行訓練,其中的traindata是訓練樣本矩陣(n*m)n為樣本數,及矩陣行數,m是單個樣本的特徵值,這裡的特徵值是把單個字元的畫素值用mat row2=roi.reshape(0,1);//把矩陣轉至成行得到的,trainclass是乙個標籤矩陣每乙個標籤一行,traindata的目的是進行監督學習,告訴機器哪類特徵對應哪類標籤,然後就可以通過knn.findneast來通過樣本的特徵對應相應的標籤

然後在檢測的時候用float result=knn.find_nearest(row2,k);來進行矩陣臨近值的分類,比如我識別到row2這個矩陣有k個臨近值(k是引數自己設的,k越大精度越高但是速度越慢)(識別臨近值是通過匹配歸一化後的矩陣的畫素點得到的roi.convertto(roi,cv_32fc1,0.0039215);//把【0-255】進行矩陣歸一化到【0-1】

mat row2=roi.reshape(0,1);//把矩陣轉至成行

),然後對標籤進行投票,比如有5個臨近值k,3票1,1票2,一票3,那麼就分類為票數最多的1

3.最後就是對數碼管數字和手寫體數字的匹配了(這個不難)

最後發現knn的識別率與樣本數量(越大越精確),k值大小(越大越精確),但是速度會越慢,knn比較雞肋,識別率在90%吧大概,但是對於9個數字的大神符大概有一半的有乙個手寫體數字識別不了8個沒問題,一半完全正確

最終匹配效果

KNN手寫體數字識別

思路 首先這是乙個通過knn分類來完成的數字識別,資料集的格式全部是經過處理後的32x32de1二進位制數字矩陣,把乙個樣本 32x32 轉化為1x1024的向量,即一行代表乙個樣本,然後把訓練樣本也轉化為乙個數字矩陣,每次輸入乙個測試集都與訓練集的矩陣進行作差,然後平方和開根號,最後將每乙個輸入的...

使用kNN實現手寫體識別

knn的總結 本質就是使用測試與樣本進行比較,找到k個最近的,在k個中選擇概率出現最高的那乙個,把數字記錄下來,這個數字就是最終目標。步驟如下 1 資料的載入。注意是隨機數的載入 有4組,分別為訓練資料,訓練標籤,測試,測試標籤 2 計算測試與訓練的距離 3 計算k個最近的 實際上就是排序 4 將得...

編寫knn演算法實現手寫體識別

knn演算法的核心思想是如果乙個樣本在特徵空間中的k個最相鄰的樣本中的大多數屬於某乙個類別,則該樣本也屬於這個類別,並具有這個類別上樣本的特性。該方法在確定分類決策上只依據最鄰近的乙個或者幾個樣本的類別來決定待分樣本所屬的類別。knn方法在類別決策時,只與極少量的相鄰樣本有關。由於knn方法主要靠周...