Zwei Mal zuvor (1/3): https://qiita.com/tfull_tf/items/6015bee4af7d48176736 Letztes Mal (2/3): https://qiita.com/tfull_tf/items/968bdb8f24f80d57617e
Ganzer Code: https://github.com/tfull/character_recognition
Nachdem das Kana-Erkennungsmodell eine Stufe erreicht hat, in der es möglich ist, den Betrieb des Systems zu überprüfen, generieren wir ein Bild mit der GUI, laden es in das Modell und geben Zeichen aus.
Ich werde Tkinter verwenden, also installiere es.
# Mac +Für Homebrew
$ brew install tcl-tk
#Für Ubuntu Linux
$ sudo apt install python-tk
Erstellen Sie eine Leinwand und klicken Sie mit der linken Maustaste, um eine weiße Linie zu zeichnen, und klicken Sie mit der rechten Maustaste, um eine schwarze Linie zu zeichnen (eigentlich ein Radiergummi, da es sich um einen schwarzen Hintergrund handelt). Es sind zwei Schaltflächen vorbereitet, eine zum Erkennen der geschriebenen Zeichen und die andere zum Löschen (Ausfüllen von Schwarz) der geschriebenen Zeichen.
import tkinter
# from PIL import Image, ImageDraw
class Board:
def __init__(self):
self.image_size = 256
self.window = tkinter.Tk()
self.window.title("Kana-Eingabe")
self.frame = tkinter.Frame(self.window, width = self.image_size + 2, height = self.image_size + 40)
self.frame.pack()
self.canvas = tkinter.Canvas(self.frame, bg = "black", width = self.image_size, height = self.image_size)
self.canvas.place(x = 0, y = 0)
self.canvas.bind("<ButtonPress-1>", self.click_left)
self.canvas.bind("<B1-Motion>", self.drag_left)
self.canvas.bind("<ButtonPress-3>", self.click_right)
self.canvas.bind("<B3-Motion>", self.drag_right)
self.button_detect = tkinter.Button(self.frame, bg = "blue", fg = "white", text = "Anerkennung", width = 100, height = 40, command = self.press_detect)
self.button_detect.place(x = 0, y = self.image_size)
self.button_delete = tkinter.Button(self.frame, bg = "green", fg = "white", text = "Löschen", width = 100, height = 40, command = self.press_delete)
self.button_delete.place(x = self.image_size // 2, y = self.image_size)
# self.image = Image.new("L", (self.image_size, self.image_size))
# self.draw = ImageDraw.Draw(self.image)
def press_detect(self):
output = recognize(np.array(self.image).reshape(1, 1, self.image_size, self.image_size)) #Erkennen ist eine Funktion, die maschinelles Lernen erkennt
sys.stdout.write(output)
sys.stdout.flush()
def press_delete(self):
# self.canvas.delete("all")
# self.draw.rectangle((0, 0, self.image_size, self.image_size), fill = 0)
def click_left(self, event):
ex = event.x
ey = event.y
self.canvas.create_oval(
ex, ey, ex, ey,
outline = "white",
width = 8
)
# self.draw.ellipse((ex - 4, ey - 4, ex + 4, ey + 4), fill = 255)
self.x = ex
self.y = ey
def drag_left(self, event):
ex = event.x
ey = event.y
self.canvas.create_line(
self.x, self.y, ex, ey,
fill = "white",
width = 8
)
# self.draw.line((self.x, self.y, ex, ey), fill = 255, width = 8)
self.x = ex
self.y = ey
def click_right(self, event):
ex = event.x
ey = event.y
self.canvas.create_oval(
ex, ey, ex, ey,
outline = "black",
width = 8
)
# self.draw.ellipse((ex - 4, ey - 4, ex + 4, ey + 4), fill = 0)
self.x = event.x
self.y = event.y
def drag_right(self, event):
ex = event.x
ey = event.y
self.canvas.create_line(
self.x, self.y, ex, ey,
fill = "black",
width = 8
)
# self.draw.line((self.x, self.y, ex, ey), fill = 0, width = 8)
self.x = event.x
self.y = event.y
Mit dieser Funktion können Sie Zeichen schreiben und löschen.
Nach einigen Recherchen kann Tkinter's Canvas Linien zeichnen, so dass es geschrieben werden kann, aber es scheint nicht möglich zu sein, das, was Sie geschrieben haben, zu lesen und zu quantifizieren.
Als ich nach einer Lösung suchte, fand ich ein Argument, dass ich Pillow intern haben und dasselbe auf Pillow's Image zeichnen sollte, wenn ich auf Leinwand zeichne. (Daran konnte ich nicht denken, deshalb hielt ich es für eine sehr kluge Idee.) Der im obigen Code auskommentierte Teil entspricht dem. Pillow's Image kann mit numpy.array schnell in ein Numpy-Array umgewandelt werden, sodass es einfach in ein Modell für maschinelles Lernen eingespeist werden kann.
Eine grafische Benutzeroberfläche zur Eingabe handgeschriebener Zeichen und ein Modell für maschinelles Lernen zur Klassifizierung von Kana-Bildern wurden fertiggestellt. Das Folgende ist eine Kombination davon.
YouTube: https://www.youtube.com/watch?v=a0MBfVVp7mA
Es ist nicht sehr genau, aber es hat es ziemlich richtig erkannt. Es erkennt keine schmutzigen Zeichen, aber wenn ich "aiueo" sorgfältig eingegeben habe, werden die entsprechenden Zeichen richtig ausgegeben.
Ich habe das "Hallo" ausprobiert, wenn "Blut" im "La" erkannt wird und "Filtration" häufig war. Ich war neugierig und als ich die Bilddaten von "Chi" überprüfte, stellte ich fest, dass es einen kleinen Unterschied zwischen der Form von "Chi", die ich schrieb, und der des Bildes gab. Da ich nur drei Arten von Schriftarten trainiert habe, kann ich die Eingabe anscheinend nicht mit seltsamen Formen verarbeiten. Als ich die Zeichen in einer Form in der Nähe der Eingabedaten schrieb, erkannten sie sie korrekt.
Die Erkennungszeit gibt das Ergebnis sofort aus, ohne die GPU für das Modell des maschinellen Lernens zu verwenden.
Es wäre ideal, wenn wir Kanji erkennen könnten, aber die Klassifizierungsziele sind 169 bis Tausende. Kana allein ist nicht genau genug, daher habe ich das Gefühl, dass die Leistung wahrscheinlich sofort sinken wird.
Es wird einige Zeit dauern, aber ich denke, dass es als Schnittstelle bequemer ist, wenn Sie die Top-n-Elemente mit einer hohen Wahrscheinlichkeit der Klassifizierung ausgeben.
Wenn Sie danach die Gewissheit als Wort lernen und sie an der Form des Zeichens + der Wahrscheinlichkeit als Wort erkennen, kann sich die Genauigkeit bei der Eingabe eines aussagekräftigen Wortes oder Satzes erhöhen. (Wenn Sie beispielsweise "Hallo" eingeben, fügen Sie hinzu, dass "ha" als nächstes kommt.)