汽车识别系统

主界面

在这里插入图片描述

代码部分

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()

功能介绍

在这里插入图片描述

图片增强

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值