如何构建基于Yolov8Dota数据集的检测系统

如何构建基于Yolov8Dota数据集的检测系统

如何构建基于Yolov8Dota数据集的检测系统
无人机小目标检测 适用于YOLO格式的无人机小目标数据集。
2.类别:飞机、轮船、篮球场、大型车辆、小型车辆等15类。
3.数量:5297张

Dota数据集 已转化为yolo格式 可直接用yolo开始训练,有15个类别,训练15749 验证5297


如果你这孩子已经将 Dota 数据集转化为 YOLO 格式,并且有 15 个类别,训练集包含 15749 张图像,验证集包含 5297 张图像,那么我们可以直接开始使用 YOLOv8 进行训练。以下是详细的步骤和代码示例。

声明:文章内所有代码仅供参考!

项目概述

我们将使用 YOLOv8 训练一个 Dota 目标检测模型。以下是详细的步骤:

  1. 数据集准备:确保数据集格式正确。
  2. 环境部署:安装必要的库。
  3. 模型训练:使用 YOLOv8 训练模型。
  4. 指标可视化:查看训练过程中的各项指标。
  5. PyQt5 界面设计:创建一个简单的 GUI 应用来进行预测。

数据集结构

假设你的数据集已经准备好,并且是以 YOLO 格式存储的。以下是数据集的标准结构:

dataset/ ├── images/ │ ├── train/ │ │ ├── image1.jpg │ │ ├── image2.jpg │ │ └── ... │ ├── val/ │ │ ├── image3.jpg │ │ ├── image4.jpg │ │ └── ... │ └── test/ │ ├── image5.jpg │ ├── image6.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── image1.txt │ │ ├── image2.txt │ │ └── ... │ ├── val/ │ │ ├── image3.txt │ │ ├── image4.txt │ │ └── ... │ └── test/ │ ├── image5.txt │ ├── image6.txt │ └── ... └── dataset.yaml

dataset.yaml内容如下:

train:./images/trainval:./images/valnc:15names:['hero1','hero2','hero3','hero4','hero5','hero6','hero7','hero8','hero9','hero10','hero11','hero12','hero13','hero14','hero15']

每个图像对应的标签文件是一个文本文件,每行表示一个边界框,格式为:

<class_id> <x_center> <y_center> <width> <height>

环境部署说明

首先,确保你已经安装了必要的库。以下是详细的环境部署步骤:

安装依赖
# 创建虚拟环境(可选)conda create-ndota_detection_envpython=3.9conda activate dota_detection_env# 安装PyTorchpipinstalltorch==1.9torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu111# 安装其他依赖pipinstallopencv-python pyqt5 ultralytics scikit-learn pandas matplotlib seaborn

模型训练权重和指标可视化展示

我们将使用 YOLOv8 进行训练,并在训练过程中记录各种指标,如 F1 曲线、准确率、召回率、损失曲线和混淆矩阵。

训练脚本train_yolov8.py
[<title="Training YOLOv8 on Dota Detection Dataset">]fromultralyticsimportYOLOimportos# Define pathsdataset_path='path/to/dataset'weights_path='runs/train/exp/weights/best.pt'# Create dataset.yamlyaml_content=f""" train:{os.path.join(dataset_path,'images/train')}val:{os.path.join(dataset_path,'images/val')}nc: 15 names: ['hero1', 'hero2', 'hero3', 'hero4', 'hero5', 'hero6', 'hero7', 'hero8', 'hero9', 'hero10', 'hero11', 'hero12', 'hero13', 'hero14', 'hero15'] """withopen(os.path.join(dataset_path,'dataset.yaml'),'w')asf:f.write(yaml_content)# Train YOLOv8model=YOLO('yolov8n.pt')# Load a pretrained model (recommended for training)results=model.train(data=os.path.join(dataset_path,'dataset.yaml'),epochs=100,imgsz=640,save=True)# Save the best weightsbest_weights_path=Path('runs/train/exp/weights/best.pt')shutil.copy(best_weights_path,weights_path)

请将path/to/dataset替换为实际的数据集路径。

指标可视化展示

我们将编写代码来可视化训练过程中的各项指标,包括 F1 曲线、准确率、召回率、损失曲线和混淆矩阵。

