基于 YOLOv8 与 VisDrone 数据集的无人机目标检测跟踪识别系统 深度学习 PySide界面设计 大数据 毕业设计✅
博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅
1、毕业设计:2025年计算机专业毕业设计选题汇总(建议收藏)✅
2、大数据毕业设计:2025年选题大全 深度学习 python语言 JAVA语言 hadoop和spark(建议收藏)✅
🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅
1、项目介绍
技术栈:
Python语言、深度学习、PyTorch、YOLOv8、PySide界面设计、VisDrone数据集、无人机目标检测
基于 YOLOv8 与 VisDrone 数据集的无人机目标检测跟踪识别系统
在安防监控、交通管理、灾害救援等领域,无人机凭借高空视角优势成为信息采集的重要工具,但如何高效处理无人机传回的图像、精准识别目标并实现跟踪,成为技术落地的关键。本项目聚焦无人机目标检测跟踪需求,以 Python 为开发核心,整合 PyTorch 深度学习框架、YOLOv8 目标检测算法、PySide 界面设计工具及 VisDrone 专业数据集,打造一套功能完善、精度优异的无人机目标检测跟踪识别系统,兼具技术创新性与实际应用价值,适用于计算机毕业设计课题。
技术架构层面,项目以 PyTorch 为底层支撑,为 YOLOv8 算法的训练与推理提供高效计算环境。YOLOv8 作为当前主流的目标检测算法,相比前代模型在检测速度与精度上均有显著提升,能快速处理无人机采集的高分辨率图像,精准识别画面中的行人、车辆、建筑等目标,满足实时检测需求。考虑到无人机图像场景复杂、目标动态变化的特点,项目引入目标跟踪机制,与 YOLOv8 算法协同工作,实现对移动目标的持续追踪,避免目标丢失导致的检测中断。
数据训练环节,项目选用 VisDrone 数据集作为模型训练基础。该数据集涵盖多种真实场景(如城市街道、乡村道路、灾害现场等),包含丰富的目标类别与标注信息,有效解决了无人机检测场景中数据稀缺、场景单一的问题,大幅提升模型的泛化能力。通过对数据集的预处理与迭代训练,模型在复杂背景、光照变化、目标遮挡等极端情况下,仍能保持较高的检测准确率,为系统稳定运行提供数据保障。
界面与功能设计上,系统采用 PySide 框架搭建可视化交互界面,界面布局简洁清晰,包含图像 / 视频导入、实时检测、跟踪结果显示、数据导出等功能模块,用户无需复杂操作即可完成目标检测任务。同时,系统支持无人机实时回传画面的接入,能同步显示检测目标的位置、类别、置信度及跟踪轨迹,方便用户直观掌握目标动态。
从应用价值来看,该系统可广泛服务于多领域:在安防监控中,可实时监测重点区域人员与车辆流动,及时预警异常情况;在交通管理中,能辅助统计车流量、识别违章车辆;在灾害救援中,可快速定位受困人员与救援目标,提升救援效率。作为毕业设计,项目不仅综合运用了深度学习、界面开发、数据处理等多学科知识,还通过实际场景落地验证了技术可行性,展现了较强的工程实践能力与创新思维。
2、项目界面
(1)无人机目标检测跟踪界面

(2)无人机目标检测跟踪界面2

(3)无人机目标检测跟踪界面3

(4)摄像头检测

