parent
							
								
									f9b77dddc5
								
							
						
					
					
						commit
						0fa6d3c59c
					
				| @ -0,0 +1,343 @@ | ||||
| import tkinter as tk | ||||
| from tkinter import filedialog, messagebox | ||||
| from tkinter import Toplevel | ||||
| from PIL import Image, ImageTk | ||||
| import numpy as np | ||||
| import cv2 | ||||
| import os | ||||
| 
 | ||||
| # 全局变量初始化 | ||||
| img_path = ""  # 用于存储图像路径 | ||||
| src = None  # 用于存储已选择的图像 | ||||
| img_label = None  # 用于存储显示选择的图片的标签 | ||||
| edge = None  # 用于存储处理后的图像以便保存 | ||||
| 
 | ||||
| # 用于存储不同窗口的全局变量 | ||||
| CorrodeWin = None | ||||
| DilaWin = None | ||||
| OpenWin = None | ||||
| CloseWin = None | ||||
| 
 | ||||
| def select_image(root): | ||||
|     """ | ||||
|     选择并显示图像 | ||||
|     """ | ||||
|     global img_path, src, img_label | ||||
| 
 | ||||
|     # 打开文件选择对话框 | ||||
|     img_path = filedialog.askopenfilename(filetypes=[("Image files", "*.jpg;*.png;*.jpeg;*.bmp")]) | ||||
|     if img_path: | ||||
|         # 确保路径中的反斜杠正确处理,并使用 UTF-8 编码处理中文路径 | ||||
|         img_path_fixed = os.path.normpath(img_path) | ||||
| 
 | ||||
|         # 读取图像并进行颜色空间转换 | ||||
|         src_temp = cv2.imdecode(np.fromfile(img_path_fixed, dtype=np.uint8), cv2.IMREAD_UNCHANGED) | ||||
|         if src_temp is None: | ||||
|             messagebox.showerror("错误", "无法读取图片,请选择有效的图片路径") | ||||
|             return | ||||
|         src = cv2.cvtColor(src_temp, cv2.COLOR_BGR2RGB) | ||||
| 
 | ||||
|         # 显示图像 | ||||
|         if img_label is None or not img_label.winfo_exists(): | ||||
|             img_label = tk.Label(root) | ||||
|             img_label.pack(side=tk.TOP, pady=10) | ||||
| 
 | ||||
|         img = Image.open(img_path) | ||||
|         img.thumbnail((160, 160)) | ||||
|         img_tk = ImageTk.PhotoImage(img) | ||||
|         img_label.configure(image=img_tk) | ||||
|         img_label.image = img_tk | ||||
|     else: | ||||
|         messagebox.showerror("错误", "没有选择图片路径") | ||||
| 
 | ||||
| def show_selected_image(root): | ||||
|     """ | ||||
|     显示已选择的图像 | ||||
|     """ | ||||
|     global img_label | ||||
|     img_label = tk.Label(root) | ||||
|     img_label.pack(side=tk.TOP, pady=10) | ||||
|     img = Image.open(img_path) | ||||
|     img.thumbnail((160, 160)) | ||||
|     img_tk = ImageTk.PhotoImage(img) | ||||
|     img_label.configure(image=img_tk) | ||||
|     img_label.image = img_tk | ||||
| 
 | ||||
| def changeSize(event, img, LabelPic): | ||||
|     """ | ||||
|     根据窗口大小调整图像大小 | ||||
|     """ | ||||
|     img_aspect = img.shape[1] / img.shape[0] | ||||
|     new_aspect = event.width / event.height | ||||
| 
 | ||||
|     if new_aspect > img_aspect: | ||||
|         new_width = int(event.height * img_aspect) | ||||
|         new_height = event.height | ||||
|     else: | ||||
|         new_width = event.width | ||||
|         new_height = int(event.width / img_aspect) | ||||
| 
 | ||||
|     resized_image = cv2.resize(img, (new_width, new_height)) | ||||
|     image1 = ImageTk.PhotoImage(Image.fromarray(resized_image)) | ||||
|     LabelPic.image = image1 | ||||
|     LabelPic['image'] = image1 | ||||
| 
 | ||||
