import tkinter as tk import tkinter.filedialog from tkinter.ttk import * import cv2 import numpy as np from PIL import Image, ImageTk import Basic import advanced root = tk.Tk() root.title('Galaxy_Eyes') img = cv2.imread('origin.jpg') img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img2 = Image.fromarray(img) photo = ImageTk.PhotoImage(img2) imageLabel = tk.Label(root, image=photo) imageLabel.pack(side=tk.LEFT) logical_var = tk.IntVar() arithmetic_var = tk.IntVar() imgx = np.zeros((img.shape[1], img.shape[0])) def img_change(img_t): global img global img2 global photo global imageLabel img = img_t img2 = Image.fromarray(img) photo = ImageTk.PhotoImage(img2) imageLabel.config(image=photo) def ope(): filename = tkinter.filedialog.askopenfilename() if filename != '': i = cv2.imread(filename) i = cv2.cvtColor(i, cv2.COLOR_BGR2RGB) img_change(i) def sav(imgt): filename = tkinter.filedialog.asksaveasfilename(defaultextension='.png', filetypes=(('PNG文件', '*.png'), ('JPEG文件', '*.jpg'), ('全部类型文件', '*.*'))) if filename != '': img_t = imgt if len(imgt.shape) >= 3: img_t = cv2.cvtColor(img_t, cv2.COLOR_RGB2BGR) cv2.imwrite(filename, img_t) def otsu(): global img img_change(Basic.turnToBinary(img)) def logical_operation(winNew, imx, imy): if logical_var.get() == 1: result = imx & imy elif logical_var.get() == 2: result = imx | imy elif logical_var.get() == 3: result = imx ^ imy else: return result = cv2.resize(result, (600, 600)) img_change(result) winNew.destroy() def logical_image_choose(fr, ph): filename = tkinter.filedialog.askopenfilename() if filename != '': imgt = cv2.imread(filename) imgt = cv2.cvtColor(imgt, cv2.COLOR_BGR2RGB) imgt = Basic.turnToBinary(imgt) imgt = cv2.resize(imgt, (150, 150)) fr.photot = ImageTk.PhotoImage(Image.fromarray(imgt)) ph.config(image=fr.photot) fr.imgy = imgt def logical_window_setup(): global logical_var logical_winNew = tk.Toplevel(root) logical_winNew.wm_attributes('-topmost', 1) logical_winNew.title('Logical_operation') logical_winNew.geometry('400x400') frame1 = tk.Frame(logical_winNew, relief=tkinter.RAISED, borderwidth=2) operation_and = tk.Radiobutton(frame1, text='逻辑与', variable=logical_var, value=1) operation_or = tk.Radiobutton(frame1, text='逻辑或', variable=logical_var, value=2) operation_xor = tk.Radiobutton(frame1, text='逻辑异或', variable=logical_var, value=3) operation_and.pack() operation_or.pack() operation_xor.pack() frame1.pack() frame2 = tk.Frame(logical_winNew, relief=tkinter.RAISED, borderwidth=2) global img img_Binary = Basic.turnToBinary(img) img_Binary = cv2.resize(img_Binary, (150, 150)) # 缩小至100x100 frame2.imgx = img_Binary frame2.imgy = img_Binary frame2.photo1 = ImageTk.PhotoImage(Image.fromarray(img_Binary)) frame2.photo2 = frame2.photo1 photo1 = tk.Label(frame2, image=frame2.photo1) photo2 = tk.Label(frame2, image=frame2.photo2) photo1.pack(side=tk.LEFT) photo2.pack(side=tk.RIGHT) frame2.pack() frame3 = tk.Frame(logical_winNew, relief=tkinter.RAISED, borderwidth=2) choose_image = tk.Button(frame3, text='请选择操作图', command=lambda: logical_image_choose(frame2, photo2)) operation_button = tk.Button(frame3, text='执行操作', command=lambda: logical_operation(logical_winNew, frame2.imgx, frame2.imgy)) choose_image.pack(side=tk.LEFT) operation_button.pack(side=tk.RIGHT) frame3.pack() def arithmetic_operation(winNew, imx, imy): if arithmetic_var.get() == 1: result = cv2.add(imx, imy) elif arithmetic_var.get() == 2: result = cv2.subtract(imx, imy) elif arithmetic_var.get() == 3: result = cv2.multiply(imx, imy) elif arithmetic_var.get() == 4: result = cv2.divide(imx, imy) else: return result = cv2.resize(result, (600, 600)) img_change(result) winNew.destroy() def arithmetic_image_choose(fr, ph): filename = tkinter.filedialog.askopenfilename() if filename != '': imgt = cv2.imread(filename) imgt = cv2.cvtColor(imgt, cv2.COLOR_BGR2RGB) imgt = cv2.resize(imgt, (150, 150)) fr.photot = ImageTk.PhotoImage(Image.fromarray(imgt)) ph.config(image=fr.photot) fr.imgy = imgt def arithmetic_window_setup(): global arithmetic_var arithmetic_winNew = tk.Toplevel(root) arithmetic_winNew.wm_attributes('-topmost', 1) arithmetic_winNew.title('Logical_operation') arithmetic_winNew.geometry('400x400') frame1 = tk.Frame(arithmetic_winNew, relief=tkinter.RAISED, borderwidth=2) operation_add = tk.Radiobutton(frame1, text='算术加', variable=arithmetic_var, value=1) operation_sub = tk.Radiobutton(frame1, text='算术减', variable=arithmetic_var, value=2) operation_mul = tk.Radiobutton(frame1, text='算术乘', variable=arithmetic_var, value=3) operation_div = tk.Radiobutton(frame1, text='算术除', variable=arithmetic_var, value=4) operation_add.pack(side=tk.LEFT) operation_sub.pack(side=tk.LEFT) operation_mul.pack(side=tk.LEFT) operation_div.pack(side=tk.LEFT) frame1.pack() frame2 = tk.Frame(arithmetic_winNew, relief=tkinter.RAISED, borderwidth=2) global img img = cv2.resize(img, (150, 150)) frame2.imgx = img frame2.imgy = img frame2.photo1 = ImageTk.PhotoImage(Image.fromarray(img)) frame2.photo2 = frame2.photo1 photo1 = tk.Label(frame2, image=frame2.photo1) photo2 = tk.Label(frame2, image=frame2.photo2) photo1.pack(side=tk.LEFT) photo2.pack(side=tk.RIGHT) frame2.pack() frame3 = tk.Frame(arithmetic_winNew, relief=tkinter.RAISED, borderwidth=2) choose_image = tk.Button(frame3, text='请选择操作图', command=lambda: arithmetic_image_choose(frame2, photo2)) operation_button = tk.Button(frame3, text='执行操作', command=lambda: arithmetic_operation(arithmetic_winNew, frame2.imgx, frame2.imgy)) choose_image.pack(side=tk.LEFT) operation_button.pack(side=tk.RIGHT) frame3.pack() def size_change_window_setup(): size_winNew = tk.Toplevel(root) textlabel = tk.Label(size_winNew, text='选择放缩后高度和宽度的大小 和 使用的线性插值') textlabel.pack() frame1 = tk.Frame(size_winNew, relief=tkinter.RAISED, borderwidth=2) frame1_hw = tk.Frame(frame1, relief=tkinter.RAISED, borderwidth=2) # 宽高 frame1_itp = tk.Frame(frame1, relief=tkinter.RAISED, borderwidth=2) # 线性插值 height_entry = tk.Entry(frame1_hw) weight_entry = tk.Entry(frame1_hw) global img height_entry.insert(0, img.shape[0]) weight_entry.insert(0, img.shape[1]) frame1.pack() frame1_hw.pack(side=tk.LEFT) frame1_itp.pack(side=tk.LEFT) height_entry.pack() weight_entry.pack() itp_var = tk.StringVar() itp_comb = Combobox(size_winNew, textvariable=itp_var, values=['最近邻插值', '双线性插值', '基于局部像素的重采样', '基于4x4像素邻域的3次插值法', '基于8x8像素邻域的Lanczos插值']) itp_comb.pack() tk.Button(size_winNew, text='放缩!', command=lambda: img_change( Basic.size_change(img, height_entry.get(), weight_entry.get(), itp_comb.current()))).pack() def panning_window_setup(): pan_winNew = tk.Toplevel(root) framex = tk.Frame(pan_winNew, relief=tkinter.RAISED, borderwidth=2) x_direction = tk.StringVar() x_direction_comb = Combobox(framex, textvariable=x_direction, value=['上', '下']) x_direction_comb.pack(side=tk.LEFT) x_direction_comb.current(0) x_direction_entry = tk.Entry(framex) x_direction_entry.insert(0, 0) x_direction_entry.pack(side=tk.LEFT) framex.pack() framey = tk.Frame(pan_winNew, relief=tkinter.RAISED, borderwidth=2) y_direction = tk.StringVar() y_direction_comb = Combobox(framey, textvariable=y_direction, value=['左', '右']) y_direction_comb.pack(side=tk.LEFT) y_direction_comb.current(0) y_direction_entry = tk.Entry(framey) y_direction_entry.pack(side=tk.LEFT) y_direction_entry.insert(0, 0) framey.pack() global img tk.Button(pan_winNew, text='平移!', command=lambda: img_change( Basic.image_panning(img, int(x_direction_entry.get()) * (1 if x_direction.get() == '下' else -1), int(y_direction_entry.get()) * (1 if y_direction.get() == '右' else -1)))).pack() def rotate_window_setup(): rotate_winNew = tk.Toplevel(root) rotate_direction = tk.StringVar() rotate_direction_comb = Combobox(rotate_winNew, textvariable=rotate_direction, value=['逆时针', '顺时针']) rotate_direction_comb.pack(side=tk.LEFT) rotate_direction_comb.current(0) rotate_angle = tk.Entry(rotate_winNew) rotate_angle.insert(0, 0) rotate_angle.pack(side=tk.LEFT) global img tk.Button(rotate_winNew, text='旋转!', command=lambda: img_change( Basic.image_rotate(img, int(rotate_angle.get()) if rotate_direction.get() == '逆时针' else ( 360 - int(rotate_angle.get()))))).pack(side=tk.BOTTOM) def Matrix_operation(MA): M = [[float for i in range(3)] for i in range(2)] for i in range(0, 2): for j in range(0, 3): M[i][j] = float(MA[i][j].get()) M = np.float32(M) global img img_change(cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))) def Matrix_window_setup(): Matrix_winNew = tk.Toplevel(root) Matrix_A = [[tk.Entry() for i in range(3)] for i in range(2)] for i in range(0, 2): for j in range(0, 3): Matrix_A[i][j] = tk.Entry(Matrix_winNew) Matrix_A[i][j].grid(row=i, column=j) Matrix_A[i][j].insert(0, (1 if i == j else 0)) for i in range(0, 3): tk.Label(Matrix_winNew, text=(1 if i == 2 else 0)).grid(row=2, column=i) tk.Button(Matrix_winNew, text='仿射变换', command=lambda: Matrix_operation(Matrix_A)).grid(row=3, column=0, columnspan=3) def flip_window_setup(): flip_winNew = tk.Toplevel(root) flip_direction = tk.StringVar() flip_direction_comb = Combobox(flip_winNew, textvariable=flip_direction, value=['水平翻转', '垂直翻转', '对角翻转']) flip_direction_comb.current(0) flip_direction_comb.pack() flip_dic = {'水平翻转': 1, '垂直翻转': 0, '对角翻转': -1} global img tk.Button(flip_winNew, text='翻转!', command=lambda: img_change(cv2.flip(img, flip_dic[flip_direction.get()], dst=None))).pack() def img_sharp(x, winNew): if x == 1: img_change(Basic.gradient_img_sharpen(img)) elif x == 2: img_change(Basic.Roberts_img_sharpen(img)) elif x == 3: img_change(Basic.Prewitt_img_sharpen(img)) elif x == 4: img_change(Basic.Sobel_img_sharpen(img)) elif x == 5: img_change(Basic.Laplacian_img_sharpen(img)) elif x == 6: img_change(Basic.LoG_img_sharpen(img)) elif x == 7: img_change(Basic.Canny_img_sharpen(img)) winNew.destroy() def sharp_window_setup(): sharp_winNew = tk.Toplevel(root) sharp_way = tk.StringVar() sharp_way_comb = Combobox(sharp_winNew, textvariable=sharp_way, value=['梯度', 'Roberts算子', 'Prewitt算子', 'Sobel算子', 'Laplacian算子', 'LoG算子', 'Canny边缘检测']) sharp_way_comb.current(0) sharp_way_comb.pack() sharp_dic = {'梯度': 1, 'Roberts算子': 2, 'Prewitt算子': 3, 'Sobel算子': 4, 'Laplacian算子': 5, 'LoG算子': 6, 'Canny边缘检测': 7} tk.Button(sharp_winNew, text='检测!', command=lambda: img_sharp(sharp_dic[sharp_way.get()], sharp_winNew)).pack() def maintain_face_detection(camera, winNew, panel, bk): global imgx success, imgx = camera.read() # 从摄像头读取照片 if success: global img imgx = cv2.cvtColor(imgx, cv2.COLOR_BGR2RGB) # 转换颜色从BGR到RGB if bk.get() == 1: imgx = advanced.face_detect_function(imgx) elif bk.get() == 2: imgx = advanced.removeBG(imgx, img) current_image = Image.fromarray(imgx) # 将图像转换成Image对象 imgtk = ImageTk.PhotoImage(image=current_image) panel.imgtk1 = imgtk panel.config(image=imgtk) winNew.after(1, lambda: maintain_face_detection(camera, winNew, panel, bk)) def real_time_face_detection(): global imgx face_winNew = tk.Toplevel(root) imageLabelt = tk.Label(face_winNew) imageLabelt.pack() frame1 = tk.Frame(face_winNew) frame1.pack() bk = tk.IntVar() no_background = tk.Radiobutton(frame1, text='无背景,人脸检测', variable=bk, value=1) with_background = tk.Radiobutton(frame1, text='以软件当前显示图片为背景', variable=bk, value=2) no_background.pack(side=tk.LEFT) with_background.pack(side=tk.LEFT) tk.Button(face_winNew, text='拍照', command=lambda: sav(imgx)).pack() camera = cv2.VideoCapture(0) maintain_face_detection(camera, face_winNew, imageLabelt, bk) face_winNew.mainloop() camera.release() mainmenu = tk.Menu(root) # 菜单栏 filemenu = tk.Menu(mainmenu) # 文件菜单 processmenu = tk.Menu(mainmenu) # 处理菜单 calculationmenu = tk.Menu(mainmenu) # 运算菜单 histmenu = tk.Menu(mainmenu) # 直方图 smoothmenu = tk.Menu(processmenu) noisemenu = tk.Menu(processmenu) structuringmenu = tk.Menu(mainmenu) advancedmenu = tk.Menu(mainmenu) mainmenu.add_cascade(label='文件', menu=filemenu) mainmenu.add_cascade(label='基本处理', menu=processmenu) mainmenu.add_cascade(label='运算', menu=calculationmenu) mainmenu.add_cascade(label='直方图', menu=histmenu) mainmenu.add_cascade(label='形态学操作', menu=structuringmenu) mainmenu.add_cascade(label='进阶操作', menu=advancedmenu) filemenu.add_command(label='打开', command=ope) filemenu.add_command(label='保存', command=lambda: sav(img)) processmenu.add_command(label='自适应阈值法二值化', command=otsu) processmenu.add_command(label='缩放', command=size_change_window_setup) processmenu.add_command(label='平移', command=panning_window_setup) processmenu.add_command(label='旋转', command=rotate_window_setup) processmenu.add_command(label='翻转', command=flip_window_setup) processmenu.add_command(label='平移和旋转(矩阵)——仿射变换', command=Matrix_window_setup) processmenu.add_command(label='Hough变换检测直线', command=lambda: img_change(Basic.Hough_transform(img))) processmenu.add_command(label='边缘检测', command=sharp_window_setup) processmenu.add_cascade(label='平滑/滤噪', menu=smoothmenu) processmenu.add_cascade(label='添加噪声', menu=noisemenu) smoothmenu.add_command(label='空域平滑-邻域平均法', command=lambda: img_change(Basic.neighberhood_average_smooth(img))) smoothmenu.add_command(label='空域平滑-中值滤波法', command=lambda: img_change(Basic.median_filtering_smooth(img))) smoothmenu.add_command(label='频域平滑-理想低通滤波', command=lambda: img_change(Basic.Ideal_low_pass_filtering_smooth(img))) smoothmenu.add_command(label='频域平滑-巴特沃斯低通滤波', command=lambda: img_change(Basic.ButterWorth_filtering_smooth(img))) smoothmenu.add_command(label='频域平滑-高斯低通滤波', command=lambda: img_change(Basic.Gaussian_filtering_smooth(img))) noisemenu.add_command(label='添加椒盐噪声', command=lambda: img_change(Basic.produce_pepper_salt_noise(img))) noisemenu.add_command(label='添加高斯噪声', command=lambda: img_change(Basic.produce_Gaussian_noise(img))) calculationmenu.add_command(label='逻辑运算', command=logical_window_setup) calculationmenu.add_command(label='算术运算', command=arithmetic_window_setup) histmenu.add_command(label='灰度直方图', command=lambda: img_change(Basic.get_gray_hist(img))) histmenu.add_command(label='彩色直方图', command=lambda: img_change(Basic.get_colorful_hist(img))) histmenu.add_command(label='分段线性变化', command=lambda: img_change(Basic.segmented_linear_transformation(img))) structuringmenu.add_command(label='膨胀', command=lambda: img_change(Basic.image_erode(img))) structuringmenu.add_command(label='腐蚀', command=lambda: img_change(Basic.image_dilate(img))) structuringmenu.add_command(label='开运算', command=lambda: img_change(Basic.image_dilate(Basic.image_erode(img)))) structuringmenu.add_command(label='闭运算', command=lambda: img_change(Basic.image_erode(Basic.image_dilate(img)))) advancedmenu.add_command(label='人脸检测', command=lambda: img_change(advanced.face_detect_function(img))) advancedmenu.add_command(label='实时更换背景/拍照', command=real_time_face_detection) root.config(menu=mainmenu) # root.bind('Button-3', popupmenu) root.mainloop()