(超详细流程-适合小白入门-一篇就够)基于YOLOv5和PYQT5进行检测界面的制作

 前言

主要将自己基于PYQT5和YOLOv5进行检测界面制作的全程流程做一个总结,进行分享,在看这篇文章前,请先阅读我的上一篇文章,所有详细内容在上一篇中:

(超详细流程-适合小白入门-一篇就够)基于YOLOv8和PYQT5进行检测界面的制作-CSDN博客

以下是我的项目代码:

mbl1234/YOLOv5_PYQT5_GUI: 基于YOLOv5和PYQT5的检测界面 (github.com)

想直接使用我的项目,避免YOLOv5的版本变化,可以直接使用我当时的版本进行模型训练,再将模型直接嵌入项目代码,进行测试使用就行:

mbl1234/YOLOv5_PYQT5_GUI: 基于YOLOv5和PYQT5的检测界面 (github.com)

项目介绍

以上是项目目录,除了跑GUI文件YOLOv5中需要的文件外:

test文件夹中存放:测试YOLOv5_PYQT5_GUI所需要的权重文件和图像,用的都是官方权重和图像.

ui文件夹中存放:QT Designer制作的.ui文件和转换生成的.py文件.

ui_img文件夹中存放:QT Designer制作GUI界面需要的图像文件.

Detect_GUI.py文件主要是直接进入检测界面.

Login_GUI.py文件主要是从注册和登录界面进入检测界面.

userInfo.csv文件中主要存放注册界面生成的账号.

登录

注册

检测

除了正常的登录和注册界面以外,检测界面主要能够完成以下任务:

最优模型选择,模型初始化,选择检测图像,保存结果图像,清除结果图像,退出应用

Detect_GUI.py文件

可以好好看看这段代码中的注释,对于各个功能模块所牵涉到的功能函数进行了备注.

其中在图像打开之后直接嵌入了模型调用命令行进行调用和检测.

# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui/ui/detect_ui.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.
import sys
import cv2
import argparse
import random
import torch
import numpy as np
import torch.backends.cudnn as cudnn
from models.common import DetectMultiBackend
from models.experimental import attempt_load
from utils.augmentations import letterbox
from utils.general import check_img_size, non_max_suppression, scale_coords, increment_path
from utils.torch_utils import select_device
from utils.plots import Annotator, plot_one_box2
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import ui_img.detect_rc
class Ui_MainWindow(QMainWindow):
    def __init__(self):
        super(Ui_MainWindow, self).__init__()
        self.setWindowTitle("基于YOLOv5的识别检测演示软件V1.0")
        self.resize(1600, 900)
        self.centralwidget = QWidget()
        self.centralwidget.setObjectName("centralwidget")
        # 背景图像
        self.listView = QtWidgets.QListView(self.centralwidget)
        self.listView.setGeometry(QtCore.QRect(-11, -10, 1661, 931))
        self.listView.setStyleSheet("background-image: url(:/detect/detect.JPG);")
        self.listView.setObjectName("listView")
        # 模型选择
        self.btn_selet_model = QtWidgets.QPushButton(self.centralwidget)
        self.btn_selet_model.setGeometry(QtCore.QRect(70, 810, 112, 51))
        font = QtGui.QFont()
        font.setFamily("Adobe 宋体 Std L")
        font.setPointSize(12)
        self.btn_selet_model.setFont(font)
        self.btn_selet_model.setObjectName("btn_selet_model")
        self.btn_selet_model.clicked.connect(self.seletModels)
        # 呈现原始图像
        self.label_show_yuanshi = QtWidgets.QLabel(self.centralwidget)
        self.label_show_yuanshi.setGeometry(QtCore.QRect(70, 80, 700, 700))
        self.label_show_yuanshi.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.label_show_yuanshi.setObjectName("label_show_yuanshi")
        # 模型初始化
        self.btn_init_model = QtWidgets.QPushButton(self.centralwidget)
        self.btn_init_model.setGeometry(QtCore.QRect(220, 810, 112, 51))
        font = QtGui.QFont()
        font.setFamily("Adobe 宋体 Std L")
        font.setPointSize(12)
        self.btn_init_model.setFont(font)
        self.btn_init_model.setObjectName("btn_init_model")
        self.btn_init_model.clicked.connect(self.initModels)
        # 选择图像进行检测
        self.btn_detect_img = QtWidgets.QPushButton(self.centralwidget)
        self.btn_detect_img.setGeometry(QtCore.QRect(370, 810, 112, 51))
        font = QtGui.QFont()
        font.setFamily("Adobe 宋体 Std L")
        font.setPointSize(12)
        self.btn_detect_img.setFont(font)
        self.btn_detect_img.setObjectName("btn_detect_img")
        self.btn_detect_img.clicked.connect(self.openImage)
        # 保存结果图像
        self.btn_save_img = QtWidgets.QPushButton(self.centralwidget)
        self.btn_save_img.setGeometry(QtCore.QRect(1125, 810, 112, 51))
        font = QtGui.QFont()
        font.setFamily("Adobe 宋体 Std L")
        font.setPointSize(12)
        self.btn_save_img.setFont(font)
        self.btn_save_img.setObjectName("btn_save_img")
        self.btn_save_img.clicked.connect(self.saveImage)
        # 清除结果图像
        self.btn_clear_img = QtWidgets.QPushButton(self.centralwidget)
        self.btn_clear_img.setGeometry(QtCore.QRect(1275, 810, 112, 51))
        font = QtGui.QFont()
        font.setFamily("Adobe 宋体 Std L")
        font.setPointSize(12)
        self.btn_clear_img.setFont(font)
        self.btn_clear_img.setObjectName("btn_clear_img")
        self.btn_clear_img.clicked.connect(self.clearImage)
        # 退出应用
        self.btn_exit_app = QtWidgets.QPushButton(self.centralwidget)
        self.btn_exit_app.setGeometry(QtCore.QRect(1425, 810, 112, 51))
        font = QtGui.QFont()
        font.setFamily("Adobe 宋体 Std L")
        font.setPointSize(12)
        self.btn_exit_app.setFont(font)
        self.btn_exit_app.setObjectName("btn_exit_app")
        self.btn_exit_app.clicked.connect(self.exitApp)
        # 呈现结果图像
        self.label_show_jieguo = QtWidgets.QLabel(self.centralwidget)
        self.label_show_jieguo.setGeometry(QtCore.QRect(840, 80, 700, 700))
        self.label_show_jieguo.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.label_show_jieguo.setObjectName("label_show_jieguo")
        # 标题
        self.label_show_title = QtWidgets.QLabel(self.centralwidget)
        self.label_show_title.setGeometry(QtCore.QRect(430, 20, 800, 41))
        self.label_show_title.setObjectName("label_show_title")
        # 主窗口
        self.setCentralWidget(self.centralwidget)
        self.retranslateUi(self.centralwidget)
        QtCore.QMetaObject.connectSlotsByName(self.centralwidget)
        
    # 图像检测函数    
    def detectImage(self, name_list, img):
        '''
        :param name_list: 文件名列表
        :param img: 待检测图片
        :return: info_show:检测输出的文字信息
        '''
        showimg = img
        with torch.no_grad():
            img = letterbox(img, new_shape=self.opt.imgsz)[0]
            # Convert
            img = img[:, :, ::-1].transpose(2, 0, 1)  # BGR to RGB, to 3x416x416
            img = np.ascontiguousarray(img)
            img = torch.from_numpy(img).to(self.device)
            img = img.half() if self.opt.half else img.float()  # uint8 to fp16/32
            img /= 255.0  # 0 - 255 to 0.0 - 1.0
            if len(img.shape) == 3:
                img = img[None]
            # Inference
            pred = self.model(img, augment=self.opt.augment, visualize=self.opt.visualize)
            # Apply NMS
            pred = non_max_suppression(pred, self.opt.conf_thres, self.opt.iou_thres, classes=self.opt.classes, agnostic=self.opt.agnostic_nms, max_det=self.opt.max_det)
            info_show = ""
            # Process detections
            annotator = Annotator(img, line_width=self.opt.line_thickness, example=str(self.names))
            for i, det in enumerate(pred):
                if det is not None and len(det):
                    # Rescale boxes from img_size to im0 size
                    det[:, :4] = scale_coords(img.shape[2:], det[:, :4], showimg.shape).round()
                    for *xyxy, conf, cls in reversed(det):
                        c = int(cls)
                        print(c)
                        label = None if self.opt.hide_labels else (self.names[c] if self.opt.hide_conf else f'{self.names[c]} {conf:.2f}')
                        name_list.append(self.names[int(cls)])
                        single_info = plot_one_box2(xyxy, showimg, label=label, color=self.colors[int(cls)], line_thickness=2)
                        print(single_info)
                        info_show = info_show + single_info + "\n"
    # 模型选择函数                  
    def seletModels(self):
        self.openfile_name_model, _ = QFileDialog.getOpenFileName(self.btn_selet_model, '选择weights文件', '.', '权重文件(*.pt)')
        if not self.openfile_name_model:
            QMessageBox.warning(self, "Warning:", "打开权重失败", buttons=QMessageBox.Ok,)
        else:
            print('加载weights文件地址为:' + str(self.openfile_name_model))
            QMessageBox.information(self, u"Notice", u"权重打开成功", buttons=QtWidgets.QMessageBox.Ok)
            
    # 模型初始化函数        
    def initModels(self):
        # 模型相关参数配置
        parser = argparse.ArgumentParser()
        parser.add_argument('--weights', nargs='+', type=str, default='runs/train/exp/weights/best.pt', help='model path(s)')
        parser.add_argument('--source', type=str, default='data/applenew5/images/test/', help='file/dir/URL/glob, 0 for webcam')
        parser.add_argument('--data', type=str, default='data/coco128.yaml', help='(optional) dataset.yaml path')
        parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=640, help='inference size h,w')
        parser.add_argument('--conf-thres', type=float, default=0.25, help='confidence threshold')
        parser.add_argument('--iou-thres', type=float, default=0.45, help='NMS IoU threshold')
        parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image')
        parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
        parser.add_argument('--view-img', action='store_true', help='show results')
        parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
        parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
        parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes')
        parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
        parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --classes 0, or --classes 0 2 3')
        parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
        parser.add_argument('--augment', action='store_true', help='augmented inference')
        parser.add_argument('--visualize', action='store_true', help='visualize features')
        parser.add_argument('--update', action='store_true', help='update all models')
        parser.add_argument('--project', default='runs/detect', help='save results to project/name')
        parser.add_argument('--name', default='exp', help='save results to project/name')
        parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
        parser.add_argument('--line-thickness', default=3, type=int, help='bounding box thickness (pixels)')
        parser.add_argument('--hide-labels', default=False, action='store_true', help='hide labels')
        parser.add_argument('--hide-conf', default=False, action='store_true', help='hide confidences')
        parser.add_argument('--half', action='store_true', help='use FP16 half-precision inference')
        parser.add_argument('--dnn', action='store_true', help='use OpenCV DNN for ONNX inference')
        self.opt = parser.parse_args()
        print(self.opt)
        # 默认使用opt中的设置(权重等)来对模型进行初始化
        source, weights, view_img, save_txt, imgsz, half, data, dnn, visualize, max_det = \
            self.opt.source, self.opt.weights, self.opt.view_img, self.opt.save_txt, self.opt.imgsz, self.opt.half, self.opt.data, self.opt.dnn, self.opt.visualize, self.opt.max_det
        # 若openfile_name_model不为空,则使用此权重进行初始化
        if self.openfile_name_model:
            weights = self.openfile_name_model
            print("Using button choose model")
        self.device = select_device(self.opt.device)
        cudnn.benchmark = True
        # Load model
        self.model = DetectMultiBackend(weights, device=self.device, dnn=self.opt.dnn, data=self.opt.data, fp16=half)
        stride = self.model.stride # model stride
        self.imgsz = check_img_size(imgsz, s=stride)  # check img_size
        # Get names and colors
        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"Notice", u"模型加载完成", buttons=QtWidgets.QMessageBox.Ok,
                                      defaultButton=QtWidgets.QMessageBox.Ok)
    # 图像选择函数
    def openImage(self):
        print('openImage')
        name_list = []
        fname, _ = QFileDialog.getOpenFileName(self, '打开文件', '.', '图像文件(*.jpg)')
        print(fname)
        # if not fname:
        #     QMessageBox.warning(self, u"Warning", u"打开图片失败", buttons=QMessageBox.Ok)
        # else:
        self.label_show_yuanshi.setPixmap(QPixmap(fname))
        self.label_show_yuanshi.setScaledContents(True)
        img = cv2.imread(fname)
        print(img)
        print("model initial done21")
        self.detectImage(name_list, img)
        info_show = self.detectImage(name_list, img)
        print(info_show)
        # 检测结果显示在界面
        print("model initial done23")
        self.result = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
        self.result = cv2.resize(self.result, (1000, 1000), interpolation=cv2.INTER_AREA)
        self.QtImg = QImage(self.result.data, self.result.shape[1], self.result.shape[0], QImage.Format_RGB32)
        self.qImg = self.QtImg
        self.label_show_jieguo.setPixmap(QtGui.QPixmap.fromImage(self.QtImg))
        print(self.label_show_jieguo)
        self.label_show_jieguo.setScaledContents(True)  # 设置图像自适应界面大小
        return self.qImg
        
    # 图像保存函数
    def saveImage(self):
        fd, _ = QFileDialog.getSaveFileName(self, "保存图片", ".", "*.jpg")
        self.qImg.save(fd)
        
    # 图像清除函数
    def clearImage(self, stopp):
        result = QMessageBox.question(self, "Warning:", "是否清除本次检测结果", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
        if result == QMessageBox.Yes:
            self.label_show_yuanshi.clear()
            self.label_show_jieguo.clear()
        else:
            stopp.ignore()
            
    # 应用退出函数
    def exitApp(self, event):
        event = QApplication.instance()
        result = QMessageBox.question(self, "Notice:", "您真的要退出此应用吗", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
        if result == QMessageBox.Yes:
            event.quit()
        else:
            event.ignore()
            
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.btn_selet_model.setText(_translate("MainWindow", "最优模型选择"))
        self.label_show_yuanshi.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\"><span style=\" font-size:16pt;\">原始图像</span></p></body></html>"))
        self.btn_init_model.setText(_translate("MainWindow", "模型初始化"))
        self.btn_detect_img.setText(_translate("MainWindow", "选择检测图像"))
        self.btn_save_img.setText(_translate("MainWindow", "保存结果图像"))
        self.btn_clear_img.setText(_translate("MainWindow", "清除结果图像"))
        self.btn_exit_app.setText(_translate("MainWindow", "退出应用"))
        self.label_show_jieguo.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\"><span style=\" font-size:16pt;\">结果图像</span></p></body></html>"))
        self.label_show_title.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\"><span style=\" font-size:26pt; color:#ffffff;\">基于YOLOv5的识别检测演示软件</span></p></body></html>"))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ui = Ui_MainWindow()
    ui.show()
    sys.exit(app.exec_())

