YOLOV5的训练与部署

本文简述使用自己电脑本地训练YOLOV5模型,并部署在树莓派上

机端环境部署

一、python环境搭建

        先检查自己电脑是否有python以及它的版本

        win+R打开运行窗口输入CMD

        

        然后在命令符里输入python

可以看到我的版本是3.10的,如果没有的可以去官网下载https://www.python.org/

接下来是创建虚拟环境(可以使用anaconda这里就不在描述)

输入python -m venv yolov5  (yolov5是虚拟环境名字)

然后激活环境yolov5\Scripts\activate

最后这样即为成功创建虚拟环境

安装CUDA与cuDNN库

下载CUDA

下载前需要确认自己的版本驱动

 输入nvidia-smi查看CUDA版本号和驱动版本,我这里是12.2,驱动版本是537

下面是CUDA 工具包和 CUDA 次要版本兼容性所需的最低驱动程序版本

具体可前往官网查看https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#id5

我这里选择12.1的下载链接https://developer.nvidia.com/cuda-toolkit-archive

建议选择自定义安装

然后一直下一步即可

下载cuDNN

下载与CUDA版本对应的cuDNN版本可去文档查看https://developer.nvidia.com/rdp/cudnn-archive

我这里选择v8.9.7的

下载完成后,需要把cuDNN文件中的三个文件夹bin、include和lib复制到CUDA的安装目录

安装PyTorch

我选择的版本是2.5.1的,尽量版本不要太高,会出现兼容问题https://pytorch.org/get-started/previous-versions/

接下来验证安装

输入python后

import torch
torch.__version__

出现我这样及安装成功

下载YOLOV5

去官网下载https://github.com/ultralytics/yolov5我的是yolov5-7.0的

下载后解压在一个文件夹并在同级目录下创建data文件夹

在data里面创建train和valid两个文件夹

接着分别在这两个文件夹中创建images和labels两个文件夹

在images文件夹放入需要标注的照片(train:valid=9:1)

下载labelimg标注工具

进入下载地址:https://github.com/tzutalin/labelImg/releases,选择windows_v1.8.1.zip,下载并解压,直接双击exe文件即可打开。

勾选自动保存

点击verify Image下面这个,使它变成YOLO

然后打开文件夹

 

保存路径为

这些是快捷键

!!!注意valid下的图片也需要标注

训练前准备

复制coco128.yaml文件,粘贴并改名为mydata.yaml

然后打开mydata.yaml,修改

path:是你的data路径

train:是你的训练集照片路径

val:是你的验证集路径

names:是你在labelimg中标注的标签名称

打开在yolov5-master下的train.py文件

修改后,我这里照片尺寸选定320z

在打开detect.py文件,修改照片尺寸

修改后

在models文件夹中,打开yolov5s.yaml(打开什么的.yaml)取决于你上面修改的两个文件中的--weights,将nc:后的数字改为你标注的种类数量

打开requirements.txt文件,将Export下的注释去掉

在命令行中进入yolov5-master目录

安装依赖

pip install -r requirements.txt 

要是你报出这样的错误

经过我的实测,该错误对后面并没有影响,所以无需在意

开始训练

安装完依赖后,就可以使用python train.py开始训练

出现以下错误,使用pip install pyyaml

出现以下错误,使用pip install tqdm

出现以下错误,使用pip install pandas

出现以下错误,使用pip install requests

出现以下错误,使用pip install numpy==1.20

如果觉得这里太慢,可以ctrl+鼠标左键进入游览器下载

然后就可以开始训练了,出现的警告不用管,那是因为PyTorch版本过高导致的

训练完后他会告诉你模型放在哪个文件

导出模型

进入export.pt文件

修改--imgsz,修改的要与你之前训练前的大小一致

然后输入命令python export.py --weights runs\train\exp5\weights\best.pt --include onnx

看见该提示及成功转换

板端环境部署

我所使用的树莓派4B安装的是ubuntu20的,如果是树莓派官方镜像内容大致不差

安装虚拟环境

1.安装 Python 3 和 venv 模块

sudo apt install python3 python3-venv python3-pip

2.创建虚拟环境

python3 -m venv yolov5

3.激活虚拟环境

source yolov5/bin/activate

安装依赖

1.安装opencv

pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple

2.安装pytorch

