博主介绍:✌全网粉丝50W+,前互联网大厂软件研发、集结硕博英豪成立软件开发工作室,专注于计算机相关专业项目实战6年之久,累计开发项目作品上万套。凭借丰富的经验与专业实力,已帮助成千上万的学生顺利毕业,选择我们,就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅

点击查看作者主页,了解更多项目!

🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅

1、毕业设计:2025年计算机专业毕业设计选题汇总(建议收藏)✅

2、最全计算机专业毕业设计选题大全(建议收藏)✅

1、项目介绍

技术栈:
python语言、YoloV8模型、PySide6界面、opencv、训练集测试集

2、项目界面

(1)多目标检测识别
在这里插入图片描述

(2)多目标检测识别

在这里插入图片描述

(3)多目标检测识别在这里插入图片描述

(4)多目标检测识别

在这里插入图片描述

(5)多目标检测识别
在这里插入图片描述

3、项目说明

基于YOLOv8模型的海洋生物目标检测系统可用于日常生活中检测海洋生物目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测识别,另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv8目标检测模型训练数据集,使用Pysdie6库来搭建页面展示系统,同时支持ONNX、PT等模型作为权重模型的输出。本系统支持的功能包括训练模型的导入、初始化;置信分与IOU阈值的调节、图像上传、检测、可视化结果展示、结果导出与结束检测;视频的上传、检测、可视化结果展示、结果导出与结束检测;摄像头的上传、检测、可视化结果展示与结束检测;已检测目标列表、位置信息;前向推理用时等功能

4、核心代码

import argparse
import random
import sys
import torch
import numpy as np
from PySide6 import QtWidgets
from PySide6.QtWidgets import QMainWindow, QApplication, QFileDialog
# 显示图片
from PySide6 import QtGui, QtCore
from PySide6.QtGui import QPixmap, QImage
from PySide6.QtCore import QTimer, Qt
from main_window import Ui_MainWindow
from threading import Thread
from plot_mask import draw_detections

import argparse
import os
import sys
import shutil
from pathlib import Path

import cv2
import torch.backends.cudnn as cudnn
FILE = Path(__file__).resolve()
ROOT = FILE.parents[0]
if str(ROOT) not in sys.path:
    sys.path.append(str(ROOT))  # add ROOT to PATH
# ROOTS = Path(os.path.relpath(ROOT, Path.cwd()))  # relative
import camera_rc

# 已有功能:
# 权重加载,权重初始化
# 图像导入,图像检测,图像结果展示,图像导出,图像检测退出
# 视频导入,视频检测,视频结果展示,视频导出,视频检测退出
# 摄像头导入,摄像头检测,摄像头结果展示,摄像头导出,摄像头检测退出
# 检测时间,检测目标数,检测目标类别,检测目标位置信息

def convert2QImage(img):
    height, width, channel = img.shape
    return QImage(img, width, height, width * channel, QImage.Format_RGB888)


def letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32):
    # Resize and pad image while meeting stride-multiple constraints
    shape = im.shape[:2]  # current shape [height, width]
    if isinstance(new_shape, int):
        new_shape = (new_shape, new_shape)

    # Scale ratio (new / old)
    r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
    if not scaleup:  # only scale down, do not scale up (for better val mAP)
        r = min(r, 1.0)

    # Compute padding
    ratio = r, r  # width, height ratios
    new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
    dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh padding
    if auto:  # minimum rectangle
        dw, dh = np.mod(dw, stride), np.mod(dh, stride)  # wh padding
    elif scaleFill:  # stretch
        dw, dh = 0.0, 0.0
        new_unpad = (new_shape[1], new_shape[0])
        ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]  # width, height ratios

    dw /= 2  # divide padding into 2 sides
    dh /= 2

    if shape[::-1] != new_unpad:  # resize
        im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)
    top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
    left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
    im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add border
    return im, ratio, (dw, dh)


