diff --git a/main.py b/main.py new file mode 100644 index 0000000..6793d57 --- /dev/null +++ b/main.py @@ -0,0 +1,550 @@ +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()