pip install torch==2.0.0 torchvision==0.15.0 -i https://mirrors.aliyun.com/pypi/simple/

3.安装onnx

pip install onnx -i https://pypi.tuna.tsinghua.edu.cn/simple

4.安装onnxruntime 

pip install onnxruntime -i https://pypi.tuna.tsinghua.edu.cn/simple

开始识别

1.建立文件夹存放onnx文件

mkdir YOLOV5_jx

2.将onnx文件复制到YOLOV5_jx中

可以借助vscode的远程连接,以及其他工具,这里不再过多描述

3.编写程序

在bast.onnx同一级目录下创建.py文件

touch run_YOLOV5.py

编写程序sudo nano run_YOLOV5.py

import cv2
import numpy as np
import onnxruntime as ort
import time
 
def plot_one_box(x, img, color=None, label=None, line_thickness=None):
    """
    description: Plots one bounding box on image img,
                 this function comes from YoLov5 project.
    param: 
        x:      a box likes [x1,y1,x2,y2]
        img:    a opencv image object
        color:  color to draw rectangle, such as (0,255,0)
        label:  str
        line_thickness: int
    return:
        no return
    """
    tl = (
        line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1
    )  # line/font thickness
    color = color or [random.randint(0, 255) for _ in range(3)]
    c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
    cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if label:
        tf = max(tl - 1, 1)  # font thickness
        t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
        c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
        cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)  # filled
        cv2.putText(
            img,
            label,
            (c1[0], c1[1] - 2),
            0,
            tl / 3,
            [225, 255, 255],
            thickness=tf,
            lineType=cv2.LINE_AA,
        )
 
def _make_grid( nx, ny):
        xv, yv = np.meshgrid(np.arange(ny), np.arange(nx))
        return np.stack((xv, yv), 2).reshape((-1, 2)).astype(np.float32)
 
def cal_outputs(outs,nl,na,model_w,model_h,anchor_grid,stride):
    
    row_ind = 0
    grid = [np.zeros(1)] * nl
    for i in range(nl):
        h, w = int(model_w/ stride[i]), int(model_h / stride[i])
        length = int(na * h * w)
        if grid[i].shape[2:4] != (h, w):
            grid[i] = _make_grid(w, h)
 
        outs[row_ind:row_ind + length, 0:2] = (outs[row_ind:row_ind + length, 0:2] * 2. - 0.5 + np.tile(
            grid[i], (na, 1))) * int(stride[i])
        outs[row_ind:row_ind + length, 2:4] = (outs[row_ind:row_ind + length, 2:4] * 2) ** 2 * np.repeat(
            anchor_grid[i], h * w, axis=0)
        row_ind += length
    return outs
 
 
 
def post_process_opencv(outputs,model_h,model_w,img_h,img_w,thred_nms,thred_cond):
    conf = outputs[:,4].tolist()
    c_x = outputs[:,0]/model_w*img_w
    c_y = outputs[:,1]/model_h*img_h
    w  = outputs[:,2]/model_w*img_w
    h  = outputs[:,3]/model_h*img_h
    p_cls = outputs[:,5:]
    if len(p_cls.shape)==1:
        p_cls = np.expand_dims(p_cls,1)
    cls_id = np.argmax(p_cls,axis=1)
 
    p_x1 = np.expand_dims(c_x-w/2,-1)
    p_y1 = np.expand_dims(c_y-h/2,-1)
    p_x2 = np.expand_dims(c_x+w/2,-1)
    p_y2 = np.expand_dims(c_y+h/2,-1)
    areas = np.concatenate((p_x1,p_y1,p_x2,p_y2),axis=-1)
    
    areas = areas.tolist()
    ids = cv2.dnn.NMSBoxes(areas,conf,thred_cond,thred_nms)
    if len(ids)>0:
        return  np.array(areas)[ids],np.array(conf)[ids],cls_id[ids]
    else:
        return [],[],[]