class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)
        self.input_width = self.input.width()
        self.input_height = self.input.height()
        # self.output_width = self.output.width()
        # self.output_height = self.output.height()
        self.imgsz = 640
        self.timer = QTimer()
        self.timer.setInterval(1)
        self.timer_c = QTimer(self)
        self.timer_c.timeout.connect(self.detect_camera)
        self.video = None
        self.out = None
        # 若是cpu检测,将cuda:0替换成cpu
        self.device = "cuda:0"
        self.num_stop = 1
        self.numcon = self.con_slider.value() / 100.0
        self.numiou = self.iou_slider.value() / 100.0
        self.results = []
        self.camera = None
        self.running = False
        self.bind_slots()
        self.init_icons()

    def open_image(self):
        self.timer.stop()
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        self.file_path, _ = QFileDialog.getOpenFileName(self, "Select File", "./", "Images (*.png *.xpm *.jpg *.jpeg *.bmp)", options=options)
        if self.file_path:
            dialog = QFileDialog(self, "Open File", self.file_path)
            dialog.resize(800, 600)
            dialog.close()
            pixmap = QPixmap(self.file_path)
            scaled_pixmap = pixmap.scaled(640, 480, aspectMode=Qt.KeepAspectRatio)
            # scaled_pixmap = pixmap.scaledToWidth(self.input.width())
            # scaled_pixmap = pixmap.scaled(self.input.size(), aspectMode=Qt.KeepAspectRatio)
            self.input.setPixmap(QPixmap(self.file_path))
            self.lineEdit.setText('图片打开成功!!!')

    def open_video(self):
        self.timer.stop()
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        self.video_path, _ = QFileDialog.getOpenFileName(self, "Select vidos", dir='./', filter="Videos (*.mp4 *.avi *.gif *.MPEG)", options=options)
        if self.video_path:
            dialog = QFileDialog(self, "Open File", self.video_path)
            dialog.resize(800, 600)
            dialog.close()
            self.video_path = self.video_path
            self.video = cv2.VideoCapture(self.video_path)

            # 读取一帧用于展示
            ret, frame = self.video.read()
            if ret:
                self.lineEdit.setText("成功打开视频!!!")
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                dst_size = (self.input_width, self.input_height)
                resized_frame = cv2.resize(frame, dst_size, interpolation=cv2.INTER_AREA)
                self.input.setPixmap(QPixmap(convert2QImage(resized_frame)))
            else:
                self.lineEdit.setText("视频有误,请重新打开!!!")
            self.out = cv2.VideoWriter('prediction.mp4', cv2.VideoWriter_fourcc(
                    *'mp4v'), 30, (int(self.video.get(3)), int(self.video.get(4))))

    def load_model(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        self.openfile_name_model, _ = QFileDialog.getOpenFileName(self.button_weight_select, '选择权重文件',
                                                                  'weights/', "Weights (*.pt *.onnx *.engine)", options=options)
        if not self.openfile_name_model:
            QtWidgets.QMessageBox.warning(self, u"Warning", u"权重打开失败", buttons=QtWidgets.QMessageBox.Ok,
                                          defaultButton=QtWidgets.QMessageBox.Ok)
        else:
            dialog = QFileDialog(self, "Open File", self.openfile_name_model)
            dialog.resize(800, 600)
            dialog.close()
            result_str = '成功加载模型权重, 权重地址: ' + str(self.openfile_name_model)
            self.lineEdit.setText(result_str)

    def init_model(self):
        from ultralytics import YOLO

        self.weights_path = str(self.openfile_name_model)
        # 8.0.124
        self.model = YOLO(self.weights_path)
        self.names = self.model.names
        self.colors = [[random.randint(0, 255)
                        for _ in range(3)] for _ in self.names]
        print("model initial done")

        QtWidgets.QMessageBox.information(self, u"!", u"模型初始化成功", buttons=QtWidgets.QMessageBox.Ok,
                                          defaultButton=QtWidgets.QMessageBox.Ok)
        self.lineEdit.setText("成功初始化模型!!!")

    def detect_begin(self):
        # name_list = []
        self.img = cv2.imread(self.file_path)
        self.pred = self.model.predict(source=self.img, iou=self.numiou, conf=self.numcon)  # save plotted images
        preprocess_speed = self.pred[0].speed['preprocess']
        inference_speed = self.pred[0].speed['inference']
        postprocess_speed = self.pred[0].speed['postprocess']
        self.lineEdit_detect_time.setText(str(round((preprocess_speed + inference_speed + postprocess_speed) / 1000, 3)))
        self.lineEdit_detect_object_nums.setText(str(self.pred[0].boxes.conf.shape[0]))

        self.results = self.pred[0].boxes.xyxy.tolist()

        if self.pred[0].boxes.conf.shape[0]:
            for i in range(self.pred[0].boxes.conf.shape[0]):
                self.comboBox.addItem('目标' + str(i + 1))
        
        QtWidgets.QMessageBox.information(self, u"!", u"成功检测图像", buttons=QtWidgets.QMessageBox.Ok,
                                      defaultButton=QtWidgets.QMessageBox.Ok)
    
        self.lineEdit.setText("成功检测图像!!!") 

    def convert2QImage(img):
        height, width, channel = img.shape
        return QImage(img, width, height, width * channel, QImage.Format_RGB888)

    def detect_show(self):
        conf_list = self.pred[0].boxes.conf.tolist()
        cls_list_int = [int(i) for i in self.pred[0].boxes.cls.tolist()]
        xyxy_list_int = [[round(num) for num in sublist] for sublist in self.pred[0].boxes.xyxy.tolist()]

        self.combined_image = draw_detections(self.img, xyxy_list_int, conf_list, cls_list_int, 0.4)

        self.result = cv2.cvtColor(self.combined_image, cv2.COLOR_BGR2BGRA)
        self.QtImg = QtGui.QImage(
            self.result.data, self.result.shape[1], self.result.shape[0], QtGui.QImage.Format_RGB32)
        
        self.input.setPixmap(QtGui.QPixmap.fromImage(self.QtImg))
        self.input.setScaledContents(True)  # 自适应界面大小

        self.lineEdit.setText('图片检测成功!!!')

        cv2.imwrite('prediction.jpg', self.combined_image)
        
    # 视频检测
    def detect_video(self):
        self.timer.start()
        ret, frame = self.video.read()
        if not ret:
            self.timer.stop()
            self.video.release()
            self.out.release()
        else:
            name_list = []   

            self.comboBox.clear()

            # 检测每一帧
            self.pred = self.model.predict(source=frame, iou=self.numiou, conf=self.numcon)  # save plotted images
            preprocess_speed = self.pred[0].speed['preprocess']
            inference_speed = self.pred[0].speed['inference']
            postprocess_speed = self.pred[0].speed['postprocess']
            self.lineEdit_detect_time.setText(str(round((preprocess_speed + inference_speed + postprocess_speed) / 1000, 2)))
            self.lineEdit_detect_object_nums.setText(str(self.pred[0].boxes.conf.shape[0]))

            self.results = self.pred[0].boxes.xyxy.tolist()

            if self.pred[0].boxes.conf.shape[0]:
                for i in range(self.pred[0].boxes.conf.shape[0]):
                    self.comboBox.addItem('目标' + str(i + 1))

            # 画图
            conf_list = self.pred[0].boxes.conf.tolist()
            cls_list_int = [int(i) for i in self.pred[0].boxes.cls.tolist()]
            xyxy_list_int = [[round(num) for num in sublist] for sublist in self.pred[0].boxes.xyxy.tolist()]

            self.combined_image = draw_detections(frame, xyxy_list_int, conf_list, cls_list_int, 0.4)

            # 写视频
            self.out.write(self.combined_image)

            self.result_frame = cv2.cvtColor(self.combined_image, cv2.COLOR_BGR2BGRA)
            self.QtImg = QtGui.QImage(
                self.result_frame.data, self.result_frame.shape[1], self.result_frame.shape[0], QtGui.QImage.Format_RGB32)
            
            self.input.setPixmap(QtGui.QPixmap.fromImage(self.QtImg))
            self.input.setScaledContents(True)  # 自适应界面大小
            self.lineEdit.setText('正在检测视频!!!')

    def suspend_video(self):
        self.timer.blockSignals(False)
        if self.timer.isActive() == True and self.num_stop % 2 == 1:
            self.button_video_suspend.setText(u'继续视频检测')  # 当前状态为暂停状态
            self.num_stop = self.num_stop + 1  # 调整标记信号为偶数
            self.timer.blockSignals(True)
        else:
            self.num_stop = self.num_stop + 1
            self.button_video_suspend.setText(u'暂停视频检测')



🍅✌感兴趣的可以先收藏起来,点赞关注不迷路,想学习更多项目可以查看主页,大家在毕设选题,项目编程以及论文编写等相关问题都可以给我留言咨询,希望可以帮助同学们顺利毕业!🍅✌

5、源码获取方式

🍅由于篇幅限制,获取完整文章或源码、代做项目的,拉到文章底部即可看到个人联系方式。🍅

点赞、收藏、关注,不迷路,下方查看👇🏻获取联系方式👇🏻

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