from PIL import Image as Im from PIL import ImageTk import tkinter as tk # 导入 Tkinter 库 from tkinter.filedialog import askopenfilename import tkinter.messagebox import tkinter.ttk import tkinter.messagebox from PIL import ImageDraw from PIL import ImageFont from PIL import ImageEnhance from hig_class import * from extra import wlw import numpy as np import tempfile import os class Win(tk.Tk): def __init__(self): super().__init__() self.title('图像处理工具') self.geometry('1080x720') self.picture = None # self.picture将作为picture类的实例化对象 self.img = None # self.img将作为窗口类中一直变动的PIL对象图片 self.file_entry = None self.setupUI() def setupUI(self): # 右边菜单栏 right_f = tk.Frame(self, height=720, width=360, bg="#F8F8FF") right_f.pack(side=tk.RIGHT) # 各种功能按钮名称及位置 btn1 = tk.Button(right_f, text='打开图像', bg="#BFEFFF", command=self.openToshow) btn1.place(y=25, x=30, width=300, height=40) btn2 = tk.Button(right_f, text='截图', bg="#BFEFFF", command=self.window_cut) btn2.place(y=85, x=30, width=144, height=40) btn3 = tk.Button(right_f, text='大小', bg="#BFEFFF", command=self.window_size) btn3.place(y=85, x=186, width=144, height=40) btn4 = tk.Button(right_f, text='旋转', bg='#B0E2FF', command=self.window_rotate) btn4.place(y=145, x=30, width=144, height=40) btn5 = tk.Button(right_f, text='翻转', bg='#B0E2FF', command=self.window_mirror) btn5.place(y=145, x=186, width=144, height=40) btn6 = tk.Button(right_f, text='灰度变换', bg='#B0E2FF', command=self.window_word) btn6.place(y=205, x=30, width=144, height=40) btn7 = tk.Button(right_f, text='滤镜', bg='#B0E2FF', command=self.window_style) btn7.place(y=205, x=186, width=144, height=40) btn8 = tk.Button(right_f, text='显示直方图', bg='#63B8FF', command=self.toshowhist) btn8.place(y=265, x=30, width=144, height=40) btn9 = tk.Button(right_f, text='图像相加', bg='#63B8FF', command=self.openToshow2) btn9.place(y=265, x=186, width=144, height=40) btn10 = tk.Button(right_f, text='滤波', bg='#63B8FF', command=self.openfilter) btn10.place(y=325, x=30, width=144, height=40) btn11 = tk.Button(right_f, text='Sobel锐化', bg='#63B8FF', command=self.opensharpen) btn11.place(y=325, x=186, width=144, height=40) # 各种调整名称及位置 lb1 = tk.Label(right_f, text='亮 度:', bg="#F8F8FF") lb1.place(y=395, x=55, width=60, height=30) self.inp1 = tk.Entry(right_f) self.inp1.place(y=395, x=105, width=90, height=30) lb2 = tk.Label(right_f, text='%', bg="#F8F8FF") lb2.place(y=395, x=205, width=13, height=30) b1 = tk.Button(right_f, text='确定', fg='#F8F8FF', width=8, command=self.brightnessPic, bg="#7EC0EE") b1.place(y=395, x=240) lb3 = tk.Label(right_f, text='色彩度:', bg="#F8F8FF") lb3.place(y=440, x=55, width=60, height=30) self.inp2 = tk.Entry(right_f) self.inp2.place(y=440, x=105, width=90, height=30) lb4 = tk.Label(right_f, text='%', bg="#F8F8FF") lb4.place(y=440, x=205, width=13, height=30) b2 = tk.Button(right_f, text='确定', fg='#F8F8FF', width=8, command=self.coolorPic, bg="#7EC0EE") b2.place(y=444, x=240) lb5 = tk.Label(right_f, text='对比度:', bg="#F8F8FF") lb5.place(y=485, x=55, width=60, height=30) self.inp3 = tk.Entry(right_f) self.inp3.place(y=485, x=105, width=90, height=30) lb6 = tk.Label(right_f, text='%', bg="#F8F8FF") lb6.place(y=485, x=205, width=13, height=30) b3 = tk.Button(right_f, text='确定', fg='#F8F8FF', width=8, command=self.contrastPic, bg="#7EC0EE") b3.place(y=489, x=240) lb7 = tk.Label(right_f, text='锐 度:', bg="#F8F8FF") lb7.place(y=530, x=55, width=60, height=30) self.inp4 = tk.Entry(right_f) self.inp4.place(y=530, x=105, width=90, height=30) lb8 = tk.Label(right_f, text='%', bg="#F8F8FF") lb8.place(y=530, x=205, width=13, height=30) b4 = tk.Button(right_f, text='确定', fg='#F8F8FF', width=8, command=self.sharpnessPic, bg="#7EC0EE") b4.place(y=534, x=240) # 底部恢复、保存、对比、人脸识别 btn18 = tk.Button(right_f, text='保存图像', fg='#F8F8FF', command=self.save_pic, bg="#1E90FF") btn18.place(y=590, x=200, width=100, height=30) btn19 = tk.Button(right_f, text='恢复图像', fg='#F8F8FF', command=self.replay, bg="#1E90FF") btn19.place(y=590, x=30) btn20 = tk.Button(right_f, text='对比图像', fg='#F8F8FF', command=self.compare, bg="#1E90FF") btn20.place(y=590, x=120) btn21 = tk.Button(right_f, text='人脸识别', fg='#F8F8FF', command=self.facedetec, bg="#1874CD") btn21.place(y=640, x=30) # 右侧图像显示栏 right_f = tk.Frame(self, height=720, width=720) right_f.pack(side=tk.RIGHT) self.image_l = tk.Label(right_f, relief='ridge') self.image_l.place(x=0, y=0, width=720, height=720) def openfilter(self): filter_win = tk.Toplevel() filter_win.title('滤波选择') filter_win.geometry('150x150') b1 = tk.Button(filter_win, text='均值滤波', command=self.filter1) b1.place(y=30, x=35, width=75) b2 = tk.Button(filter_win, text='中值滤波', command=self.filter2) b2.place(y=60, x=35, width=75) b3 = tk.Button(filter_win, text='完成', command=filter_win.destroy) b3.place(y=110, x=80, width=40) def opensharpen(self): sharpen_pic = self.img sharpen_pic = wlw.sharpen(sharpen_pic) self.show_img(sharpen_pic) # 打开图片时使用,传值(图)给展示函数 def openToshow(self): address = self.getAddress() self.open_picToimg = self.picture.open_pic(address) self.firstPic(self.open_picToimg) self.show_img(self.open_picToimg) # 打开图片时使用,传值(图)给展示函数 def openToshow2(self): address2 = self.getAddress2() self.open_picToimg2 = self.picture.open_pic(address2) self.firstPic2(self.open_picToimg2) self.show_img2(self.open_picToimg2) def filter1(self): img_show = wlw.filter1(self.img) self.image_l.config(image=img_show) self.image_l.image = img_show return self.img def filter2(self): img_show = wlw.filter2(self.img) self.image_l.config(image=img_show) self.image_l.image = img_show return self.img # 打开图片时使用,获得地址 def getAddress(self): path = tk.StringVar() self.file_entry = tk.Entry(self, state='readonly', text=path) path_ = askopenfilename() path.set(path_) self.picture = picture() return self.file_entry.get() # 打开图片时使用,获得地址 def getAddress2(self): path2 = tk.StringVar() file_entry2 = tk.Entry(self, state='readonly', text=path2) path_2 = askopenfilename() path2.set(path_2) self.picture2 = picture() return file_entry2.get() # 展示函数 def show_img(self, n_img): self.img = n_img # self.img PIL对象方便传值给picture类以及本类中其他需要使用PIL图像的地方 img_show = ImageTk.PhotoImage(self.img) self.image_l.config(image=img_show) self.image_l.image = img_show return self.img def show_img2(self, n_img): self.img2 = n_img # self.img PIL对象方便传值给picture类以及本类中其他需要使用PIL图像的地方 img_show2 = self.img2 img_show2 = wlw.Add(img_show2, self.Fpic) self.image_l.config(image=img_show2) self.image_l.image = img_show2 return self.img2 # 保存函数 def save_pic(self): fname = tkinter.filedialog.asksaveasfilename(title='保存文件', filetypes=[("PNG", ".png")]) self.img.save(str(fname)) # PIL保存 # 打开图像调用 def open_pic(self, address): self.pic_get = Im.open(address).convert('RGBA') wid, hei = self.pic_get.size if wid > 600 or hei > 400: if tk.messagebox.askokcancel('提示', '图片可能过大,是否压缩?'): needShow_pic = self.openResize() return needShow_pic return self.pic_get else: return self.pic_get # 原图储存 def firstPic(self, pic): self.Fpic = pic return self.Fpic # 原图储存 def firstPic2(self, pic): self.Fpic2 = pic return self.Fpic2 # 打开图像时的图像压缩展示 def openResize(self): w, h = self.pic_get.size w_hope = 500 h_hope = 300 f1 = 1.0 * w_hope / w f2 = 1.0 * h_hope / h factor = min([f1, f2]) width = int(w * factor) height = int(h * factor) pic_show = self.pic_get.resize((width, height)) return pic_show # 截图操作页面 def window_cut(self): Cut_win = tk.Toplevel() Cut_win.title('截图操作') Cut_win.geometry('220x380') nowPic = self.img if self.img == None: lNone = tk.Label(Cut_win, text='请先打开一张图片') lNone.place(y=55, x=50) else: wNow, hNow = nowPic.size l1 = tk.Label(Cut_win, text="此时图片尺寸:") l1.place(y=30, x=25) l2 = tk.Label(Cut_win, text=wNow) l2.place(y=55, x=25) l3 = tk.Label(Cut_win, text="X") l3.place(y=55, x=65) l4 = tk.Label(Cut_win, text=hNow) l4.place(y=55, x=85) l5 = tk.Label(Cut_win, text="截图区域") l5.place(y=85, x=25) l6 = tk.Label(Cut_win, text="起始点:(左上为(0,0))") l6.place(y=115, x=25) l7 = tk.Label(Cut_win, text="x:") l7.place(y=145, x=25) self.e1 = tk.Entry(Cut_win, width=10) self.e1.place(y=145, x=55) l8 = tk.Label(Cut_win, text="y:") l8.place(y=180, x=25) self.e2 = tk.Entry(Cut_win, width=10) self.e2.place(y=180, x=55) l9 = tk.Label(Cut_win, text="终止点:") l9.place(y=220, x=25) l10 = tk.Label(Cut_win, text="x:") l10.place(y=250, x=25) self.e3 = tk.Entry(Cut_win, width=10) self.e3.place(y=250, x=55) l11 = tk.Label(Cut_win, text="y:") l11.place(y=285, x=25) self.e4 = tk.Entry(Cut_win, width=10) self.e4.place(y=285, x=55) b1 = tk.Button(Cut_win, text='确定', command=self.getCutpart) b1.place(y=320, x=80, width=40) b2 = tk.Button(Cut_win, text='完成', command=Cut_win.destroy) b2.place(y=350, x=150, width=40) # 大小尺寸操作窗口 def window_size(self): Size_win = tk.Toplevel() Size_win.title('尺寸操作') Size_win.geometry('200x180') l1 = tk.Label(Size_win, text="宽:") l1.place(y=30, x=25) self.text1 = tk.Entry(Size_win, width=10) self.text1.place(y=25, x=50) l1_1 = tk.Label(Size_win, text="px") l1_1.place(y=28, x=150) l2 = tk.Label(Size_win, text="高:") l2.place(y=60, x=25) self.text2 = tk.Entry(Size_win, width=10) self.text2.place(y=55, x=50) l2_1 = tk.Label(Size_win, text="px") l2_1.place(y=58, x=150) b1 = tk.Button(Size_win, text='确定', command=self.getSize_change) b1.place(y=100, x=80, width=40) b2 = tk.Button(Size_win, text='完成', command=Size_win.destroy) b2.place(y=145, x=140, width=40) # 接收截图区域,传送展示 def getCutpart(self): nCut_pic = self.img x = int(self.e1.get()) y = int(self.e2.get()) xl = int(self.e3.get()) yl = int(self.e4.get()) self.picture = picture() showCut_pic = self.picture.Cutpic(nCut_pic, x, y, xl, yl) self.show_img(showCut_pic) # 获得输入尺寸 def getSize_change(self): sizeNum_w = int(self.text1.get()) sizeNum_h = int(self.text2.get()) # print('1') self.showSize_change(sizeNum_w, sizeNum_h) # print(sizeNum_w, sizeNum_h) # 尺寸修改并展示图片 def showSize_change(self, renewSize_w, renewSize_h): # print('2') self.picture = picture() needResize_pic = self.img show_resizePic = self.picture.changeResize(needResize_pic, renewSize_w, renewSize_h) self.show_img(show_resizePic) # 灰度转换功能窗口 def window_word(self): Word_win = tk.Toplevel() Word_win.title('灰度变化') Word_win.geometry('300x400') l1 = tk.Label(Word_win, text='请选择灰度转换方法:') l1.place(y=10, x=20, width=130) l0 = tk.Label(Word_win, text="n(n值):") l0.place(y=40, x=20) self.i0 = tk.Entry(Word_win, width=13) # 输入参数n self.i0.place(y=40, x=100) bt1 = tk.Button(Word_win, text='n值化', command=self.getn) bt1.place(y=70, x=20, width=80) l2 = tk.Label(Word_win, text="k(对比度):") l2.place(y=110, x=20) self.i1 = tk.Entry(Word_win, width=13) # 输入线性化参数k self.i1.place(y=110, x=100) l3 = tk.Label(Word_win, text="b(亮度):") l3.place(y=130, x=20) self.i2 = tk.Entry(Word_win, width=13) # 输入线性化参数b self.i2.place(y=130, x=100) bt2 = tk.Button(Word_win, text='线性化', command=self.getkb) bt2.place(y=160, x=20, width=80) l3 = tk.Label(Word_win, text="c(尺度比较常数):") l3.place(y=200, x=20) self.i3 = tk.Entry(Word_win, width=13) # 输入参数c self.i3.place(y=200, x=140) bt3 = tk.Button(Word_win, text='非线性化(对数转换)', command=self.getc) bt3.place(y=230, x=20, width=120) b7 = tk.Button(Word_win, text='完成', command=Word_win.destroy) b7.place(y=300, x=210) # 获得输入的n值转换值 def getn(self): npic = self.img n = float(self.i0.get()) # 图像线性化获取展示 npic = wlw.tonpic(npic, n) self.show_img(npic) # 获得输入的线性转换值 def getkb(self): linearpic = self.img k = float(self.i1.get()) b = float(self.i2.get()) # 图像线性化获取展示 linearpic = wlw.linearization(linearpic, k, b) self.show_img(linearpic) # 获得输入的对数转换值 def getc(self): logpic = self.img c = float(self.i3.get()) # 图像对数化获取展示 logpic = wlw.tologpic(logpic, c) self.show_img(logpic) # 图像旋转操作窗口 def window_rotate(self): Rot_win = tk.Toplevel() Rot_win.title('旋转') Rot_win.geometry('225x220') l1 = tk.Label(Rot_win, text="角度:") l1.place(y=20, x=10) self.inpt = tk.Entry(Rot_win, width=13) self.inpt.place(y=15, x=50) b0 = tk.Button(Rot_win, text='确定', command=lambda: self.getDegree('1')) b0.place(y=55, x=160, width=40) b1 = tk.Button(Rot_win, text='+90', command=lambda: self.getDegree('2')) b1.place(y=85, x=60, width=95) b2 = tk.Button(Rot_win, text='-90', command=lambda: self.getDegree('3')) b2.place(y=115, x=60, width=95) b3 = tk.Button(Rot_win, text='180', command=lambda: self.getDegree('4')) b3.place(y=145, x=60, width=95) b4 = tk.Button(Rot_win, text='完成', command=Rot_win.destroy) b4.place(y=180, x=160, width=40) # 旋转角度获取 def getDegree(self, n): self.picture = picture() needRotate_pic = self.img # print('99') # print(n) if n == '1': shouldDegree = float(self.inpt.get()) # print('36') # print(shouldDegree) showRotate_pic = self.picture.rotatePic(needRotate_pic, shouldDegree) elif n == '2': # print('34') showRotate_pic = self.picture.rotatePic(needRotate_pic, +90) elif n == '3': showRotate_pic = self.picture.rotatePic(needRotate_pic, -90) elif n == '4': showRotate_pic = self.picture.rotatePic(needRotate_pic, 180) else: return 0 self.show_img(showRotate_pic) # 滤镜选择窗口 def window_style(self): Sty_win = tk.Toplevel() Sty_win.title('滤镜选择') Sty_win.geometry('230x180') bt1 = tk.Button(Sty_win, text='图像模糊', command=self.sty_1) bt1.place(y=25, x=25, width=80) bt2 = tk.Button(Sty_win, text='轮廓滤波', command=self.sty_2) bt2.place(y=25, x=115, width=80) bt3 = tk.Button(Sty_win, text='高斯模糊', command=self.sty_3) bt3.place(y=65, x=25, width=80) bt4 = tk.Button(Sty_win, text='浮雕滤镜', command=self.sty_4) bt4.place(y=65, x=115, width=80) bt6 = tk.Button(Sty_win, text='完成', command=Sty_win.destroy) bt6.place(y=140, x=160) # 图像模糊获取展示 def sty_1(self): sty_1_pic = self.img relSty_1 = wlw.blurPic(sty_1_pic) self.show_img(relSty_1) # 边界增强获取展示 def sty_2(self): sty_2_pic = self.img reSty_2 = wlw.edge(sty_2_pic) self.show_img(reSty_2) # 高斯模糊获取展示 def sty_3(self): sty_3_pic = self.img reSty_3 = wlw.gaussianBlur(sty_3_pic) self.show_img(reSty_3) # 浮雕滤镜获取展示 def sty_4(self): sty_4_pic = self.img reSty_4 = wlw.emboss(sty_4_pic) self.show_img(reSty_4) # 亮度调整 def brightnessPic(self): self.picture = picture() needBright_pic = self.img b_num = float(self.inp1.get()) briNum = b_num / 100 showBright_pic = self.picture.brightPic(needBright_pic, briNum) self.show_img(showBright_pic) # 色彩度调整 def coolorPic(self): self.picture = picture() needColor_pic = self.img co_num = float(self.inp2.get()) colNum = co_num / 100 showColor_pic = self.picture.colornPic(needColor_pic, colNum) self.show_img(showColor_pic) # 对比度调整 def contrastPic(self): self.picture = picture() needCon_pic = self.img c_num = float(self.inp3.get()) ConNum = c_num / 100 showContrast_pic = self.picture.constractPic(needCon_pic, ConNum) self.show_img(showContrast_pic) # 锐度调整 def sharpnessPic(self): self.picture = picture() needSharp_pic = self.img s_num = float(self.inp4.get()) ShNum = s_num / 100 showSharp_pic = self.picture.constractPic(needSharp_pic, ShNum) self.show_img(showSharp_pic) # 镜像操作窗口 def window_mirror(self): Mir_win = tk.Toplevel() Mir_win.title('镜像操作') Mir_win.geometry('150x150') b1 = tk.Button(Mir_win, text='左右', command=self.MirrorImg_lr) b1.place(y=30, x=35, width=75) b2 = tk.Button(Mir_win, text='上下', command=self.MirrorImg_tb) b2.place(y=60, x=35, width=75) b3 = tk.Button(Mir_win, text='完成', command=Mir_win.destroy) b3.place(y=110, x=80, width=40) # 镜像左右调用展示 def MirrorImg_lr(self): self.picture = picture() Mirror_img_lr = self.img MittotImg_lrFinish = self.picture.MirrorPic_leftOrright(Mirror_img_lr) self.show_img(MittotImg_lrFinish) # 镜像上下调用展示 def MirrorImg_tb(self): self.picture = picture() Mirror_img_tb = self.img MittotImg_tbFinish = self.picture.MirrorPic_topOrbuttom(Mirror_img_tb) self.show_img(MittotImg_tbFinish) # 恢复图像 def replay(self): self.show_img(self.Fpic) # 对比图像 def compare(self): Im._show(self.Fpic) def toshowhist(self): # gethist = wlw.showhist(self.img) # self.show_img(gethist) wlw.showhist(self.img) #人脸识别 def facedetec(self): minc=self.img path=self.file_entry.get() minc = wlw.face_detect(minc, path) self.show_img(minc) print("图片路径:", path) if __name__ == '__main__': root = Win() # 窗体主循环 root.mainloop()