| def savefile(): | ||||
|     """ | ||||
|     保存处理后的图像 | ||||
|     """ | ||||
|     global edge | ||||
| 
 | ||||
|     filename = filedialog.asksaveasfilename(defaultextension=".jpg", filetypes=[("JPEG files", "*.jpg"), ("PNG files", "*.png"), ("BMP files", "*.bmp")]) | ||||
|     if not filename: | ||||
|         return | ||||
|     if edge is not None: | ||||
|         try: | ||||
|             edge.save(filename) | ||||
|             messagebox.showinfo("保存成功", "图片保存成功!") | ||||
|         except Exception as e: | ||||
|             messagebox.showerror("保存失败", f"无法保存图片: {e}") | ||||
|     else: | ||||
|         messagebox.showerror("保存失败", "没有图像可保存") | ||||
| 
 | ||||
| # 腐蚀 | ||||
| def corrode(root): | ||||
|     """ | ||||
|     腐蚀操作 | ||||
|     """ | ||||
|     global src, CorrodeWin, edge | ||||
| 
 | ||||
|     # 判断是否已经选取图片 | ||||
|     if src is None: | ||||
|         messagebox.showerror("错误", "没有选择图片!") | ||||
|         return | ||||
| 
 | ||||
|     # 定义结构元素(该处使用矩形3*3结构) | ||||
|     kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3), anchor=None) | ||||
| 
 | ||||
|     # 腐蚀图像 | ||||
|     eroded = cv2.erode(src, kernel) | ||||
| 
 | ||||
|     # 更新 edge 变量 | ||||
|     edge = Image.fromarray(eroded) | ||||
| 
 | ||||
|     # 创建 Toplevel 窗口 | ||||
|     try: | ||||
|         CorrodeWin.destroy() | ||||
|     except Exception: | ||||
|         print("NVM") | ||||
|     finally: | ||||
|         CorrodeWin = Toplevel(root) | ||||
|         CorrodeWin.attributes('-topmost', True) | ||||
|     CorrodeWin.geometry("360x300") | ||||
|     CorrodeWin.resizable(True, True)  # 可缩放 | ||||
|     CorrodeWin.title("腐蚀结果") | ||||
| 
 | ||||
|     # 显示图像 | ||||
|     LabelPic = tk.Label(CorrodeWin, text="IMG", width=360, height=240) | ||||
|     image = ImageTk.PhotoImage(Image.fromarray(eroded)) | ||||
|     LabelPic.image = image | ||||
|     LabelPic['image'] = image | ||||
| 
 | ||||
|     LabelPic.bind('<Configure>', lambda event: changeSize(event, eroded, LabelPic)) | ||||
|     LabelPic.pack(fill=tk.BOTH, expand=tk.YES) | ||||
| 
 | ||||
|     # 添加保存按钮 | ||||
|     btn_save = tk.Button(CorrodeWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, command=savefile) | ||||
|     btn_save.pack(pady=10) | ||||
| 
 | ||||
|     return | ||||
| 
 | ||||
| # 膨胀 | ||||
| def dilatation(root): | ||||
|     """ | ||||
|     膨胀操作 | ||||
|     """ | ||||
|     global src, DilaWin, edge | ||||
| 
 | ||||
|     # 判断是否已经选取图片 | ||||
|     if src is None: | ||||
|         messagebox.showerror("错误", "没有选择图片!") | ||||
|         return | ||||
| 
 | ||||
|     # 定义结构元素(该处使用矩形3*3结构) | ||||
|     kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3), anchor=None) | ||||
| 
 | ||||
|     # 膨胀图像 | ||||
|     dilated = cv2.dilate(src, kernel) | ||||
| 
 | ||||
|     # 更新 edge 变量 | ||||
|     edge = Image.fromarray(dilated) | ||||
| 
 | ||||
