import tkinter as tk
import tkinter.filedialog as fd
import PIL.Image
import PIL.ImageTk
# 機械学習で使うモジュ-ル
import sklearn.datasets
import sklearn.svm
import PIL.Image
import numpy
# 画像ファイルを数値リストに変換
def imageToData(filename):
# 画像を8×8のグレ-スケ-ルに変換
grayImage = PIL.Image.open(filename).convert("L")
grayImage = grayImage.resize((8,8),PIL.Image.ANTIALIAS)
# その画像を表示
dispImage = PIL.ImageTk.PhotoImage(grayImage.resize((300,300)))
imageLabel.configure(image = dispImage)
imageLabel.image = dispImage
# 数値リストに変換
numImage = numpy.asarray(grayImage, dtype = float)
numImage = numpy.floor(16 - 16 * (numImage / 256))
numImage = numImage.flatten()
return numImage
# 数字を予測する
def predictDigits(data):
# 学習用デ-タを読み込む
digits = sklearn.datasets.load_digits()
# 機械学習する
clf = sklearn.svm.SVC(gamma = 0.001)
clf.fit(digits.data,digits.target)
# 予測結果を表示
n = clf.predict([data])
textLabel.configure(text = "この画像は"+str(n)+"です!")
# ファイルダイアログを開く
def openFile():
fpath = fd.askopenfilename()
if fpath:
# 画像ファイルを数値リストに変換
data = imageToData(fpath)
# 数字を予測
predictDigits(data)
# ウィンドウを作る
root = tk.Tk()
root.geometry("400x400")
btn = tk.Button(root, text="ファイルを開く", command = openFile )
imageLabel = tk.Label()
btn.pack()
imageLabel.pack()
# 予測結果を表示
textLabel = tk.Label(text="手書き数字を認識!")
textLabel.pack()
tk.mainloop()
aW1wb3J0IHRraW50ZXIgYXMgdGsKaW1wb3J0IHRraW50ZXIuZmlsZWRpYWxvZyBhcyBmZAppbXBvcnQgUElMLkltYWdlCmltcG9ydCBQSUwuSW1hZ2VUawoKIyAg5qmf5qKw5a2m57+S44Gn5L2/44GG44Oi44K444Ol77yN44OrCmltcG9ydCBza2xlYXJuLmRhdGFzZXRzCmltcG9ydCBza2xlYXJuLnN2bQppbXBvcnQgUElMLkltYWdlCmltcG9ydCBudW1weQoKI+OAgOeUu+WDj+ODleOCoeOCpOODq+OCkuaVsOWApOODquOCueODiOOBq+WkieaPmwpkZWYgaW1hZ2VUb0RhdGEoZmlsZW5hbWUpOgogICAgI+OAgOeUu+WDj+OCkjjDlzjjga7jgrDjg6zvvI3jgrnjgrHvvI3jg6vjgavlpInmj5sKICAgIGdyYXlJbWFnZSA9IFBJTC5JbWFnZS5vcGVuKGZpbGVuYW1lKS5jb252ZXJ0KCJMIikKICAgIGdyYXlJbWFnZSA9IGdyYXlJbWFnZS5yZXNpemUoKDgsOCksUElMLkltYWdlLkFOVElBTElBUykKCiAgICAjICDjgZ3jga7nlLvlg4/jgpLooajnpLoKICAgIGRpc3BJbWFnZSA9IFBJTC5JbWFnZVRrLlBob3RvSW1hZ2UoZ3JheUltYWdlLnJlc2l6ZSgoMzAwLDMwMCkpKQogICAgaW1hZ2VMYWJlbC5jb25maWd1cmUoaW1hZ2UgPSBkaXNwSW1hZ2UpCiAgICBpbWFnZUxhYmVsLmltYWdlID0gZGlzcEltYWdlCiAgICAgICAgCiAgICAj44CA5pWw5YCk44Oq44K544OI44Gr5aSJ5o+bIAogICAgbnVtSW1hZ2UgPSBudW1weS5hc2FycmF5KGdyYXlJbWFnZSwgZHR5cGUgPSBmbG9hdCkKICAgIG51bUltYWdlID0gbnVtcHkuZmxvb3IoMTYgLSAxNiAqIChudW1JbWFnZSAvIDI1NikpICAgIAogICAgbnVtSW1hZ2UgPSBudW1JbWFnZS5mbGF0dGVuKCkgICAgCiAgICAKICAgIHJldHVybiBudW1JbWFnZQoKIyAg5pWw5a2X44KS5LqI5ris44GZ44KLCmRlZiBwcmVkaWN0RGlnaXRzKGRhdGEpOgogICAgIyAg5a2m57+S55So44OH77yN44K/44KS6Kqt44G/6L6844KACiAgICBkaWdpdHMgPSBza2xlYXJuLmRhdGFzZXRzLmxvYWRfZGlnaXRzKCkKICAgICMgIOapn+aisOWtpue/kuOBmeOCiwogICAgY2xmID0gc2tsZWFybi5zdm0uU1ZDKGdhbW1hID0gMC4wMDEpCiAgICBjbGYuZml0KGRpZ2l0cy5kYXRhLGRpZ2l0cy50YXJnZXQpCiAgICAjICDkuojmuKzntZDmnpzjgpLooajnpLoKICAgIG4gPSBjbGYucHJlZGljdChbZGF0YV0pCiAgICB0ZXh0TGFiZWwuY29uZmlndXJlKHRleHQgPSAi44GT44Gu55S75YOP44GvIitzdHIobikrIuOBp+OBmSEiKQoKIyAg44OV44Kh44Kk44Or44OA44Kk44Ki44Ot44Kw44KS6ZaL44GPCmRlZiBvcGVuRmlsZSgpOgogICAgZnBhdGggPSBmZC5hc2tvcGVuZmlsZW5hbWUoKQogICAgaWYgZnBhdGg6CiAgICAgICAgIyAg55S75YOP44OV44Kh44Kk44Or44KS5pWw5YCk44Oq44K544OI44Gr5aSJ5o+bCiAgICAgICAgZGF0YSA9IGltYWdlVG9EYXRhKGZwYXRoKQogICAgICAgICMgIOaVsOWtl+OCkuS6iOa4rAogICAgICAgIHByZWRpY3REaWdpdHMoZGF0YSkKCgojICDjgqbjgqPjg7Pjg4njgqbjgpLkvZzjgosKcm9vdCA9IHRrLlRrKCkKcm9vdC5nZW9tZXRyeSgiNDAweDQwMCIpCgpidG4gPSB0ay5CdXR0b24ocm9vdCwgdGV4dD0i44OV44Kh44Kk44Or44KS6ZaL44GPIiwgY29tbWFuZCA9IG9wZW5GaWxlICkKCgppbWFnZUxhYmVsID0gdGsuTGFiZWwoKQoKCmJ0bi5wYWNrKCkKaW1hZ2VMYWJlbC5wYWNrKCkKCgojICDkuojmuKzntZDmnpzjgpLooajnpLoKdGV4dExhYmVsID0gdGsuTGFiZWwodGV4dD0i5omL5pu444GN5pWw5a2X44KS6KqN6K2YISIpCnRleHRMYWJlbC5wYWNrKCkKCnRrLm1haW5sb29wKCkK