当前位置: 首页 > news >正文

汽车识别项目

窗口设计

这里的代码放在py文件最前面或者最后面都无所谓

# 创建主窗口
window = tk.Tk()
window.title("图像目标检测系统")
window.geometry('1000x650')  # 设置窗口大小# 创建背景画布并使用grid布局管理器
canvas_background = tk.Canvas(window, width=1000, height=650, bg="#e6f2ff")
canvas_background.grid(row=0, column=0, columnspan=2, rowspan=4, sticky='nsew')  # 使用grid管理器# 加载背景图像
background_image = Image.open(r"图标/5.jpg")  # 替换为您的背景图像路径
background_image = background_image.resize((1000, 650), 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  # 保持对图像的引用# 加载按钮图片
upload_img = Image.open(r"图标/3.jpg")  # 替换为您的上传按钮图片路径
upload_img = upload_img.resize((100, 50), Image.Resampling.LANCZOS)  # 调整图片大小
upload_img = ImageTk.PhotoImage(upload_img)start_detection_img = Image.open(r"图标/2.jpg")  # 替换为您的开始检测按钮图片路径
start_detection_img = start_detection_img.resize((100, 50), Image.Resampling.LANCZOS)  # 调整图片大小
start_detection_img = ImageTk.PhotoImage(start_detection_img)img_intensification_img = Image.open(r"图标/1.jpg")  # 替换为您的图像增强按钮图片路径
img_intensification_img = img_intensification_img.resize((100, 50), Image.Resampling.LANCZOS)  # 调整图片大小
img_intensification_img = ImageTk.PhotoImage(img_intensification_img)# 创建两个画布区域
canvas_left = tk.Canvas(window, width=224, height=224, bg="#e6f2ff")
canvas_right = tk.Canvas(window, width=224, height=224, bg="#e6f2ff")
# 加载图片
waiting_image = Image.open(r"图标/8.jpg")  # 替换为您的图片路径
detected_image = Image.open(r"图标/7.jpg")  # 替换为您的图片路径
waiting_image = waiting_image.resize((200, 50), Image.Resampling.LANCZOS)
detected_image = detected_image.resize((200, 50), Image.Resampling.LANCZOS)
waiting_photo = ImageTk.PhotoImage(waiting_image)
detected_photo = ImageTk.PhotoImage(detected_image)
# 将两个画布区域放置在主窗口中
canvas_left.grid(row=1, column=0, padx=10, pady=10, sticky='nsew')
canvas_right.grid(row=1, column=1, padx=10, pady=10, sticky='nsew')# 创建标签
label_waiting_image = tk.Label(window, image=waiting_photo, font=("Arial", 16), bg="#e6f2ff")
label_detected_image = tk.Label(window, image=detected_photo, font=("Arial", 16), bg="#e6f2ff")# 定位标签
label_waiting_image.grid(row=0, column=0, padx=10, pady=10, sticky='nsew')
label_detected_image.grid(row=0, column=1, padx=10, pady=10, sticky='nsew')# 设置标签的图片
label_waiting_image.config(image=waiting_photo)
label_detected_image.config(image=detected_photo)# 创建按钮并放置在主窗口上
button_upload = tk.Button(window, image=upload_img, command=upload_image, relief="flat", borderwidth=0, background='#e6f2ff', activebackground='#e6f2ff')
button_start_detection = tk.Button(window, image=start_detection_img, command=start_detection, relief="flat", borderwidth=0, background='#e6f2ff', activebackground='#e6f2ff')
img_intensification = tk.Button(window, image=img_intensification_img, command=img_inten, relief="flat", borderwidth=0, background='#e6f2ff', activebackground='#e6f2ff')# 将按钮放置在主窗口上
button_upload.place(x=155,y=495)
button_start_detection.place(x=755,y=495)
img_intensification.place(x=455,y=495)# 运行主窗口
window.mainloop()

1.导入需要用到的包

import torch.nn as nn
import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
import torch
from torchvision import transforms, models
from efficientnet_pytorch import EfficientNet
import numpy as np
import cv2

2.加载模型

这里加载了模型需要的可以联系我

class EfficientNetModel(nn.Module):def __init__(self, num_classes=10, pretrained=True):super(EfficientNetModel, self).__init__()# 加载预训练的EfficientNet模型self.efficientnet = EfficientNet.from_name('efficientnet-b3')## if pretrained:#     # 加载预训练权重#     self.efficientnet.load_state_dict(#         torch.load(r'D:\python\pytorch\Vehicle identification\save pth\efficientnet-b3-5fb5a3c3.pth'))# 获取EfficientNet模型的最后一层全连接层的输入特征数量num_ftrs = self.efficientnet._fc.in_features# 将EfficientNet模型的最后一层全连接层替换为一个新的全连接层,输出特征数量设置为num_classesself.efficientnet._fc = nn.Linear(num_ftrs, num_classes)# forward方法定义了前向传播过程def forward(self, x):return self.efficientnet(x)# Example usage
model = EfficientNetModel(num_classes=12)# 加载训练好的模型参数
model_path = 'best_EfficientNet_b3_updata1.pth'
model.load_state_dict(torch.load(model_path, map_location=torch.device('cpu')))
model.eval()

3.定义图像转换

# 定义图像转换
transform = transforms.Compose([transforms.Resize((224, 224)),  # ResNet-50 的输入图像大小transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),  # ResNet-50 的标准化
])

4.定义车类标签

classes =  ['皮卡', '敞篷车', '跑车', '掀背两箱车', '小型面包车', 'SUV', '轿车', '厢式货车', '旅行车', '公共汽车', '消防车', '出租车']

5.定义全局变量

# 初始化全局变量
selected_image_path = None
label_text = None
right_canvas_image = None

6.几个方法

def upload_image():global selected_image_path, label_textfile_path = filedialog.askopenfilename()if file_path:selected_image_path = file_pathimage = Image.open(file_path)original_width, original_height = image.size# 计算宽高比aspect_ratio = original_width / original_height# 根据画布尺寸和宽高比计算新尺寸canvas_width = 500canvas_height = 300new_width = canvas_widthnew_height = int(new_width / aspect_ratio)if new_height > canvas_height:new_height = canvas_heightnew_width = int(new_height * aspect_ratio)# 调整图片大小image = image.resize((new_width, new_height), Image.Resampling.LANCZOS)# 居中图片photo = ImageTk.PhotoImage(image)canvas_left.create_image((canvas_width - new_width) / 2, (canvas_height - new_height) / 2, 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_imageif 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()label_text.config(text=f"{label} - {max_probability:.2f}")# 显示图片在右侧画布image = Image.open(selected_image_path)  # 重新打开图片以避免被转换影响original_width, original_height = image.sizeaspect_ratio = original_width / original_heightcanvas_width = 500canvas_height = 300new_width = canvas_widthnew_height = int(new_width / aspect_ratio)if new_height > canvas_height:new_height = canvas_heightnew_width = int(new_height * aspect_ratio)image = image.resize((new_width, new_height), Image.Resampling.LANCZOS)photo = ImageTk.PhotoImage(image)# 检查是否已经创建了右侧画布的图片if right_canvas_image is None:right_canvas_image = canvas_right.create_image((canvas_width - new_width) / 2, (canvas_height - new_height) / 2, anchor='nw', image=photo)else:canvas_right.itemconfig(right_canvas_image, image=photo)canvas_right.image = photo  # Keep a reference!else:messagebox.showwarning("警告", "请先选择一张图像")# 将标签放置在图片上label_text.grid(row=1, column=1, padx=10, pady=10, sticky='n')def replaceZeroes(data):min_nonzero = min(data[np.nonzero(data)])data[data == 0] = min_nonzeroreturn datadef MSR(img, scales):weight = 1 / 3.0scales_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_uint8def img_inten():global selected_image_path, right_canvas_imageif 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((224, 224), 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()# 显示增强后的图像和检测结果在右侧画布enhanced_image = enhanced_image.resize((500, 300), Image.Resampling.LANCZOS)photo = ImageTk.PhotoImage(enhanced_image)if right_canvas_image is None:right_canvas_image = canvas_right.create_image((500 - 500) / 2, (300 - 300) / 2, anchor='nw', image=photo)else:canvas_right.itemconfig(right_canvas_image, image=photo)canvas_right.image = photo  # Keep a reference!# 更新标签文本label_text.config(text=f"{label} - {max_probability:.2f}")else:messagebox.showwarning("警告", "请先选择一张图像")

全部代码:

这里直接用是用不了的,只是给大家提供一个思路,模型可以自己训练,有需要的可以联系我,我把整个代码给你。

import torch.nn as nn
import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
import torch
from torchvision import transforms, models
from efficientnet_pytorch import EfficientNet
import numpy as np
import cv2
class EfficientNetModel(nn.Module):def __init__(self, num_classes=10, pretrained=True):super(EfficientNetModel, self).__init__()# 加载预训练的EfficientNet模型self.efficientnet = EfficientNet.from_name('efficientnet-b3')## if pretrained:#     # 加载预训练权重#     self.efficientnet.load_state_dict(#         torch.load(r'D:\python\pytorch\Vehicle identification\save pth\efficientnet-b3-5fb5a3c3.pth'))# 获取EfficientNet模型的最后一层全连接层的输入特征数量num_ftrs = self.efficientnet._fc.in_features# 将EfficientNet模型的最后一层全连接层替换为一个新的全连接层,输出特征数量设置为num_classesself.efficientnet._fc = nn.Linear(num_ftrs, num_classes)# forward方法定义了前向传播过程def forward(self, x):return self.efficientnet(x)# Example usage
model = EfficientNetModel(num_classes=12)# 加载训练好的模型参数
model_path = 'best_EfficientNet_b3_updata1.pth'
model.load_state_dict(torch.load(model_path, map_location=torch.device('cpu')))
model.eval()# 定义图像转换
transform = transforms.Compose([transforms.Resize((224, 224)),  # ResNet-50 的输入图像大小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 = Nonedef upload_image():global selected_image_path, label_textfile_path = filedialog.askopenfilename()if file_path:selected_image_path = file_pathimage = Image.open(file_path)original_width, original_height = image.size# 计算宽高比aspect_ratio = original_width / original_height# 根据画布尺寸和宽高比计算新尺寸canvas_width = 500canvas_height = 300new_width = canvas_widthnew_height = int(new_width / aspect_ratio)if new_height > canvas_height:new_height = canvas_heightnew_width = int(new_height * aspect_ratio)# 调整图片大小image = image.resize((new_width, new_height), Image.Resampling.LANCZOS)# 居中图片photo = ImageTk.PhotoImage(image)canvas_left.create_image((canvas_width - new_width) / 2, (canvas_height - new_height) / 2, 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_imageif 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()label_text.config(text=f"{label} - {max_probability:.2f}")# 显示图片在右侧画布image = Image.open(selected_image_path)  # 重新打开图片以避免被转换影响original_width, original_height = image.sizeaspect_ratio = original_width / original_heightcanvas_width = 500canvas_height = 300new_width = canvas_widthnew_height = int(new_width / aspect_ratio)if new_height > canvas_height:new_height = canvas_heightnew_width = int(new_height * aspect_ratio)image = image.resize((new_width, new_height), Image.Resampling.LANCZOS)photo = ImageTk.PhotoImage(image)# 检查是否已经创建了右侧画布的图片if right_canvas_image is None:right_canvas_image = canvas_right.create_image((canvas_width - new_width) / 2, (canvas_height - new_height) / 2, anchor='nw', image=photo)else:canvas_right.itemconfig(right_canvas_image, image=photo)canvas_right.image = photo  # Keep a reference!else:messagebox.showwarning("警告", "请先选择一张图像")# 将标签放置在图片上label_text.grid(row=1, column=1, padx=10, pady=10, sticky='n')def replaceZeroes(data):min_nonzero = min(data[np.nonzero(data)])data[data == 0] = min_nonzeroreturn datadef MSR(img, scales):weight = 1 / 3.0scales_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_uint8def img_inten():global selected_image_path, right_canvas_imageif 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((224, 224), 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()# 显示增强后的图像和检测结果在右侧画布enhanced_image = enhanced_image.resize((500, 300), Image.Resampling.LANCZOS)photo = ImageTk.PhotoImage(enhanced_image)if right_canvas_image is None:right_canvas_image = canvas_right.create_image((500 - 500) / 2, (300 - 300) / 2, anchor='nw', image=photo)else:canvas_right.itemconfig(right_canvas_image, image=photo)canvas_right.image = photo  # Keep a reference!# 更新标签文本label_text.config(text=f"{label} - {max_probability:.2f}")else:messagebox.showwarning("警告", "请先选择一张图像")# ... [剩余的代码] ...# 创建主窗口
window = tk.Tk()
window.title("图像目标检测系统")
window.geometry('1000x650')  # 设置窗口大小# 创建背景画布并使用grid布局管理器
canvas_background = tk.Canvas(window, width=1000, height=650, bg="#e6f2ff")
canvas_background.grid(row=0, column=0, columnspan=2, rowspan=4, sticky='nsew')  # 使用grid管理器# 加载背景图像
background_image = Image.open(r"图标/5.jpg")  # 替换为您的背景图像路径
background_image = background_image.resize((1000, 650), 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  # 保持对图像的引用# 加载按钮图片
upload_img = Image.open(r"图标/3.jpg")  # 替换为您的上传按钮图片路径
upload_img = upload_img.resize((100, 50), Image.Resampling.LANCZOS)  # 调整图片大小
upload_img = ImageTk.PhotoImage(upload_img)start_detection_img = Image.open(r"图标/2.jpg")  # 替换为您的开始检测按钮图片路径
start_detection_img = start_detection_img.resize((100, 50), Image.Resampling.LANCZOS)  # 调整图片大小
start_detection_img = ImageTk.PhotoImage(start_detection_img)img_intensification_img = Image.open(r"图标/1.jpg")  # 替换为您的图像增强按钮图片路径
img_intensification_img = img_intensification_img.resize((100, 50), Image.Resampling.LANCZOS)  # 调整图片大小
img_intensification_img = ImageTk.PhotoImage(img_intensification_img)# 创建两个画布区域
canvas_left = tk.Canvas(window, width=224, height=224, bg="#e6f2ff")
canvas_right = tk.Canvas(window, width=224, height=224, bg="#e6f2ff")
# 加载图片
waiting_image = Image.open(r"图标/8.jpg")  # 替换为您的图片路径
detected_image = Image.open(r"图标/7.jpg")  # 替换为您的图片路径
waiting_image = waiting_image.resize((200, 50), Image.Resampling.LANCZOS)
detected_image = detected_image.resize((200, 50), Image.Resampling.LANCZOS)
waiting_photo = ImageTk.PhotoImage(waiting_image)
detected_photo = ImageTk.PhotoImage(detected_image)
# 将两个画布区域放置在主窗口中
canvas_left.grid(row=1, column=0, padx=10, pady=10, sticky='nsew')
canvas_right.grid(row=1, column=1, padx=10, pady=10, sticky='nsew')# 创建标签
label_waiting_image = tk.Label(window, image=waiting_photo, font=("Arial", 16), bg="#e6f2ff")
label_detected_image = tk.Label(window, image=detected_photo, font=("Arial", 16), bg="#e6f2ff")# 定位标签
label_waiting_image.grid(row=0, column=0, padx=10, pady=10, sticky='nsew')
label_detected_image.grid(row=0, column=1, padx=10, pady=10, sticky='nsew')# 设置标签的图片
label_waiting_image.config(image=waiting_photo)
label_detected_image.config(image=detected_photo)# 创建按钮并放置在主窗口上
button_upload = tk.Button(window, image=upload_img, command=upload_image, relief="flat", borderwidth=0, background='#e6f2ff', activebackground='#e6f2ff')
button_start_detection = tk.Button(window, image=start_detection_img, command=start_detection, relief="flat", borderwidth=0, background='#e6f2ff', activebackground='#e6f2ff')
img_intensification = tk.Button(window, image=img_intensification_img, command=img_inten, relief="flat", borderwidth=0, background='#e6f2ff', activebackground='#e6f2ff')# 将按钮放置在主窗口上
button_upload.place(x=155,y=495)
button_start_detection.place(x=755,y=495)
img_intensification.place(x=455,y=495)# 运行主窗口
window.mainloop()

代码实现效果

图像增强效果

这里图像增强本应该导致准确率增强,可能代码实现错误,不过不太重要,只是给大家提供思路

http://www.lryc.cn/news/361261.html

相关文章:

  • 【面试题-012】什么是Spring 它有哪些优势
  • ImageButton src图片会照成内存泄露吗 会使native内存增加吗?
  • 负载均衡与容错性:集群模式在分布式系统中的应用
  • 【UE5.1 角色练习】09-物体抬升、抛出技能 - part1
  • 最大的游戏交流社区Steam服务器意外宕机 玩家服务受影响
  • 如何手动批准内核扩展 Tuxera NTFS for mac内核扩展需要批准 内核扩展怎么打开
  • ffmpeg常用命令
  • 在MongoDB中,您可以通过以下步骤来创建账号密码,并限制其在特定数据库上的访问权限
  • 前端JS必用工具【js-tool-big-box】学习,检测密码强度
  • PHP精度处理
  • 618电商大战开启!2024淘宝京东618满减规则与优惠力度大比拼
  • 【全开源】种草分享|动态朋友圈|瀑布流|uniapp
  • HDTune和CrystalDiskInfo硬盘检测S.M.A.R.T.参数当前值最差值阈值
  • Homebrew、RVM、ruby、cocoapods
  • Flutter 中的 SliverConstrainedCrossAxis 小部件:全面指南
  • Vue.js:渐进式JavaScript框架-前端开发
  • 代码随想录算法训练营Day55 | 583. 两个字符串的删除操作 72. 编辑距离 编辑距离总结篇
  • 【Python网络爬虫】详解python爬虫中正则表达式、BeautifulSoup和lxml数据解析
  • 树莓派串口无法使用(排除硬件错误后)
  • JavaEE IO流(1)
  • Prisma是什么:现代数据库工具和ORM
  • SpringBootWeb登录认证
  • vim编辑器的使用
  • 深入理解Linux网络总结
  • Python冷知识
  • Redis之内存管理过期、淘汰机制
  • 金融科技赋能跨境支付:便捷与安全并驾齐驱
  • 【康耐视国产案例】智能AI相机:深度解析DataMan 380大视野高速AI读码硬实力
  • SQL实验 带函数查询和综合查询
  • 【前端每日基础】day34——HTTP和HTTPS