|     # 创建 Toplevel 窗口 | ||||
|     try: | ||||
|         DilaWin.destroy() | ||||
|     except Exception: | ||||
|         print("NVM") | ||||
|     finally: | ||||
|         DilaWin = Toplevel(root) | ||||
|         DilaWin.attributes('-topmost', True) | ||||
|     DilaWin.geometry("360x300") | ||||
|     DilaWin.resizable(True, True)  # 可缩放 | ||||
|     DilaWin.title("膨胀结果") | ||||
| 
 | ||||
|     # 显示图像 | ||||
|     LabelPic = tk.Label(DilaWin, text="IMG", width=360, height=240) | ||||
|     image = ImageTk.PhotoImage(Image.fromarray(dilated)) | ||||
|     LabelPic.image = image | ||||
|     LabelPic['image'] = image | ||||
| 
 | ||||
|     LabelPic.bind('<Configure>', lambda event: changeSize(event, dilated, LabelPic)) | ||||
|     LabelPic.pack(fill=tk.BOTH, expand=tk.YES) | ||||
| 
 | ||||
|     # 添加保存按钮 | ||||
|     btn_save = tk.Button(DilaWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, command=savefile) | ||||
|     btn_save.pack(pady=10) | ||||
| 
 | ||||
|     return | ||||
| 
 | ||||
| # 开运算 | ||||
| def open_op(root): | ||||
|     """ | ||||
|     开运算操作 | ||||
|     """ | ||||
|     global src, OpenWin, edge | ||||
| 
 | ||||
|     # 判断是否已经选取图片 | ||||
|     if src is None: | ||||
|         messagebox.showerror("错误", "没有选择图片!") | ||||
|         return | ||||
| 
 | ||||
|     # 交叉结构元 | ||||
|     kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5)) | ||||
| 
 | ||||
|     # 进行开运算 | ||||
|     open_result = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel) | ||||
| 
 | ||||
|     # 更新 edge 变量 | ||||
|     edge = Image.fromarray(open_result) | ||||
| 
 | ||||
|     # 创建 Toplevel 窗口 | ||||
|     try: | ||||
|         OpenWin.destroy() | ||||
|     except Exception: | ||||
|         print("NVM") | ||||
|     finally: | ||||
|         OpenWin = Toplevel(root) | ||||
|         OpenWin.attributes('-topmost', True) | ||||
|     OpenWin.geometry("360x300") | ||||
|     OpenWin.resizable(True, True)  # 可缩放 | ||||
|     OpenWin.title("开运算结果") | ||||
| 
 | ||||
|     # 显示图像 | ||||
|     LabelPic = tk.Label(OpenWin, text="IMG", width=360, height=240) | ||||
|     image = ImageTk.PhotoImage(Image.fromarray(open_result)) | ||||
|     LabelPic.image = image | ||||
|     LabelPic['image'] = image | ||||
| 
 | ||||
|     LabelPic.bind('<Configure>', lambda event: changeSize(event, open_result, LabelPic)) | ||||
|     LabelPic.pack(fill=tk.BOTH, expand=tk.YES) | ||||
| 
 | ||||
|     # 添加保存按钮 | ||||
|     btn_save = tk.Button(OpenWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, command=savefile) | ||||
|     btn_save.pack(pady=10) | ||||
| 
 | ||||
|     return | ||||
| 
 | ||||
| # 闭运算 | ||||
| def close_op(root): | ||||
|     """ | ||||
|     闭运算操作 | ||||
|     """ | ||||
|     global src, CloseWin, edge | ||||
| 
 | ||||
|     # 判断是否已经选取图片 | ||||
|     if src is None: | ||||
|         messagebox.showerror("错误", "没有选择图片!") | ||||
|         return | ||||
| 
 | ||||
|     # 交叉结构元 | ||||
|     kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (10, 10)) | ||||
| 
 | ||||
|     # 进行闭运算 | ||||
|     close_result = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel) | ||||
| 
 | ||||
|     # 更新 edge 变量 | ||||
|     edge = Image.fromarray(close_result) | ||||
| 
 | ||||
