Update noise_filter.py

main
pos97em56 5 months ago
parent 6570ee0239
commit 6ed7cee447

@ -1,303 +1,293 @@
import tkinter as tk import tkinter as tk
from tkinter import filedialog, messagebox from tkinter import filedialog, messagebox
from tkinter import Toplevel from tkinter import Toplevel
from PIL import Image, ImageTk from PIL import Image, ImageTk
import numpy as np import numpy as np
import math import math
import cv2 import cv2
import os import os
img_path = "" # 全局变量,用于存储图像路径 img_path = "" # 全局变量,用于存储图像路径
src = None # 全局变量,用于存储已选择的图像 src = None # 全局变量,用于存储已选择的图像
X = None # 用于存储第一张图像 X = None # 用于存储第一张图像
Y = None # 用于存储第二张图像 Y = None # 用于存储第二张图像
img_label = None # 全局变量,用于存储显示选择的图片的标签 img_label = None # 全局变量,用于存储显示选择的图片的标签
GeomeanWin = None GeomeanWin = None
SortstatWin = None SortstatWin = None
SelectWin = None SelectWin = None
def select_image(root): def select_image(root):
global img_path, src, img_label, edge global img_path, src, img_label, edge
img_path = filedialog.askopenfilename(filetypes=[("Image files", "*.jpg;*.png;*.jpeg;*.bmp")]) img_path = filedialog.askopenfilename(filetypes=[("Image files", "*.jpg;*.png;*.jpeg;*.bmp")])
if img_path: if img_path:
# 确保路径中的反斜杠正确处理,并使用 UTF-8 编码处理中文路径 # 确保路径中的反斜杠正确处理,并使用 UTF-8 编码处理中文路径
img_path_fixed = os.path.normpath(img_path) img_path_fixed = os.path.normpath(img_path)
# 图像输入 # 图像输入
src_temp = cv2.imdecode(np.fromfile(img_path_fixed, dtype=np.uint8), cv2.IMREAD_UNCHANGED) src_temp = cv2.imdecode(np.fromfile(img_path_fixed, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
if src_temp is None: if src_temp is None:
messagebox.showerror("错误", "无法读取图片,请选择有效的图片路径") messagebox.showerror("错误", "无法读取图片,请选择有效的图片路径")
return return
src = cv2.cvtColor(src_temp, cv2.COLOR_BGR2RGB) src = cv2.cvtColor(src_temp, cv2.COLOR_BGR2RGB)
# 检查 img_label 是否存在且有效 # 检查 img_label 是否存在且有效
if img_label is None or not img_label.winfo_exists(): if img_label is None or not img_label.winfo_exists():
img_label = tk.Label(root) img_label = tk.Label(root)
img_label.pack(side=tk.TOP, pady=10) img_label.pack(side=tk.TOP, pady=10)
img = Image.open(img_path) img = Image.open(img_path)
img.thumbnail((160, 160)) img.thumbnail((160, 160))
img_tk = ImageTk.PhotoImage(img) img_tk = ImageTk.PhotoImage(img)
img_label.configure(image=img_tk) img_label.configure(image=img_tk)
img_label.image = img_tk img_label.image = img_tk
# 定义 edge 变量为 PIL.Image 对象,以便稍后保存 # 定义 edge 变量为 PIL.Image 对象,以便稍后保存
edge = Image.fromarray(src) edge = Image.fromarray(src)
else: else:
messagebox.showerror("错误", "没有选择图片路径") messagebox.showerror("错误", "没有选择图片路径")
def show_selected_image(root): def changeSize(event, img, LabelPic):
global img_label img_aspect = img.shape[1] / img.shape[0]
img_label = tk.Label(root) new_aspect = event.width / event.height
img_label.pack(side=tk.TOP, pady=10)
img = Image.open(img_path) if new_aspect > img_aspect:
img.thumbnail((160, 160)) new_width = int(event.height * img_aspect)
img_tk = ImageTk.PhotoImage(img) new_height = event.height
img_label.configure(image=img_tk) else:
img_label.image = img_tk new_width = event.width
new_height = int(event.width / img_aspect)
def changeSize(event, img, LabelPic):
img_aspect = img.shape[1] / img.shape[0] resized_image = cv2.resize(img, (new_width, new_height))
new_aspect = event.width / event.height image1 = ImageTk.PhotoImage(Image.fromarray(resized_image))
LabelPic.image = image1
if new_aspect > img_aspect: LabelPic['image'] = image1
new_width = int(event.height * img_aspect)
new_height = event.height def savefile():
else: global edge
new_width = event.width
new_height = int(event.width / img_aspect) filename = filedialog.asksaveasfilename(defaultextension=".jpg", filetypes=[("JPEG files", "*.jpg"), ("PNG files", "*.png"), ("BMP files", "*.bmp")])
if not filename:
resized_image = cv2.resize(img, (new_width, new_height)) return
image1 = ImageTk.PhotoImage(Image.fromarray(resized_image)) # 确保 edge 变量已定义
LabelPic.image = image1 if edge is not None:
LabelPic['image'] = image1 try:
edge.save(filename)
def savefile(): messagebox.showinfo("保存成功", "图片保存成功!")
global edge except Exception as e:
messagebox.showerror("保存失败", f"无法保存图片: {e}")
filename = filedialog.asksaveasfilename(defaultextension=".jpg", filetypes=[("JPEG files", "*.jpg"), ("PNG files", "*.png"), ("BMP files", "*.bmp")]) else:
if not filename: messagebox.showerror("保存失败", "没有图像可保存")
return
# 确保 edge 变量已定义 #几何均值滤波
if edge is not None: def geo_mean_filter(root):
try: global src, GeomeanWin, edge
edge.save(filename)
messagebox.showinfo("保存成功", "图片保存成功!") # 判断是否已经选取图片
except Exception as e: if src is None:
messagebox.showerror("保存失败", f"无法保存图片: {e}") messagebox.showerror("错误", "没有选择图片!")
else: return
messagebox.showerror("保存失败", "没有图像可保存")
image = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
#几何均值滤波
def geo_mean_filter(root): # 待输出的图片
global src, GeomeanWin, edge output = np.zeros(image.shape, np.uint8)
# 遍历图像,进行均值滤波
# 判断是否已经选取图片 for i in range(image.shape[0]):
if src is None: for j in range(image.shape[1]):
messagebox.showerror("错误", "没有选择图片!") # 计算均值,完成对图片src的几何均值滤波
return ji = 1.0
image = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) # 遍历滤波器内的像素值
for k in range(-1, 2):
# 待输出的图片 if 0 <= j + k < image.shape[1]:
output = np.zeros(image.shape, np.uint8) ji *= image[i, j + k]
# 遍历图像,进行均值滤波
for i in range(image.shape[0]): # 滤波器的大小为1*3
for j in range(image.shape[1]): geom_mean = math.pow(ji, 1 / 3.0)
# 计算均值,完成对图片src的几何均值滤波 output[i, j] = int(geom_mean)
ji = 1.0
# 更新 edge 变量
# 遍历滤波器内的像素值 edge = Image.fromarray(output)
for k in range(-1, 2):
if 0 <= j + k < image.shape[1]: # 创建Toplevel窗口
ji *= image[i, j + k] try:
GeomeanWin.destroy()
# 滤波器的大小为1*3 except Exception:
geom_mean = math.pow(ji, 1 / 3.0) print("NVM")
output[i, j] = int(geom_mean) finally:
GeomeanWin = Toplevel()
# 更新 edge 变量 GeomeanWin.attributes('-topmost', True)
edge = Image.fromarray(output) GeomeanWin.geometry("720x300")
GeomeanWin.resizable(True, True) # 可缩放
# 创建Toplevel窗口 GeomeanWin.title("几何均值滤波结果")
try:
GeomeanWin.destroy() # 显示图像
except Exception: LabelPic = tk.Label(GeomeanWin, text="IMG", width=360, height=240)
print("NVM") image = ImageTk.PhotoImage(Image.fromarray(output))
finally: LabelPic.image = image
GeomeanWin = Toplevel() LabelPic['image'] = image
GeomeanWin.attributes('-topmost', True)
GeomeanWin.geometry("720x300") LabelPic.bind('<Configure>', lambda event: changeSize(event, output, LabelPic))
GeomeanWin.resizable(True, True) # 可缩放 LabelPic.pack(fill=tk.BOTH, expand=tk.YES)
GeomeanWin.title("几何均值滤波结果")
# 添加保存按钮
# 显示图像 btn_save = tk.Button(GeomeanWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20,
LabelPic = tk.Label(GeomeanWin, text="IMG", width=360, height=240) command=savefile)
image = ImageTk.PhotoImage(Image.fromarray(output)) btn_save.pack(pady=10)
LabelPic.image = image
LabelPic['image'] = image return
LabelPic.bind('<Configure>', lambda event: changeSize(event, output, LabelPic)) #排序统计类滤波
LabelPic.pack(fill=tk.BOTH, expand=tk.YES) def sort_stat_filter(root):
global src, SortstatWin, combined, edge
# 添加保存按钮
btn_save = tk.Button(GeomeanWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, # 判断是否已经选取图片
command=savefile) if src is None:
btn_save.pack(pady=10) messagebox.showerror("错误", "没有选择图片!")
return
return
image = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
#排序统计类滤波
def sort_stat_filter(root): # 待输出的图片
global src, SortstatWin, combined, edge output_max = np.zeros(image.shape, np.uint8)
output_median = np.zeros(image.shape, np.uint8)
# 判断是否已经选取图片 output_min = np.zeros(image.shape, np.uint8)
if src is None:
messagebox.showerror("错误", "没有选择图片!") # 遍历图像
return for i in range(image.shape[0]):
for j in range(image.shape[1]):
image = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) # 用于存储3x3邻域像素值
neighbors = []
# 待输出的图片 for m in range(-1, 2):
output_max = np.zeros(image.shape, np.uint8) for n in range(-1, 2):
output_median = np.zeros(image.shape, np.uint8) if 0 <= i + m < image.shape[0] and 0 <= j + n < image.shape[1]:
output_min = np.zeros(image.shape, np.uint8) neighbors.append(image[i + m, j + n])
# 遍历图像 # 最大值滤波
for i in range(image.shape[0]): output_max[i, j] = max(neighbors)
for j in range(image.shape[1]): # 中值滤波
# 用于存储3x3邻域像素值 output_median[i, j] = np.median(neighbors)
neighbors = [] # 最小值滤波
for m in range(-1, 2): output_min[i, j] = min(neighbors)
for n in range(-1, 2):
if 0 <= i + m < image.shape[0] and 0 <= j + n < image.shape[1]: combined = np.hstack((output_max, output_median, output_min))
neighbors.append(image[i + m, j + n])
# 更新 edge 变量
# 最大值滤波 edge = Image.fromarray(combined)
output_max[i, j] = max(neighbors)
# 中值滤波 # 创建Toplevel窗口
output_median[i, j] = np.median(neighbors) try:
# 最小值滤波 SortstatWin.destroy()
output_min[i, j] = min(neighbors) except Exception:
print("NVM")
combined = np.hstack((output_max, output_median, output_min)) finally:
SortstatWin = Toplevel()
# 更新 edge 变量 SortstatWin.attributes('-topmost', True)
edge = Image.fromarray(combined) SortstatWin.geometry("720x300")
SortstatWin.resizable(True, True) # 可缩放
# 创建Toplevel窗口 SortstatWin.title("排序统计类滤波结果")
try:
SortstatWin.destroy() # 显示图像
except Exception: LabelPic = tk.Label(SortstatWin, text="IMG", width=360, height=240)
print("NVM") image = ImageTk.PhotoImage(Image.fromarray(combined))
finally: LabelPic.image = image
SortstatWin = Toplevel() LabelPic['image'] = image
SortstatWin.attributes('-topmost', True)
SortstatWin.geometry("720x300") LabelPic.bind('<Configure>', lambda event: changeSize(event, combined, LabelPic))
SortstatWin.resizable(True, True) # 可缩放 LabelPic.pack(fill=tk.BOTH, expand=tk.YES)
SortstatWin.title("排序统计类滤波结果")
# 添加保存按钮
# 显示图像 btn_save = tk.Button(SortstatWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20,
LabelPic = tk.Label(SortstatWin, text="IMG", width=360, height=240) command=savefile)
image = ImageTk.PhotoImage(Image.fromarray(combined)) btn_save.pack(pady=10)
LabelPic.image = image
LabelPic['image'] = image return
LabelPic.bind('<Configure>', lambda event: changeSize(event, combined, LabelPic)) #选择性滤波
LabelPic.pack(fill=tk.BOTH, expand=tk.YES) def selective_filter(root):
global src, SelectWin, combined, edge
# 添加保存按钮
btn_save = tk.Button(SortstatWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, # 判断是否已经选取图片
command=savefile) if src is None:
btn_save.pack(pady=10) messagebox.showerror("错误", "没有选择图片!")
return
return
image = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
#选择性滤波
def selective_filter(root): # 待输出的图片
global src, SelectWin, combined, edge output_low_pass = np.zeros(image.shape, np.uint8)
output_high_pass = np.zeros(image.shape, np.uint8)
# 判断是否已经选取图片 output_band_pass = np.zeros(image.shape, np.uint8)
if src is None: output_band_stop = np.zeros(image.shape, np.uint8)
messagebox.showerror("错误", "没有选择图片!")
return # 边界
low_pass_threshold = 100
image = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) high_pass_threshold = 100
band_pass_low_threshold = 100
# 待输出的图片 band_pass_high_threshold = 200
output_low_pass = np.zeros(image.shape, np.uint8) band_stop_low_threshold = 100
output_high_pass = np.zeros(image.shape, np.uint8) band_stop_high_threshold = 200
output_band_pass = np.zeros(image.shape, np.uint8)
output_band_stop = np.zeros(image.shape, np.uint8) # 遍历图像
for i in range(image.shape[0]):
# 边界 for j in range(image.shape[1]):
low_pass_threshold = 100 pixel_value = image[i][j]
high_pass_threshold = 100
band_pass_low_threshold = 100 # 低通滤波器
band_pass_high_threshold = 200 if pixel_value <= low_pass_threshold:
band_stop_low_threshold = 100 output_low_pass[i][j] = pixel_value
band_stop_high_threshold = 200 else:
output_low_pass[i][j] = 0
# 遍历图像
for i in range(image.shape[0]): # 高通滤波器
for j in range(image.shape[1]): if pixel_value >= high_pass_threshold:
pixel_value = image[i][j] output_high_pass[i][j] = pixel_value
else:
# 低通滤波器 output_high_pass[i][j] = 0
if pixel_value <= low_pass_threshold:
output_low_pass[i][j] = pixel_value # 带通滤波器
else: if band_pass_low_threshold < pixel_value <= band_pass_high_threshold:
output_low_pass[i][j] = 0 output_band_pass[i][j] = pixel_value
else:
# 高通滤波器 output_band_pass[i][j] = 0
if pixel_value >= high_pass_threshold:
output_high_pass[i][j] = pixel_value # 带阻滤波器
else: if band_stop_low_threshold < pixel_value <= band_stop_high_threshold:
output_high_pass[i][j] = 0 output_band_stop[i][j] = 0
else:
# 带通滤波器 output_band_stop[i][j] = pixel_value
if band_pass_low_threshold < pixel_value <= band_pass_high_threshold:
output_band_pass[i][j] = pixel_value combined = np.hstack((output_low_pass, output_high_pass, output_band_pass, output_band_stop))
else:
output_band_pass[i][j] = 0 # 更新 edge 变量
edge = Image.fromarray(combined)
# 带阻滤波器
if band_stop_low_threshold < pixel_value <= band_stop_high_threshold: # 创建Toplevel窗口
output_band_stop[i][j] = 0 try:
else: SelectWin.destroy()
output_band_stop[i][j] = pixel_value except Exception:
print("NVM")
combined = np.hstack((output_low_pass, output_high_pass, output_band_pass, output_band_stop)) finally:
SelectWin = Toplevel()
# 更新 edge 变量 SelectWin.attributes('-topmost', True)
edge = Image.fromarray(combined) SelectWin.geometry("720x300")
SelectWin.resizable(True, True) # 可缩放
# 创建Toplevel窗口 SelectWin.title("选择性滤波结果")
try:
SelectWin.destroy() # 显示图像
except Exception: LabelPic = tk.Label(SelectWin, text="IMG", width=360, height=240)
print("NVM") image = ImageTk.PhotoImage(Image.fromarray(combined))
finally: LabelPic.image = image
SelectWin = Toplevel() LabelPic['image'] = image
SelectWin.attributes('-topmost', True)
SelectWin.geometry("720x300") LabelPic.bind('<Configure>', lambda event: changeSize(event, combined, LabelPic))
SelectWin.resizable(True, True) # 可缩放 LabelPic.pack(fill=tk.BOTH, expand=tk.YES)
SelectWin.title("选择性滤波结果")
# 添加保存按钮
# 显示图像 btn_save = tk.Button(SelectWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20,
LabelPic = tk.Label(SelectWin, text="IMG", width=360, height=240) command=savefile)
image = ImageTk.PhotoImage(Image.fromarray(combined)) btn_save.pack(pady=10)
LabelPic.image = image
LabelPic['image'] = image
LabelPic.bind('<Configure>', lambda event: changeSize(event, combined, LabelPic))
LabelPic.pack(fill=tk.BOTH, expand=tk.YES)
# 添加保存按钮
btn_save = tk.Button(SelectWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20,
command=savefile)
btn_save.pack(pady=10)
return return
Loading…
Cancel
Save