主界面
代码部分
import torch.nn as nn
import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk,ImageDraw,ImageFont
import torch
from torchvision import transforms, models
from efficientnet_pytorch import EfficientNet
import numpy as np
import cv2
import tkinter.ttk as ttk
import time
import subprocess
class EfficientNetModel(nn.Module):
def __init__(self, num_classes=10, pretrained=True):
super(EfficientNetModel, self).__init__()
# 加载预训练的EfficientNet模型
self.efficientnet = EfficientNet.from_name('efficientnet-b3')
num_ftrs = self.efficientnet._fc.in_features
# 将EfficientNet模型的最后一层全连接层替换为一个新的全连接层,输出特征数量设置为num_classes
self.efficientnet._fc = nn.Linear(num_ftrs, num_classes)
# forward方法定义了前向传播过程
def forward(self, x):
return self.efficientnet(x)
# Example usage
model = EfficientNetModel(num_classes=12)
# # 定义并加载 ResNet-50 模型
# num_classes = 10 # 根据实际类别数修改
# model = models.resnet50(weights=None)
# model.fc = nn.Linear(model.fc.in_features, num_classes)
# 加载训练好的模型参数
model_path = 'best_EfficientNet_b3_updata6.pth'
model.load_state_dict(torch.load(model_path, map_location=torch.device('cpu')))
model.eval()
# 定义图像转换
transform = transforms.Compose([
transforms.Resize((300, 300)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), # ResNet-50 的标准化
])
# 类别标签(请根据您的实际类别名称设置)
classes = ['皮卡', '敞篷车', '跑车', '掀背两箱车', '小型面包车', 'SUV', '轿车', '厢式货车', '旅行车', '公共汽车', '消防车', '出租车']
# 初始化全局变量
selected_image_path = None
label_text = None
right_canvas_image = None
def upload_image():
global selected_image_path, label_text
file_path = filedialog.askopenfilename()
if file_path:
selected_image_path = file_path
image = Image.open(file_path)
# 调整图片大小为500x400
image = image.resize((500, 400), Image.Resampling.LANCZOS)
# 居中图片
photo = ImageTk.PhotoImage(image)
canvas_left.create_image(0, 0, anchor='nw', image=photo)
canvas_left.image = photo # Keep a reference!
# 创建图片的标签
if label_text is None:
label_text = tk.Label(window, text="", font=("Arial", 16))
label_text.grid(row=3, column=0, columnspan=2, padx=10, pady=10)
def start_detection():
global right_canvas_image
if selected_image_path is not None:
image = Image.open(selected_image_path)
input_image = transform(image).unsqueeze(0)
with torch.no_grad():
outputs = model(input_image)
_, predicted = torch.max(outputs, 1)
label = classes[predicted.item()]
probabilities = torch.nn.functional.softmax(outputs, dim=1)
max_probability = probabilities[0][predicted].item() * 100 # 将概率值乘以100
label_text.config(text=f"{label} - {max_probability:.2f}%") # 显示为百分比格式
# 调整图片大小为500x400
image = image.resize((500, 400), Image.Resampling.LANCZOS)
# 显示图片在右侧画布
photo = ImageTk.PhotoImage(image)
# 检查是否已经创建了右侧画布的图片
if right_canvas_image is None:
right_canvas_image = canvas_right.create_image(0, 0, anchor='nw', image=photo)
else:
canvas_right.itemconfig(right_canvas_image, image=photo)
canvas_right.image = photo # 保持引用
else:
messagebox.showwarning("警告", "请先选择一张图像")
# 将标签放置在图片上
label_text.place(x=1185,y=155)
def replaceZeroes(data):
min_nonzero = min(data[np.nonzero(data)])
data[data == 0] = min_nonzero
return data
def MSR(img, scales):
weight = 1 / 3.0
scales_size = len(scales)
h, w = img.shape[:2]
log_R = np.zeros((h, w), dtype=np.float32)
for i in range(scales_size):
img = replaceZeroes(img)
L_blur = cv2.GaussianBlur(img, (scales[i], scales[i]), 0)
L_blur = replaceZeroes(L_blur)
dst_Img = cv2.log(img / 255.0)
dst_Lblur = cv2.log(L_blur / 255.0)
dst_Ixl = cv2.multiply(dst_Img, dst_Lblur)
log_R += weight * cv2.subtract(dst_Img, dst_Ixl)
dst_R = cv2.normalize(log_R, None, 0, 255, cv2.NORM_MINMAX)
log_uint8 = cv2.convertScaleAbs(dst_R)
return log_uint8
def img_inten():
global selected_image_path, right_canvas_image
if selected_image_path is not None:
# 创建进度条
progress = ttk.Progressbar(window, orient='horizontal', length=160, mode='determinate', maximum=100)
#进度条位置
progress.place(x=1000, y=160)
label_text.config(text=f"处理中")
# 模拟图像处理过程
window.after(100, lambda: process_image(progress))
else:
messagebox.showwarning("警告", "请先选择一张图像")
def process_image(progress):
# 模拟图像处理
steps = 3 # 假设有10个处理步骤
for i in range(steps):
time.sleep(1) # 每个步骤耗时1秒
progress['value'] += 35 # 每个步骤增加10%的进度
window.update_idletasks() # 更新进度条显示
# 停止进度条
progress.stop()
progress.grid_forget() # 隐藏进度条
# 显示处理后的图像和检测结果
global selected_image_path, right_canvas_image
if selected_image_path is not None:
# 读取图像
image = Image.open(selected_image_path)
# 转换为OpenCV格式
image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
# 应用MSR算法
scales = [15, 101, 301] # 可根据需要调整
b_gray, g_gray, r_gray = cv2.split(image)
b_gray = MSR(b_gray, scales)
g_gray = MSR(g_gray, scales)
r_gray = MSR(r_gray, scales)
enhanced_image = cv2.merge([b_gray, g_gray, r_gray])
# 转换回PIL图像格式
enhanced_image = Image.fromarray(cv2.cvtColor(enhanced_image, cv2.COLOR_BGR2RGB))
# 调整图像大小以适应模型输入
enhanced_image = enhanced_image.resize((500, 400), Image.Resampling.LANCZOS)
# 转换图像为模型可以接受的格式
input_image = transform(enhanced_image).unsqueeze(0)
# 使用模型进行检测
with torch.no_grad():
outputs = model(input_image)
_, predicted = torch.max(outputs, 1)
label = classes[predicted.item()]
probabilities = torch.nn.functional.softmax(outputs, dim=1)
max_probability = probabilities[0][predicted].item() * 100
# 更新标签文本
label_text.config(text=f"处理完成")
# 显示增强后的图像和检测结果在右侧画布
enhanced_image = enhanced_image.resize((500, 400), Image.Resampling.LANCZOS)
photo = ImageTk.PhotoImage(enhanced_image)
if right_canvas_image is None:
right_canvas_image = canvas_right.create_image(0, 0, anchor='nw', image=photo)
else:
canvas_right.itemconfig(right_canvas_image, image=photo)
canvas_right.image = photo # 保持引用
# 更新标签文本
label_text.config(text=f"{label} - {max_probability:.2f}%") # 显示为百分比格式。
# 创建主窗口
window = tk.Tk()
window.title("图像目标检测系统")
window.geometry('1400x700') # 设置窗口大小
# 创建背景画布并使用grid布局管理器
canvas_background = tk.Canvas(window, width=1400, height=700)
canvas_background.grid(row=0, column=0, columnspan=2, rowspan=4, sticky='nsew') # 使用grid管理器
# 打开图片
image = Image.open(r"ttbb\background.jpg")
# 转换图像模式为RGB
image = image.convert("RGB")
draw = ImageDraw.Draw(image)
# 定义要画的文字和位置
text = "待检测的图片:"
position = (440, 190) # 文字的左上角位置坐标
# 定义字体和字号
font = ImageFont.truetype("SourceHanSansSC-Bold.otf", 30) # 使用字体,字号30
# 画文字
draw.text(position, text, fill=(0, 0, 0), font=font) # fill参数为文字颜色
text2 = "检测结果:"
position = (1180, 190) # 文字的左上角位置坐标
# 定义字体和字号
font = ImageFont.truetype("SourceHanSansSC-Bold.otf", 30) # 使用字体,字号30
# 画文字
draw.text(position, text2, fill=(0, 0, 0), font=font) # fill参数为文字颜色
text3 = "基于深度学习车型检测的关键算法设计"
position = (580, 10) # 文字的左上角位置坐标
# 定义字体和字号
font = ImageFont.truetype("SourceHanSansSC-Bold.otf", 50) # 使用字体,字号30
# 画文字
draw.text(position, text3, fill=(0, 0, 0), font=font) # fill参数为文字颜色
text4 = "功能区"
position = (100, 135)
# 定义字体和字号
font = ImageFont.truetype("SourceHanSansSC-Bold.otf", 30) # 使用字体,字号30
# 画文字
draw.text(position, text4, fill=(0, 0, 0), font=font) # fill参数为文字颜色
draw.line((12, 157, 91, 157), fill='black',width=3)
draw.line((12, 157, 12, 600), fill='black',width=3)
draw.line((12, 600, 285, 600), fill='black',width=3)
draw.line((285, 600, 285, 157), fill='black',width=3)
draw.line((285, 157, 192, 157), fill='black',width=3)
# 加载背景图像
background_image = image
background_image = background_image.resize((1400, 700), Image.Resampling.LANCZOS) # 调整图像大小以适应窗口
background_photo = ImageTk.PhotoImage(background_image)
# 在背景画布上绘制背景图像
canvas_background.create_image(0, 0, anchor='nw', image=background_photo)
canvas_background.image = background_photo # 保持对图像的引用
# 创建两个画布区域
canvas_left = tk.Canvas(window, width=500, height=400, bg="#e6f2ff")
canvas_right = tk.Canvas(window, width=500, height=400, bg="#e6f2ff")
# 将两个画布区域放置在主窗口中
canvas_left.place(x=325, y=200)
canvas_right.place(x=865, y=200)
# 创建按钮并放置在主窗口上
button_upload = tk.Button(window, width=13, text='上传图片', font=14, command=upload_image)
button_start_detection = tk.Button(window, width=13, text='开始检测', font=14, command=start_detection)
img_intensification = tk.Button(window, width=13, text='图像增强', font=14, command=img_inten)
# 将按钮放置在主窗口上
button_upload.place(x=35, y=170)
button_start_detection.place(x=35, y=230)
img_intensification.place(x=35, y=290)
#
# 运行主窗口
window.mainloop()
功能介绍
图片增强