|     # 创建 Toplevel 窗口 | ||||
|     try: | ||||
|         CloseWin.destroy() | ||||
|     except Exception: | ||||
|         print("NVM") | ||||
|     finally: | ||||
|         CloseWin = Toplevel(root) | ||||
|         CloseWin.attributes('-topmost', True) | ||||
|     CloseWin.geometry("360x300") | ||||
|     CloseWin.resizable(True, True)  # 可缩放 | ||||
|     CloseWin.title("闭运算结果") | ||||
| 
 | ||||
|     # 显示图像 | ||||
|     LabelPic = tk.Label(CloseWin, text="IMG", width=360, height=240) | ||||
|     image = ImageTk.PhotoImage(Image.fromarray(close_result)) | ||||
|     LabelPic.image = image | ||||
|     LabelPic['image'] = image | ||||
| 
 | ||||
|     LabelPic.bind('<Configure>', lambda event: changeSize(event, close_result, LabelPic)) | ||||
|     LabelPic.pack(fill=tk.BOTH, expand=tk.YES) | ||||
| 
 | ||||
|     # 添加保存按钮 | ||||
|     btn_save = tk.Button(CloseWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, command=savefile) | ||||
|     btn_save.pack(pady=10) | ||||
| 
 | ||||
|     return | ||||
| 
 | ||||
| # 边缘检测 | ||||
| def edge_detection(root): | ||||
|     """ | ||||
|     边缘检测操作 | ||||
|     """ | ||||
|     global src, EdgeWin, edge | ||||
| 
 | ||||
|     # 判断是否已经选取图片 | ||||
|     if src is None: | ||||
|         messagebox.showerror("错误", "没有选择图片!") | ||||
|         return | ||||
| 
 | ||||
|     # 使用 Sobel 算子进行边缘检测 | ||||
|     sobelx = cv2.Sobel(cv2.cvtColor(src, cv2.COLOR_RGB2GRAY), cv2.CV_64F, 1, 0, ksize=5) | ||||
|     sobely = cv2.Sobel(cv2.cvtColor(src, cv2.COLOR_RGB2GRAY), cv2.CV_64F, 0, 1, ksize=5) | ||||
|     abs_sobelx = np.absolute(sobelx) | ||||
|     abs_sobely = np.absolute(sobely) | ||||
|     sobel_combined = cv2.bitwise_or(np.uint8(abs_sobelx), np.uint8(abs_sobely)) | ||||
|     sobel_combined = cv2.cvtColor(sobel_combined, cv2.COLOR_GRAY2RGB) | ||||
| 
 | ||||
|     # 更新 edge 变量 | ||||
|     edge = Image.fromarray(sobel_combined) | ||||
| 
 | ||||
|     # 创建 Toplevel 窗口 | ||||
|     try: | ||||
|         EdgeWin.destroy() | ||||
|     except Exception: | ||||
|         print("NVM") | ||||
|     finally: | ||||
|         EdgeWin = Toplevel(root) | ||||
|         EdgeWin.attributes('-topmost', True) | ||||
|     EdgeWin.geometry("360x300") | ||||
|     EdgeWin.resizable(True, True)  # 可缩放 | ||||
|     EdgeWin.title("边缘检测结果") | ||||
| 
 | ||||
|     # 显示图像 | ||||
|     LabelPic = tk.Label(EdgeWin, text="IMG", width=360, height=240) | ||||
|     image = ImageTk.PhotoImage(Image.fromarray(sobel_combined)) | ||||
|     LabelPic.image = image | ||||
|     LabelPic['image'] = image | ||||
| 
 | ||||
|     LabelPic.bind('<Configure>', lambda event: changeSize(event, sobel_combined, LabelPic)) | ||||
|     LabelPic.pack(fill=tk.BOTH, expand=tk.YES) | ||||
| 
 | ||||
|     # 添加保存按钮 | ||||
|     btn_save = tk.Button(EdgeWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, command=savefile) | ||||
|     btn_save.pack(pady=10) | ||||
| 
 | ||||
|     return | ||||
					Loading…
					
					
				
		Reference in new issue