Login_GUI.py

登录界面中包含登录和检测,其中还需要导入你在QT Designer中制作的的登录注册界面的.ui文件转换成的.py文件.

import sys
from datetime import datetime
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import *
from utils.id_utils import get_id_info, sava_id_info # 账号信息工具函数
from lib.share import shareInfo # 公共变量名
# 导入QT-Design生成的UI
from ui.login_ui import Ui_Form
from ui.registe_ui import Ui_Dialog
# 导入设计好的检测界面
from Detect_GUI import Ui_MainWindow
import matplotlib.backends.backend_tkagg
# 界面登录
class win_Login(QMainWindow):
    def __init__(self, parent = None):
        super(win_Login, self).__init__(parent)
        self.ui_login = Ui_Form()
        self.ui_login.setupUi(self)
        self.init_slots()
        self.hidden_pwd()
    # 密码输入框隐藏
    def hidden_pwd(self):
        self.ui_login.edit_password.setEchoMode(QLineEdit.Password)
    # 绑定信号槽
    def init_slots(self):
        self.ui_login.btn_login.clicked.connect(self.onSignIn) # 点击按钮登录
        self.ui_login.edit_password.returnPressed.connect(self.onSignIn) # 按下回车登录
        self.ui_login.btn_regeist.clicked.connect(self.create_id)
    # 跳转到注册界面
    def create_id(self):
        shareInfo.createWin = win_Register()
        shareInfo.createWin.show()
    # 保存登录日志
    def sava_login_log(self, username):
        with open('login_log.txt', 'a', encoding='utf-8') as f:
            f.write(username + '\t log in at' + datetime.now().strftimestrftime+ '\r')
    # 登录
    def onSignIn(self):
        print("You pressed sign in")
        # 从登陆界面获得输入账户名与密码
        username = self.ui_login.edit_username.text().strip()
        password = self.ui_login.edit_password.text().strip()
        print(username)
        print(password)
        # 获得账号信息
        USER_PWD = get_id_info()
        # print(USER_PWD)
        if username not in USER_PWD.keys():
            replay = QMessageBox.warning(self,"登陆失败!", "账号或密码输入错误", QMessageBox.Yes)
        else:
            # 若登陆成功,则跳转主界面
            if USER_PWD.get(username) == password:
                print("Jump to main window")
                # 所以使用公用变量名
                # shareInfo.mainWin = UI_Logic_Window()
                shareInfo.mainWin = Ui_MainWindow()
                shareInfo.mainWin.show()
                # 关闭当前窗口
                self.close()
            else:
                replay = QMessageBox.warning(self, "!", "账号或密码输入错误", QMessageBox.Yes)