可视化脚本visualize_metrics.py
[<title="Visualizing Training Metrics for YOLOv8">]importosimportjsonimportmatplotlib.pyplotaspltimportseabornassnsimportnumpyasnpfromsklearn.metricsimportconfusion_matrix,ConfusionMatrixDisplay# Load metricsresults_dir='runs/train/exp'metrics_path=os.path.join(results_dir,'results.json')withopen(metrics_path,'r')asf:results=json.load(f)# Extract metricsloss=[entry['loss']forentryinresultsif'loss'inentry]precision=[entry['metrics/precision(m)']forentryinresultsif'metrics/precision(m)'inentry]recall=[entry['metrics/recall(m)']forentryinresultsif'metrics/recall(m)'inentry]mAP_05=[entry['metrics/mAP50(m)']forentryinresultsif'metrics/mAP50(m)'inentry]# Plot loss curveplt.figure(figsize=(15,5))plt.subplot(1,3,1)plt.plot(loss,label='Loss')plt.xlabel('Epochs')plt.ylabel('Loss')plt.title('Training Loss Curve')plt.legend()# Plot precision and recall curvesplt.subplot(1,3,2)plt.plot(precision,label='Precision')plt.plot(recall,label='Recall')plt.xlabel('Epochs')plt.ylabel('Score')plt.title('Precision and Recall Curves')plt.legend()# Plot mAP@0.5 curveplt.subplot(1,3,3)plt.plot(mAP_05,label='mAP@0.5')plt.xlabel('Epochs')plt.ylabel('mAP@0.5')plt.title('mAP@0.5 Curve')plt.legend()plt.tight_layout()plt.show()# Confusion matrix# Assuming you have predictions and true labels# For demonstration, let's create some dummy datanum_classes=15true_labels=np.random.randint(0,num_classes,size=100)# Random true labelspredictions=np.random.randint(0,num_classes,size=100)# Random predicted labelscm=confusion_matrix(true_labels,predictions,labels=list(range(num_classes)))labels=[f'Hero{i+1}'foriinrange(num_classes)]disp=ConfusionMatrixDisplay(confusion_matrix=cm,display_labels=labels)disp.plot(cmap=plt.cm.Blues)plt.title('Confusion Matrix')plt.xticks(rotation=90)plt.yticks(rotation=0)plt.tight_layout()plt.show()

PyQt5设计的界面

我们将使用 PyQt5 设计一个简单的 GUI 界面来进行模型预测。

