標籤:filter 回調 手寫 tor pre string sel data none
概述帶GUI介面的,基於python sklearn knn演算法的手寫數字辨識器,可用於識別手寫數字,訓練資料集為mnist。詳細代碼下載:http://www.demodashi.com/demo/13039.html前言
k-近鄰(kNN, k-NearestNeighbor)演算法是一種基本分類與迴歸方法,
通俗點來說,就是給定一個訓練資料集,對新的輸入執行個體,在訓練資料集中找到與該執行個體最鄰近的 k 個執行個體,這 k 個執行個體的多數屬於某個類,就把該輸入執行個體分為這個類。
python 第三方庫scikit-learn(sklearn)提供了knn的分類器。
MNIST手寫數字資料庫(Mixed National Institute of Standards and Technology database)包含
70000張手寫數字圖片。這些數字是通過美國國家統計局的員工和美國高校的學生收集的。每張圖片
都是28x28的灰階圖。
用mnist資料集訓練出一個knn分類器,對新輸入的手寫數字進行識別。
準備工作
1.安裝必要的第三方庫:
pip install scikit-learn
pip install numpy
pip install wxPython
安裝PIL,在以下地址下載PIL庫進行安裝:
http://effbot.org/media/downloads/PIL-1.1.7.win32-py2.7.exe
(或在http://effbot.org/downloads/ 中找到與你作業系統及python版本相對應
版本的PIL)
2.下載mnist資料集:
可以從以下地址下載mnist資料集。
http://yann.lecun.com/exdb/mnist/
如下:
項目結構圖
整體的項目結構十分簡單,一共兩個指令檔,一個是GUI介面指令碼(digit_gui.py),
一個是分類器指令碼(model.py)。
如下:
實現過程的部分代碼展示
1. 在model.py中匯入相關的庫:
import numpy as npimport osfrom PIL import Imageimport randomfrom sklearn.neighbors import KNeighborsClassifier as knnfrom sklearn.externals import joblib
2. 編寫model.py中的相關函數,
將圖片轉為向量:
def img2vec(fname): ‘‘‘將jpg等格式的圖片轉為向量‘‘‘ im = Image.open(fname).convert(‘L‘) im = im.resize((28,28)) tmp = np.array(im) vec = tmp.ravel() return vec
隨機抽取1000張圖片作為訓練集:
def split_data(paths): ‘‘‘隨機抽取1000張圖片作為訓練集‘‘‘ fn_list = os.llistdir(paths) X = [] y = [] d0 = random.sample(fn_list,1000) for i,name in enumerate(d0): y.append(name[0]) X.append(img2vec(name)) dataset = np.array([X,y]) return X,y
構建分類器:
def knn_clf(X_train,label): ‘‘‘構建分類器‘‘‘ clf = knn() clf.fit(X_train,label) return clf
儲存模型:
def save_model(model,output_name): ‘‘‘儲存模型‘‘‘ joblib.dump(model,ouotput_name)
3. 訓練模型:
X_train,y_label = split_data(file_path)clf = knn_clf(X_train,y_label)save_model(clf,‘mnist_knn1000.m‘)
4. 在digit_gui.py中編寫使用者介面:
匯入相關的庫:
import wxfrom collections import namedtuplefrom PIL import Imageimport osimport model
編寫介面:
class MainWindow(wx.Frame): def __init__(self,parent,title): wx.Frame.__init__(self,parent,title=title,size=(600,-1)) static_font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL) Size = namedtuple("Size",[‘x‘,‘y‘]) s = Size(100,50) sm = Size(100,25) self.fileName = None self.model = model b_labels = [u‘open‘,u‘run‘] TipString = [u‘選擇圖片‘, u‘識別數字‘] funcs = [self.choose_file,self.run] ‘‘‘create input area‘‘‘ self.in1 = wx.TextCtrl(self,-1,size = (2*s.x,3*s.y)) self.out1 = wx.TextCtrl(self,-1,size = (s.x,3*s.y)) ‘‘‘create button‘‘‘ self.sizer0 = wx.FlexGridSizer(rows=1, hgap=4, vgap=2) self.sizer0.Add(self.in1) buttons = [] for i,label in enumerate(b_labels): b = wx.Button(self, id = i,label = label,size = (1.5*s.x,s.y)) buttons.append(b) self.sizer0.Add(b) self.sizer0.Add(self.out1) ‘‘‘set the color and size of labels and buttons‘‘‘ for i,button in enumerate(buttons): button.SetForegroundColour(‘red‘) button.SetFont(static_font) button.SetToolTipString(TipString[i]) button.Bind(wx.EVT_BUTTON,funcs[i]) ‘‘‘layout‘‘‘ self.SetSizer(self.sizer0) self.SetAutoLayout(1) self.sizer0.Fit(self) self.CreateStatusBar() self.Show(True)
介面如下:
編寫控制項的回呼函數:
def run(self,evt): if self.fileName is None: self.raise_msg(u‘請選擇一幅圖片‘) return None else: model_path = os.path.join(origin_path,‘mnist_knn1000.m‘) clf = model.load_model(model_path) ans = model.tester(self.fileName,clf) self.out1.Clear() self.out1.write(str(ans)) def choose_file(self,evt): ‘‘‘choose img‘‘‘ dlg = wx.FileDialog( self, message="Choose a file", defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR ) if dlg.ShowModal() == wx.ID_OK: paths = dlg.GetPaths() dlg.Destroy() self.in1.Clear() self.in1.write(paths[0]) self.fileName = paths[0] im = Image.open(self.fileName) im.show() else: return None
運行效果
代碼下載:http://www.demodashi.com/demo/13039.html註:本文著作權歸作者,由demo大師發表,拒絕轉載,轉載需要作者授權
用python實現的的手寫數字辨識器