def infer_img(img0,net,model_h,model_w,nl,na,stride,anchor_grid,thred_nms=0.4,thred_cond=0.5):
    # 图像预处理
    img = cv2.resize(img0, [model_w,model_h], interpolation=cv2.INTER_AREA)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = img.astype(np.float32) / 255.0
    blob = np.expand_dims(np.transpose(img, (2, 0, 1)), axis=0)
 
    # 模型推理
    outs = net.run(None, {net.get_inputs()[0].name: blob})[0].squeeze(axis=0)
 
    # 输出坐标矫正
    outs = cal_outputs(outs,nl,na,model_w,model_h,anchor_grid,stride)
 
    # 检测框计算
    img_h,img_w,_ = np.shape(img0)
    boxes,confs,ids = post_process_opencv(outs,model_h,model_w,img_h,img_w,thred_nms,thred_cond)
 
    return  boxes,confs,ids
 
 
 
 
if __name__ == "__main__":
 
    # 模型加载
    model_pb_path = "best.onnx" #这里为自己训练出模型的名字
    so = ort.SessionOptions()
    net = ort.InferenceSession(model_pb_path, so)
    
    # 标签字典 (以下为标注时的种类)
    dic_labels= {0:'laji'}
    
    # 模型参数 (导出模型时的尺寸)
    model_h = 320
    model_w = 320
    nl = 3
    na = 3
    stride=[8.,16.,32.]
    anchors = [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]]
    anchor_grid = np.asarray(anchors, dtype=np.float32).reshape(nl, -1, 2)
    
    video = 0
    cap = cv2.VideoCapture(video)
    flag_det = False
    while True:
        success, img0 = cap.read()
        if success:
            
            if flag_det:
                t1 = time.time()
                det_boxes,scores,ids = infer_img(img0,net,model_h,model_w,nl,na,stride,anchor_grid,thred_nms=0.4,thred_cond=0.5)
                t2 = time.time()
            
                
                for box,score,id in zip(det_boxes,scores,ids):
                    label = '%s:%.2f'%(dic_labels[id],score)
            
                    plot_one_box(box.astype(np.int16), img0, color=(255,0,0), label=label, line_thickness=None)
                    
                str_FPS = "FPS: %.2f"%(1./(t2-t1))
                
                cv2.putText(img0,str_FPS,(50,50),cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),3)
                
            
            cv2.imshow("video",img0)
        key=cv2.waitKey(1) & 0xFF    
        if key == ord('q'):
        
            break
        elif key & 0xFF == ord('s'):
            flag_det = not flag_det
            print(flag_det)
            
    cap.release() 

4.运行代码

python3 run_YOLOV5.py

按下s开始识别

按下q结束

### 安装和配置YOLOv5 #### 准备工作 为了在树莓派上成功安装并运行YOLOv5,首先需要确保操作系统是最新的,并且已经安装了一些必要的依赖库。可以通过执行以下命令来更新系统软件包列表以及升级已有的软件包: ```bash sudo apt-get update && sudo apt-get upgrade -y ``` 接着,还需要安装一系列用于支持YOLOv5所需的开发库[^4]。 #### 安装Miniconda 考虑到Python环境管理和依赖项处理的重要性,推荐先安装Miniconda作为Python环境管理工具。这有助于创建独立的虚拟环境来进行YOLOv5项目的开发测试[^2]。 - 下载适合ARM架构的Miniconda版本; - 使用`sh Miniconda*.sh`指令完成安装过程; - 初始化Conda以便可以在终端中直接调用conda命令。 #### 创建专用环境 通过Conda创建一个新的虚拟环境专门用于YOLOv5项目,可以有效避免不同项目之间的冲突问题。具体操作如下所示: ```bash conda create --name yolov5 python=3.9 conda activate yolov5 ``` #### 安装PyTorch及相关组件 由于YOLOv5基于PyTorch框架构建而成,因此接下来要在这个新环境中安装合适的PyTorch版本以及其他必需的支持库。对于树莓派而言,官方提供的预编译二进制文件可能并不适用,所以通常会选择从源码编译或者寻找社区维护好的轮子(wheel)文件进行安装[^3]。 #### 获取YOLOv5仓库 克隆GitHub上的YOLOv5官方存储库到本地计算机之后,进入对应的目录下按照README.md中的指导进一步设置模型参数和其他选项。 ```bash git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt ``` 当看到提示信息类似于“Successfully installed”,则表明所需的所有Python模块都已经正确加载完毕[^1]。 #### 测试验证 最后一步是对整个流程做一个简单的检验——尝试运行一次推理任务来看看是否一切正常运作。如果遇到任何异常情况,则应该仔细查阅日志记录找出潜在的问题所在;必要时还可以向专业人士求助以获得更专业的技术支持。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值