Update image_enhance.py

main
pos97em56 5 months ago
parent 4d549d031f
commit 87a6541480

@ -1,284 +1,271 @@
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 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 # 用于存储显示选择的图片的标签
edge = None # 用于存储处理后的图像 edge = None # 用于存储处理后的图像
GraylineWin = None # 线性变换窗口 GraylineWin = None # 线性变换窗口
GraylogWin = None # 对数变换窗口 GraylogWin = None # 对数变换窗口
EqualWin = None # 直方图均衡化窗口 EqualWin = None # 直方图均衡化窗口
RegulWin = None # 直方图正规化窗口 RegulWin = 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:
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) # 转换为 RGB 格式 src = cv2.cvtColor(src_temp, cv2.COLOR_BGR2RGB) # 转换为 RGB 格式
# 创建或更新图像标签 # 创建或更新图像标签
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 = Image.fromarray(src) # 更新 edge 变量为 PIL.Image 对象 edge = Image.fromarray(src) # 更新 edge 变量为 PIL.Image 对象
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):
""" resized_image = cv2.resize(img, (new_width, new_height))
根据窗口尺寸调整图像大小并显示 image1 = ImageTk.PhotoImage(Image.fromarray(resized_image))
""" LabelPic.image = image1
img_aspect = img.shape[1] / img.shape[0] LabelPic['image'] = image1
new_aspect = event.width / event.height
def savefile():
if new_aspect > img_aspect: """
new_width = int(event.height * img_aspect) 保存处理后的图像
new_height = event.height """
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)) if edge is not None:
LabelPic.image = image1 try:
LabelPic['image'] = image1 edge.save(filename)
messagebox.showinfo("保存成功", "图片保存成功!")
def savefile(): except Exception as e:
""" messagebox.showerror("保存失败", f"无法保存图片: {e}")
保存处理后的图像 else:
""" messagebox.showerror("保存失败", "没有图像可保存")
global edge
def line_tra(root):
filename = filedialog.asksaveasfilename(defaultextension=".jpg", filetypes=[("JPEG files", "*.jpg"), ("PNG files", "*.png"), ("BMP files", "*.bmp")]) """
if not filename: 进行线性变换
return """
if edge is not None: global src, GraylineWin, edge
try:
edge.save(filename) # 判断是否已经选择图片
messagebox.showinfo("保存成功", "图片保存成功!") if src is None:
except Exception as e: messagebox.showerror("错误", "没有选择图片!")
messagebox.showerror("保存失败", f"无法保存图片: {e}") return
else:
messagebox.showerror("保存失败", "没有图像可保存") gray_src = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) # 转换为灰度图
def line_tra(root): a = 20
""" b = 241
进行线性变换 c = 0
""" d = 255
global src, GraylineWin, edge
result = (d - c) / (b - a) * gray_src + (b * c - a * d) / (b - a) # 线性变换公式
# 判断是否已经选择图片
if src is None: edge = Image.fromarray(result) # 更新 edge 变量
messagebox.showerror("错误", "没有选择图片!")
return # 创建或更新线性变换结果窗口
try:
gray_src = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) # 转换为灰度图 GraylineWin.destroy()
except Exception:
a = 20 print("NVM")
b = 241 finally:
c = 0 GraylineWin = Toplevel()
d = 255 GraylineWin.attributes('-topmost', True)
GraylineWin.geometry("360x300")
result = (d - c) / (b - a) * gray_src + (b * c - a * d) / (b - a) # 线性变换公式 GraylineWin.resizable(True, True)
GraylineWin.title("线性变换结果")
edge = Image.fromarray(result) # 更新 edge 变量
# 显示处理后的图像
# 创建或更新线性变换结果窗口 LabelPic = tk.Label(GraylineWin, text="IMG", width=360, height=240)
try: image = ImageTk.PhotoImage(Image.fromarray(result))
GraylineWin.destroy() LabelPic.image = image
except Exception: LabelPic['image'] = image
print("NVM")
finally: LabelPic.bind('<Configure>', lambda event: changeSize(event, result, LabelPic))
GraylineWin = Toplevel() LabelPic.pack(fill=tk.BOTH, expand=tk.YES)
GraylineWin.attributes('-topmost', True)
GraylineWin.geometry("360x300") btn_save = tk.Button(GraylineWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, command=savefile)
GraylineWin.resizable(True, True) btn_save.pack(pady=10)
GraylineWin.title("线性变换结果")
def log_tra(root):
# 显示处理后的图像 """
LabelPic = tk.Label(GraylineWin, text="IMG", width=360, height=240) 进行对数变换
image = ImageTk.PhotoImage(Image.fromarray(result)) """
LabelPic.image = image global src, GraylogWin, edge
LabelPic['image'] = image
# 判断是否已经选择图片
LabelPic.bind('<Configure>', lambda event: changeSize(event, result, LabelPic)) if src is None:
LabelPic.pack(fill=tk.BOTH, expand=tk.YES) messagebox.showerror("错误", "没有选择图片!")
return
btn_save = tk.Button(GraylineWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, command=savefile)
btn_save.pack(pady=10) gray_src = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) # 转换为灰度图
def log_tra(root): C = 255 / np.log(1 + 255) # 对数变换常数
""" result = np.array(C * np.log(1 + gray_src), np.float64) # 对数变换公式
进行对数变换
""" edge = Image.fromarray(result) # 更新 edge 变量
global src, GraylogWin, edge
# 创建或更新对数变换结果窗口
# 判断是否已经选择图片 try:
if src is None: GraylogWin.destroy()
messagebox.showerror("错误", "没有选择图片!") except Exception:
return print("NVM")
finally:
gray_src = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) # 转换为灰度图 GraylogWin = Toplevel()
GraylogWin.attributes('-topmost', True)
C = 255 / np.log(1 + 255) # 对数变换常数 GraylogWin.geometry("360x300")
result = np.array(C * np.log(1 + gray_src), np.float64) # 对数变换公式 GraylogWin.resizable(True, True)
GraylogWin.title("对数变换结果")
edge = Image.fromarray(result) # 更新 edge 变量
# 显示处理后的图像
# 创建或更新对数变换结果窗口 LabelPic = tk.Label(GraylogWin, text="IMG", width=360, height=240)
try: image = ImageTk.PhotoImage(Image.fromarray(result))
GraylogWin.destroy() LabelPic.image = image
except Exception: LabelPic['image'] = image
print("NVM")
finally: LabelPic.bind('<Configure>', lambda event: changeSize(event, result, LabelPic))
GraylogWin = Toplevel() LabelPic.pack(fill=tk.BOTH, expand=tk.YES)
GraylogWin.attributes('-topmost', True)
GraylogWin.geometry("360x300") btn_save = tk.Button(GraylogWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, command=savefile)
GraylogWin.resizable(True, True) btn_save.pack(pady=10)
GraylogWin.title("对数变换结果")
def equal(root):
# 显示处理后的图像 """
LabelPic = tk.Label(GraylogWin, text="IMG", width=360, height=240) 进行直方图均衡化
image = ImageTk.PhotoImage(Image.fromarray(result)) """
LabelPic.image = image global src, EqualWin, edge
LabelPic['image'] = image
# 判断是否已经选择图片
LabelPic.bind('<Configure>', lambda event: changeSize(event, result, LabelPic)) if src is None:
LabelPic.pack(fill=tk.BOTH, expand=tk.YES) messagebox.showerror("错误", "没有选择图片!")
return
btn_save = tk.Button(GraylogWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, command=savefile)
btn_save.pack(pady=10) gray_src = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) # 转换为灰度图
original_size = gray_src.shape # 保存原始图像尺寸
def equal(root): gray_src_resized = cv2.resize(gray_src, (256, 256)) # 图像放缩到 256 x 256
""" hist = cv2.calcHist([gray_src_resized], [0], None, [256], [0, 256]) # 计算直方图
进行直方图均衡化 equ_resized = cv2.equalizeHist(gray_src_resized) # 均衡化
""" equ = cv2.resize(equ_resized, (original_size[1], original_size[0])) # 恢复均衡化后的图像到原始尺寸
global src, EqualWin, edge
edge = Image.fromarray(equ) # 更新 edge 变量
# 判断是否已经选择图片
if src is None: # 创建或更新直方图均衡化结果窗口
messagebox.showerror("错误", "没有选择图片!") try:
return EqualWin.destroy()
except Exception as e:
gray_src = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) # 转换为灰度图 print("NVM")
original_size = gray_src.shape # 保存原始图像尺寸 finally:
gray_src_resized = cv2.resize(gray_src, (256, 256)) # 图像放缩到 256 x 256 EqualWin = Toplevel()
hist = cv2.calcHist([gray_src_resized], [0], None, [256], [0, 256]) # 计算直方图 EqualWin.attributes('-topmost', True)
equ_resized = cv2.equalizeHist(gray_src_resized) # 均衡化 EqualWin.geometry("360x300")
equ = cv2.resize(equ_resized, (original_size[1], original_size[0])) # 恢复均衡化后的图像到原始尺寸 EqualWin.resizable(True, True)
EqualWin.title("直方图均衡化结果")
edge = Image.fromarray(equ) # 更新 edge 变量
# 显示处理后的图像
# 创建或更新直方图均衡化结果窗口 LabelPic = tk.Label(EqualWin, text="IMG", width=720, height=480)
try: image = ImageTk.PhotoImage(Image.fromarray(equ))
EqualWin.destroy() LabelPic.image = image
except Exception as e: LabelPic['image'] = image
print("NVM")
finally: LabelPic.bind('<Configure>', lambda event: changeSize(event, equ, LabelPic))
EqualWin = Toplevel() LabelPic.pack(fill=tk.BOTH, expand=tk.YES)
EqualWin.attributes('-topmost', True)
EqualWin.geometry("360x300") btn_save = tk.Button(EqualWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, command=savefile)
EqualWin.resizable(True, True) btn_save.pack(pady=10)
EqualWin.title("直方图均衡化结果")
def regul(root):
# 显示处理后的图像 """
LabelPic = tk.Label(EqualWin, text="IMG", width=720, height=480) 进行直方图正规化
image = ImageTk.PhotoImage(Image.fromarray(equ)) """
LabelPic.image = image global src, RegulWin, edge
LabelPic['image'] = image
# 判断是否已经选择图片
LabelPic.bind('<Configure>', lambda event: changeSize(event, equ, LabelPic)) if src is None:
LabelPic.pack(fill=tk.BOTH, expand=tk.YES) messagebox.showerror("错误", "没有选择图片!")
return
btn_save = tk.Button(EqualWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, command=savefile)
btn_save.pack(pady=10) gray_src = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) # 转换为灰度图
original_size = gray_src.shape # 保存原始图像尺寸
def regul(root): gray_src_resized = cv2.resize(gray_src, (256, 256)) # 图像放缩到 256 x 256
""" hist = cv2.calcHist([gray_src_resized], [0], None, [256], [0, 256]) # 计算直方图
进行直方图正规化 cv2.normalize(hist, hist, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX) # 正规化
""" result = np.zeros((256, 256), dtype=np.uint8) # 初始化结果图像
global src, RegulWin, edge
for i in range(256):
# 判断是否已经选择图片 result[gray_src_resized == i] = hist[i] # 应用正规化直方图
if src is None:
messagebox.showerror("错误", "没有选择图片!") equ = cv2.resize(result, (original_size[1], original_size[0])) # 恢复正规化后的图像到原始尺寸
return
edge = Image.fromarray(equ) # 更新 edge 变量
gray_src = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) # 转换为灰度图
original_size = gray_src.shape # 保存原始图像尺寸 # 创建或更新直方图正规化结果窗口
gray_src_resized = cv2.resize(gray_src, (256, 256)) # 图像放缩到 256 x 256 try:
hist = cv2.calcHist([gray_src_resized], [0], None, [256], [0, 256]) # 计算直方图 RegulWin.destroy()
cv2.normalize(hist, hist, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX) # 正规化 except Exception as e:
result = np.zeros((256, 256), dtype=np.uint8) # 初始化结果图像 print("NVM")
finally:
for i in range(256): RegulWin = Toplevel()
result[gray_src_resized == i] = hist[i] # 应用正规化直方图 RegulWin.attributes('-topmost', True)
RegulWin.geometry("360x300")
equ = cv2.resize(result, (original_size[1], original_size[0])) # 恢复正规化后的图像到原始尺寸 RegulWin.resizable(True, True)
RegulWin.title("直方图正规化结果")
edge = Image.fromarray(equ) # 更新 edge 变量
# 显示处理后的图像
# 创建或更新直方图正规化结果窗口 LabelPic = tk.Label(RegulWin, text="IMG", width=720, height=480)
try: image = ImageTk.PhotoImage(Image.fromarray(equ))
RegulWin.destroy() LabelPic.image = image
except Exception as e: LabelPic['image'] = image
print("NVM")
finally: LabelPic.bind('<Configure>', lambda event: changeSize(event, equ, LabelPic))
RegulWin = Toplevel() LabelPic.pack(fill=tk.BOTH, expand=tk.YES)
RegulWin.attributes('-topmost', True)
RegulWin.geometry("360x300") btn_save = tk.Button(RegulWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, command=savefile)
RegulWin.resizable(True, True) btn_save.pack(pady=10)
RegulWin.title("直方图正规化结果")
# 显示处理后的图像
LabelPic = tk.Label(RegulWin, text="IMG", width=720, height=480)
image = ImageTk.PhotoImage(Image.fromarray(equ))
LabelPic.image = image
LabelPic['image'] = image
LabelPic.bind('<Configure>', lambda event: changeSize(event, equ, LabelPic))
LabelPic.pack(fill=tk.BOTH, expand=tk.YES)
btn_save = tk.Button(RegulWin, text="保存", bg='#add8e6', fg='black', font=('Helvetica', 14), width=20, command=savefile)
btn_save.pack(pady=10)

Loading…
Cancel
Save