手写数字识别系统编程技巧
之前,我写过一篇文章Python实现手写识别系统http://blog.csdn.net/louishao/article/details/60867339。这个实际上是我最近完成的本科毕业论文的课题。
本文就在那篇文章的基础上,总结当中的编程技巧,主要是图像处理和tkinter的编程。注意:本文写的编程技巧,仅针对之前的文章而言,并非是系统的讲解!
1 图像处理编程技巧
手写数字的预处理,我设计的系统中,包含了整形,灰度化和像素值的归一化。当然,我的论文课题重点不是图像处理,因此,这里我基本用的python第三方库PIL实现的。
整形、灰度化、像素值归一化的编程实现
# reshape
def reshapepic(pic):
im = Image.open(pic)
if im.size!=(28,28):
im = im.resize((28,28))#,Image.ANTIALIAS)
return im
# graying
def graypic(pic):
if pic.mode!='L':
pic = pic.convert('L')
return pic
# normalization
def normalizepic(pic):
im_arr = list(pic.getdata())
im_nparr = []
for x in im_arr:
x=1-x/255
im_nparr.append(x)
im_nparr = np.array([im_nparr])
return im_nparr,pic
**说明:**mnist中的图像都是28×28的,因此,使用reshapepic()将输入的图片整形为28×28的;同时训练图像是黑白的,因此,使用gray()进行灰度化;而且,训练图像的像素值都是在0-1之间的,因此需要归一化。
2 tkinter编程技巧
我本身对tkinter懂得不多,也只是懂一些很基础的编程,但通过之前手写识别系统的GUI实现后,自己学习了很多,现在作个总结。
很基础的构建控件,添加命令,我这里没有提及,主要是写一些,实用的技巧。
2.1 tkinter中的menu
我实现的系统中,含有’OpenFile’的菜单。实现如下:(这里是从我的整个项目文件上截取的,我采用面向对象的写法)
# ------Menu--------------------
self.menubar = Menu(self.root)
self.root.config(menu=self.menubar)
self.menubar.add_command(label='OpenFile',command=self.openfile)
self.piccan = Canvas(self.numberrec,
width=168,height=168,bg='#f2f2f2')
self.root['menu']=self.menubar
self.piccan.grid(row=2,column=0,rowspan=3)
打开图片后,使用一个Canvas来显示图片
# ------ Menu function --------------------------------------
def openfile(self):
try:
fname = td.askopenfilename(title="open", filetypes=[('Image','*.png'),('Image','*.bmp'), ('All Files', '*')])
self.imagepath.set(fname)
self.showimage()
#del(self.im_nparr)
self.reshbutton['state']='normal'
except AttributeError:
tb.showwarning('Warining',"You haven't import any images!")
except IOError:
tb.showwarning('Warining',"You should import an image!")
# ------- function to show image ------------------------------
def showimage(self):
self.__img = Image.open(self.imagepath.get())
#print(self.__img)
self.__photo = ImageTk.PhotoImage(self.__img)
self.piccan.create_image((84,84),image=self.__photo)
最后实现的结果,就是在菜单上导入图片,可以在一个Canvas的中间位置显示。
2.2 tkinter中的scrolledtext编程技巧
scrolledtext是将滚动轴和文本控件结合在一起,这样,使用起来更方便。
我的系统使用scrolledtext是用于显示各种信息的,类似很多集成系统的Console框的使用。
功能实现:
self.trainmsg = ScrolledText(self.train,font=("Microsoft YaHei",10),width=40,height=15,padx=5,pady=5)
self.trainmsg.grid(column=0,row=0,padx=5,pady=5)
这样,就能设置显示文本的字体和大小,以及这个控件的长和宽。
编写在ScrolledText中显示文本的函数,如下:
self.message = StringVar(self.root)
def printt(self,msg):
self.message.set(msg+"\n")
self.trainmsg.insert(INSERT,self.message.get())
self.trainmsg.see(END)
ScrolledText的使用关键在于printt()的函数上。insert()是用于插入要显示的文本,see(END)是当显示内容超过文本框的时候,自动滑到最下方。
2.3 tkinter中的Canvas编程技巧
对于Canvas控件,有一个方法很使用,就是delete(“all”),它能清空当前Canvas显示的图像,一定程度上能起到刷新的作用。
总结:做整个项目之前,我自己基本上都不知道怎么实现界面。但是,自己不断地尝试,写了很多很多的测试文件,自己也查了很多资料,但是网上tkinter的资料比较少,而且很多都只是很基础的教程,所以我还看了一部分的tkinter官方文档。总的来说,用了一个月写界面,学了很多,自己之前写过MATLAB的GUI,现在有写了python的,感觉自己对GUI的编程有一点小心得,也对编程有了信心。最终把自己既定的功能都写出来了,也很有满足感,继续努力!