# 注册界面
class win_Register(QMainWindow):
    def __init__(self, parent = None):
        super(win_Register, self).__init__(parent)
        self.ui_register = Ui_Dialog()
        self.ui_register.setupUi(self)
        self.init_slots()
    # 绑定槽信号
    def init_slots(self):
        self.ui_register.pushButton_regiser.clicked.connect(self.new_account)
        self.ui_register.pushButton_cancer.clicked.connect(self.cancel)
    # 创建新账户
    def new_account(self):
        print("Create new account")
        USER_PWD = get_id_info()
        # print(USER_PWD)
        new_username = self.ui_register.edit_username.text().strip()
        new_password = self.ui_register.edit_password.text().strip()
        # 判断用户名是否为空
        if new_username == "":
            replay = QMessageBox.warning(self, "!", "账号不准为空", QMessageBox.Yes)
        else:
            # 判断账号是否存在
            if new_username in USER_PWD.keys():
                replay = QMessageBox.warning(self, "!", "账号已存在", QMessageBox.Yes)
            else:
                # 判断密码是否为空
                if new_password == "":
                    replay = QMessageBox.warning(self, "!", "密码不能为空", QMessageBox.Yes)
                else:
                    # 注册成功
                    print("Successful!")
                    sava_id_info(new_username, new_password)
                    replay = QMessageBox.warning(self,  "!", "注册成功!", QMessageBox.Yes)
                    # 关闭界面
                    self.close()
    # 取消注册
    def cancel(self):
        self.close() # 关闭当前界面