3、项目说明
技术栈:
Python语言、深度学习、PyTorch、YOLOv8、PySide界面设计、VisDrone数据集、无人机目标检测
YOLOv8无人机目标检测跟踪识别系统 深度学习 PySide界面设计 大数据 毕业设计
YOLOv8无人机目标检测跟踪识别系统
本项目聚焦于无人机目标检测领域,运用前沿技术打造一套高效精准的检测跟踪识别系统。技术上,以 Python 为基础语言,借助 PyTorch 深度学习框架,采用先进的 YOLOv8 算法模型,该模型在目标检测方面具有出色的性能与准确性,能快速识别无人机图像中的各类目标。
系统采用 PySide 进行界面设计,为用户提供简洁直观、操作便捷的交互体验。数据方面,选用 VisDrone 数据集,其丰富的场景和多样的目标类别,有效保障了模型的泛化能力。通过大数据训练,模型不断优化,提升检测精度与速度。
此系统可广泛应用于安防监控、交通管理、灾害救援等场景,为相关领域提供实时、准确的目标信息。作为毕业设计项目,它不仅综合运用了深度学习、界面设计等多方面知识,还具备较高的实用价值与创新性,有望为无人机目标检测领域的发展贡献一份力量。
4、核心代码
from ultralytics import YOLO
from PySide6.QtWidgets import QApplication, QMainWindow, QFileDialog, QMenu
from PySide6.QtGui import QImage, QPixmap, QColor
from PySide6.QtCore import QTimer, QThread, Signal, QObject, QPoint, Qt
from UIFunctions import *
from ui.home import Ui_MainWindow
#from utils.capnums import Camera
from utils.rtsp_win import Window
from collections import deque
import numpy as np
import time
import json
import sys
import cv2
import os
IMG_FORMATS = ('bmp', 'dng', 'jpeg', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp', 'pfm') # image suffixes
VID_FORMATS = ('asf', 'avi', 'gif', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'ts', 'wmv', 'webm') # video suffixes
def is_video_file(path):
suffix = path.split('.')[-1].lower()
if suffix in IMG_FORMATS:
return False
elif suffix in VID_FORMATS:
return True
else:
print(f"Suffix '{suffix}' is invalid!")
raise ValueError("Invalid file suffix")
class YoloPredictor(QObject):
yolo2main_pre_img = Signal(np.ndarray) # raw image signal
yolo2main_res_img = Signal(np.ndarray) # test result signal
yolo2main_status_msg = Signal(str) # Detecting/pausing/stopping/testing complete/error reporting signal
yolo2main_fps = Signal(str) # fps
yolo2main_labels = Signal(dict) # Detected target results (number of each category)
yolo2main_progress = Signal(int) # Completeness
yolo2main_class_num = Signal(int) # Number of categories detected
yolo2main_target_num = Signal(int) # Targets detected
def __init__(self):
super().__init__()
# GUI args
self.used_model_name = None # The detection model name to use
self.source = '' # input source
self.stop_dtc = False # Termination detection
self.continue_dtc = True # pause
self.labels_dict = {} # return a dictionary of results
self.progress_value = 0 # progress bar
self.YoloConfig = dict()
self.YoloConfig['model'] = None
self.YoloConfig['iou'] = 0.70 # iou
self.YoloConfig['conf'] = 0.25 # conf
self.YoloConfig['rate'] = 30 # delay, ms
self.YoloConfig['save_res'] = False # Save test results
self.YoloConfig['save_txt'] = False # save label(txt) file
# Usable if setup is done
self.model = None
self.imgsz = None
self.device = None
self.dataset = None
self.vid_path, self.vid_writer = None, None
self.data_path = None
self.source_type = None
self.batch = None
self.fps_counter = 0
self.fps_frames = deque(maxlen=10) # 存储最近 10 帧的时间
self.fps = 0
def loadmodel(self):
if not self.model or self.used_model_name != self.YoloConfig['model']:
self.yolo2main_status_msg.emit('Loading Model...')
print('model used = ', self.YoloConfig['model'])
self.model = YOLO(self.YoloConfig['model'])
self.used_model_name = self.YoloConfig['model']
def run(self):
print("running detection ......")
# set model
self.loadmodel()
self.yolo2main_status_msg.emit('Detecting...')
print('conf threshold = ', self.YoloConfig['conf'])
print('iou threshold = ', self.YoloConfig['iou'])
print('save = ', self.YoloConfig['save_res'])
print('save_txt = ', self.YoloConfig['save_txt'])
if not is_video_file(self.source):
res = self.model.predict(self.source, save=self.YoloConfig['save_res'],
save_txt=self.YoloConfig['save_txt'], imgsz=640, conf=self.YoloConfig['conf'],
iou=self.YoloConfig['iou'], device='cpu')
preprocess_speed = res[0].speed['preprocess']
inference_speed = res[0].speed['inference']
postprocess_speed = res[0].speed['postprocess']
total_infer_speed = preprocess_speed + inference_speed + postprocess_speed
fps = 1000 / total_infer_speed
print("FPS:", fps)
detected_boxes = res[0].boxes
# print(res[0])
print("detected boxes ......")
# Create an empty list to store the class IDs
class_ids = []
# Iterate over each box and extract the class ID
for box in detected_boxes:
class_id = box.cls # get the class id
class_id_cpu = class_id.cpu() # move the value to CPU
class_id_int = int(class_id_cpu.item()) # convert to integer
class_ids.append(class_id_int) # append to the list
# Print the class ID
print("class ids = ", class_ids)
total_classes = len(set(class_ids))
total_ids = len(class_ids)
# Send test results
orig_img = res[0].orig_img
annotated_img = res[0].plot()
self.yolo2main_pre_img.emit(orig_img) # Before testing
self.yolo2main_res_img.emit(annotated_img) # after detection
# self.yolo2main_labels.emit(self.labels_dict) # webcam need to change the def write_results
self.yolo2main_class_num.emit(total_classes)
self.yolo2main_target_num.emit(total_ids)
self.yolo2main_fps.emit(str(int(fps)))
self.yolo2main_status_msg.emit('Detection completed')
else:
cap = cv2.VideoCapture(self.source)
# Loop through the video frames
count = 0 # run location frame
start_time = time.time() # used to calculate the frame rate
all_count = cap.get(cv2.CAP_PROP_FRAME_COUNT) # total frames
while cap.isOpened():
# Termination detection
if self.stop_dtc:
self.yolo2main_status_msg.emit('Detection terminated!')
self.stop_dtc = False
break
# Read a frame from the video
success, frame = cap.read()
count += 1 # frame count +1
self.progress_value = int(count / all_count * 1000) # progress bar(0~1000)
self.yolo2main_progress.emit(self.progress_value) # progress bar
if count % 5 == 0 and count >= 5: # Calculate the frame rate every 5 frames
self.yolo2main_fps.emit(str(int(5 / (time.time() - start_time))))
start_time = time.time()
# Terminate button and associated state
def stop(self):
if self.yolo_thread.isRunning():
self.yolo_thread.quit() # end thread
self.yolo_predict.stop_dtc = True
self.run_button.setChecked(False) # start key recovery
self.save_res_button.setEnabled(True) # Ability to use the save button
self.save_txt_button.setEnabled(True) # Ability to use the save button
self.pre_video.clear() # clear image display
self.res_video.clear() # clear image display
self.progress_bar.setValue(0)
self.Class_num.setText('--')
self.Target_num.setText('--')
self.fps_label.setText('--')
# Change detection parameters
def change_val(self, x, flag):
if flag == 'iou_spinbox':
self.iou_slider.setValue(int(x*100)) # The box value changes, changing the slider
elif flag == 'iou_slider':
self.iou_spinbox.setValue(x/100) # The slider value changes, changing the box
self.show_status('IOU Threshold: %s' % str(x/100))
self.yolo_predict.YoloConfig['iou'] = x/100
elif flag == 'conf_spinbox':
self.conf_slider.setValue(int(x*100))
elif flag == 'conf_slider':
self.conf_spinbox.setValue(x/100)
self.show_status('Conf Threshold: %s' % str(x/100))
self.yolo_predict.YoloConfig['conf'] = x/100
elif flag == 'speed_spinbox':
self.speed_slider.setValue(x)
elif flag == 'speed_slider':
self.speed_spinbox.setValue(x)
self.show_status('Delay: %s ms' % str(x))
self.yolo_predict.YoloConfig['speed'] = x # ms
# change model
def change_model(self,x):
self.select_model = self.model_box.currentText()
self.yolo_predict.YoloConfig['model'] = "./models/%s" % self.select_model
self.show_status('Change Model:%s' % self.select_model)
self.Model_name.setText(self.select_model)
# load model signal emission
self.main2yolo_loadmodel_sgl.emit()
# Cycle monitoring model file changes
def ModelBoxRefre(self):
pt_list = os.listdir('./models')
pt_list = [file for file in pt_list if file.endswith('.pt')]
pt_list.sort(key=lambda x: os.path.getsize('./models/' + x))
# It must be sorted before comparing, otherwise the list will be refreshed all the time
if pt_list != self.pt_list:
self.pt_list = pt_list
self.model_box.clear()
self.model_box.addItems(self.pt_list)
# Get the mouse position (used to hold down the title bar and drag the window)
def mousePressEvent(self, event):
p = event.globalPosition()
globalPos = p.toPoint()
self.dragPos = globalPos
# Optimize the adjustment when dragging the bottom and right edges of the window size
def resizeEvent(self, event):
# Update Size Grips
UIFuncitons.resize_grips(self)
# Exit Exit thread, save settings
def closeEvent(self, event):
config_file = 'config/setting.json'
config = dict()
config['iou'] = self.iou_spinbox.value()
config['conf'] = self.conf_spinbox.value()
config['rate'] = self.speed_spinbox.value()
config['save_res'] = (0 if self.save_res_button.checkState()==Qt.Unchecked else 2)
config['save_txt'] = (0 if self.save_txt_button.checkState()==Qt.Unchecked else 2)
config_json = json.dumps(config, ensure_ascii=False, indent=2)
with open(config_file, 'w', encoding='utf-8') as f:
f.write(config_json)
# Exit the process before closing
if self.yolo_thread.isRunning():
self.yolo_predict.stop_dtc = True
self.yolo_thread.quit()
MessageBox(
self.close_button, title='Note', text='Exiting, please wait...', time=3000, auto=True).exec()
sys.exit(0)
else:
sys.exit(0)
if __name__ == "__main__":
app = QApplication(sys.argv)
Home = MainWindow()
Home.show()
sys.exit(app.exec())
5、源码获取方式
🍅由于篇幅限制,获取完整文章或源码、代做项目的,查看【用户名】、【专栏名称】就可以找到我啦🍅
感兴趣的可以先收藏起来,点赞、关注不迷路,下方查看👇🏻获取联系方式👇🏻
更多推荐



所有评论(0)