This document is a final report for a handwriting recognition system course project. It introduces the project, describes the programming environment in Python, and provides code samples to convert a handwriting model to a pickle file and build a writing pad GUI for recognition. It shows the results and concludes the recognition success rate was 72% based on testing 100 handwritten samples.
5. 3.程式碼
*將 handwriting-zh_TW 轉換到 model.pickle 執行
from struct import unpack_from, calcsize
import sys
import pickle
from itertools import takewhile, starmap, repeat
from io import BytesIO
def binary_file_parser(fn):
get_next=lambdafmt:unpack_from(fmt,sio.read(calcsize(fmt)))
buf=open(fn,"rb").read()
sio=BytesIO(buf)
return buf,get_next
def main(fn, freq=None):
MAGIC=0xef71821
buf,get_next=binary_file_parser(fn)
(magic,version,nsize)=get_next("III")
assert magic^MAGIC==len(buf)
if freq:
freq_chars=set(open(freq,"r",encoding="big5").read())
model=[]
for i in range(nsize):
(cs,bias)=get_next("16sf")
character=cs.rstrip(b"x00").decode("utf8")
w=sorted(takewhile((-1, 0.0).__ne__,starmap(get_next,
repeat(("if",)))))
if not freq or character in freq_chars:
model.append((character,bias, w))
pickle.dump(model,open("model.pickle","wb"))
main("handwriting-zh_TW.model")
print("modelconverted")
6. --------------------------------------------------------
*製作手寫板並比對辨識輸出
# *encoding=utf-8
import sys
import pickle
from hwr import recognize
from tkinter import *
from tkinter.scrolledtextimport *
from itertools import chain
class WritePad:
def autorecog(self):
if self.strokes:
self.idle_count+=1
if self.idle_count>=5:
self.charlist=recognize(self.model,self.dim,
self.strokes)
self.listbox.delete(0,END)
self.listbox.insert(END,*(c for f,c in self.charlist))
self.text.insert(INSERT,self.charlist[0][1])
self.wa_reset()
self.write_area.after(100,self.autorecog)
def selc(self,event):
sel=self.listbox.curselection()
if sel:
c=self.charlist[int(sel[0])][1]
self.text.delete(INSERT+"-1c")
self.text.insert(INSERT,c)
self.text.focus_set()
def wa_reset(self):
self.write_area.delete(ALL)
w,h=self.dim[0]-1,self.dim[1]-1
vlines=((w*i//3+2,0,w*i//3+2,h) for i in range(4))
7. hlines=((0,h*i//3+2,w,h*i//3+2) for i in range(4))
for var in chain(vlines, hlines):
self.write_area.create_line(*var, fill="#e00000")
self.text.focus_set()
self.strokes,self.idle_count,self.s=[],0, None
def __init__(self,master, model,width=300, height=300):
self.model,self.dim=model,(width,height)
self.text=ScrolledText(master,height=4, width=24,
font=("defaultgui",40))
self.text.pack()
Frame(master, height=height//20).pack(fill="x",expand=1)
Frame(master, height=height,
width=width//3).pack(side=LEFT)
self.write_area=Canvas(master,width=width, height=height,
bg="#FFE")
self.write_area.pack(side=LEFT)
self.write_area.bind("<Motion>",self.motion)
self.write_area.bind("<1>",self.b1down)
self.write_area.bind("<ButtonRelease-1>",self.b1up)
Frame(master, height=height,
width=width//15).pack(side=LEFT)
self.listbox= Listbox(master,selectmode=SINGLE,
width=3, height=10, font=("default",22))
self.listbox.bind("<ButtonRelease-1>",self.selc)
self.listbox.pack(side=LEFT)
Frame(master, height=height,
width=width//15).pack(side=LEFT)
f=Frame(height=height)
f.pack(side=LEFT)
bstyle={"width":5, "font":("default",16)} #button style
Button(f, command=lambda :self.text.delete(INSERT+"-1c"),
text="del",**bstyle).pack()
insertf=lambdac: lambda :self.text.insert(INSERT,c)
for c in ",。?!「」n":
Button(f, text=repr(c)[1:-1], command=insertf(c),
**bstyle).pack()