if __name__ == "__main__":
    app = QApplication(sys.argv)
    # 利用共享变量名来实例化对象
    shareInfo.loginWin = win_Login() # 登录界面作为主界面
    shareInfo.loginWin.show()
    sys.exit(app.exec_())

### PyQt5中集成YOLO进行目标检测PyQt5应用程序中集成了YOLO目标检测功能可以创建交互式的图形用户界面(GUI),用于处理图像视频文件并实时显示检测结果。为了实现这一目的,通常会利用Python库如`opencv-python`来读取展示媒体文件,并通过调用预训练好的YOLO模型来进行对象识别。 #### 创建GUI布局 使用PyQt5设计一个简单的用户界面,该界面上有按钮可以选择要分析的图片或视频源以及启动/停止检测过程。这里提供了一个简化版的设计思路: ```python import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QLabel, QFileDialog from PyQt5.QtGui import QPixmap class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("YOLO Object Detection with PyQt5") layout = QVBoxLayout() self.label_image = QLabel() layout.addWidget(self.label_image) btn_open_file = QPushButton('Open Image or Video') btn_open_file.clicked.connect(self.open_file_dialog) layout.addWidget(btn_open_file) container = QWidget() container.setLayout(layout) self.setCentralWidget(container) def open_file_dialog(self): file_name, _ = QFileDialog.getOpenFileName( None, "Select an image or video", "", "All Files (*);;Image Files (*.png *.jpg *.jpeg *.bmp)" ) if file_name: pixmap = QPixmap(file_name).scaled(640, 480) self.label_image.setPixmap(pixmap) app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_()) ``` 这段代码构建了一个基本的应用程序框架,在其中定义了加载多媒体资源的方法[^1]。 #### 集成YOLO模型 对于YOLO部分,则需依赖于特定版本的YOLO(例如YOLOv3、YOLOv5等),并且可能还需要额外安装一些必要的包,像`torchvision`或其他支持深度学习推理引擎的工具。下面是一个假设性的函数示例,它展示了如何在一个选定的输入上应用YOLO模型执行预测操作: ```python import torch from models.experimental import attempt_load from utils.general import non_max_suppression, scale_coords from utils.datasets import letterbox import numpy as np import cv2 def detect_objects(image_path_or_video_capture, model_weights='yolov5s.pt'): device = 'cuda' if torch.cuda.is_available() else 'cpu' half = device != 'cpu' # Load YOLO Model model = attempt_load(model_weights, map_location=device) # load FP32 model if isinstance(image_path_or_video_capture, str): # 如果传入的是路径则视为静态图象 img0 = cv2.imread(image_path_or_video_capture) ... elif hasattr(image_path_or_video_capture, 'read'): # 否则是cv2.VideoCapture实例代表动态影像流 ret_val, img0 = image_path_or_video_capture.read() ... # Preprocess the input data according to what your specific version of YOLO expects. img = letterbox(img0)[0] img = img[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, to 3x416x416 img = np.ascontiguousarray(img) img = torch.from_numpy(img).to(device) img = img.half() if half else img.float() # uint8 to fp16/32 img /= 255.0 # 0 - 255 to 0.0 - 1.0 if img.ndimension() == 3: img = img.unsqueeze(0) pred = model(img, augment=False)[0] det = non_max_suppression(pred, conf_thres=0.25, iou_thres=0.45) # Process detections... for *xyxy, conf, cls in reversed(det[0]): label = f'{names[int(cls)]} {conf:.2f}' plot_one_box(xyxy, im0, label=label, color=colors(c), line_thickness=3) return annotated_img ``` 请注意上述代码片段中的某些细节可能会因所使用的具体YOLO变体而有所不同;因此建议查阅官方文档获取最准确的信息[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值