GUI代码gui_app.py
[<title="PyQt5 GUI for YOLOv8 Dota Detection">]importsysimportcv2importnumpyasnpfromPyQt5.QtWidgetsimportQApplication,QMainWindow,QLabel,QPushButton,QVBoxLayout,QWidget,QFileDialog,QMessageBox,QProgressBar,QTextEditfromPyQt5.QtGuiimportQImage,QPixmapfromPyQt5.QtCoreimportQTimerfromultralyticsimportYOLOclassMainWindow(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle("Dota Hero Detection")self.setGeometry(100,100,800,600)self.central_widget=QWidget(self)self.setCentralWidget(self.central_widget)self.layout=QVBoxLayout(self.central_widget)self.label_display=QLabel(self)self.layout.addWidget(self.label_display)self.button_layout=QHBoxLayout()self.pushButton_image=QPushButton("Open Image",self)self.pushButton_image.clicked.connect(self.open_image)self.button_layout.addWidget(self.pushButton_image)self.pushButton_folder=QPushButton("Open Folder",self)self.pushButton_folder.clicked.connect(self.open_folder)self.button_layout.addWidget(self.pushButton_folder)self.pushButton_video=QPushButton("Open Video",self)self.pushButton_video.clicked.connect(self.open_video)self.button_layout.addWidget(self.pushButton_video)self.pushButton_camera=QPushButton("Start Camera",self)self.pushButton_camera.clicked.connect(self.start_camera)self.button_layout.addWidget(self.pushButton_camera)self.pushButton_stop=QPushButton("Stop Camera",self)self.pushButton_stop.clicked.connect(self.stop_camera)self.button_layout.addWidget(self.pushButton_stop)self.layout.addLayout(self.button_layout)self.model=YOLO('runs/train/exp/weights/best.pt')self.cap=Noneself.timer=QTimer()self.timer.timeout.connect(self.process_frame)defload_image(self,file_name):img=cv2.imread(file_name)# BGRassertimgisnotNone,f'Image Not Found{file_name}'returnimgdefprocess_image(self,img):results=self.model(img,stream=True)forresultinresults:boxes=result.boxes.cpu().numpy()forboxinboxes:r=box.xyxy[0].astype(int)cls=int(box.cls[0])conf=box.conf[0]label=f'{self.model.names[cls]}{conf:.2f}'color=(0,255,0)# Greencv2.rectangle(img,r[:2],r[2:],color,2)cv2.putText(img,label,(r[0],r[1]-10),cv2.FONT_HERSHEY_SIMPLEX,0.9,color,2)rgb_image=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)h,w,ch=rgb_image.shape bytes_per_line=ch*w qt_image=QImage(rgb_image.data,w,h,bytes_per_line,QImage.Format_RGB888)pixmap=QPixmap.fromImage(qt_image)self.label_display.setPixmap(pixmap.scaled(800,600))defopen_image(self):options=QFileDialog.Options()file_name,_=QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()","","Images (*.jpeg *.jpg);;All Files (*)",options=options)iffile_name:img=self.load_image(file_name)self.process_image(img)defopen_folder(self):folder_name=QFileDialog.getExistingDirectory(self,"Select Folder")iffolder_name:forfilenameinos.listdir(folder_name):iffilename.lower().endswith(('.png','.jpg','.jpeg')):file_path=os.path.join(folder_name,filename)img=self.load_image(file_path)self.process_image(img)defopen_video(self):options=QFileDialog.Options()file_name,_=QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()","","Videos (*.mp4 *.avi);;All Files (*)",options=options)iffile_name:self.cap=cv2.VideoCapture(file_name)self.timer.start(30)# Process frame every 30 msdefstart_camera(self):self.cap=cv2.VideoCapture(0)self.timer.start(30)# Process frame every 30 msdefstop_camera(self):ifself.capisnotNone:self.cap.release()self.cap=Noneself.timer.stop()defprocess_frame(self):ifself.capisnotNone:ret,frame=self.cap.read()ifret:self.process_image(frame)else:self.cap.release()self.cap=Noneself.timer.stop()if__name__=="__main__":app=QApplication(sys.argv)window=MainWindow()window.show()sys.exit(app.exec_())

辅助工具文件utils.py

这个文件可以用来存放一些辅助函数,比如保存结果等。

[<title="Utility Functions for Dota Hero Detection">]importcv2importosdefsave_results(image,detections,output_dir,filename):fordetindetections:r=det['bbox']cls=det['class']conf=det['confidence']label=f'{cls}{conf:.2f}'color=(0,255,0)# Greencv2.rectangle(image,(int(r[0]),int(r[1])),(int(r[2]),int(r[3])),color,2)cv2.putText(image,label,(int(r[0]),int(r[1])-10),cv2.FONT_HERSHEY_SIMPLEX,0.9,color,2)output_path=os.path.join(output_dir,filename)cv2.imwrite(output_path,image)

运行效果展示

假设你已经有了运行效果的图像,可以在README.md中添加这些图像以供参考。

# Dota Hero Detection System ## Overview This project provides a deep learning-based system for detecting Dota heroes in images using thermal infrared images. The system can identify Dota heroes in images, folders, videos, and live camera feeds. ## Environment Setup - Software: PyCharm + Anaconda - Environment: Python=3.9, OpenCV-Python, PyQt5, Torch=1.9 ## Features - Detects Dota heroes. - Supports detection on images, folders, videos, and live camera feed. - Batch processing of images. - Real-time display of detected heroes with confidence scores and bounding boxes. - Saving detection results. ## Usage 1. Run the program. 2. Choose an option to detect Dota heroes in images, folders, videos, or via the camera. ## Screenshots ![Example Screenshot](data/screenshots/example_screenshot.png)

总结

构建一个完整的基于 YOLOv8 的 Dota 英雄检测系统,包括数据集准备、环境部署、模型训练、指标可视化展示和 PyQt5 界面设计。以下是所有相关的代码文件:

  1. 训练脚本(train_yolov8.py)
  2. 指标可视化脚本(visualize_metrics.py)
  3. GUI应用代码(gui_app.py)
  4. 辅助工具文件(utils.py)
  5. 文档(README.md)