YOLO v5lite-s训练部署自己的数据集-基于矩池云服务器训练

一、数据集采集(视频拆分为图片)

  1. 采集方式:视频、图片、下载别人的数据集

  2. 视频采集处理

通过程序把采集到的视频按帧率重新保存为图片

import cv2
video_path = 'Z:/YOLOv5/shuju/yuanshen/date/images/text/yuanshen1.MP4'  # 视频地址
output_path = 'Z:/YOLOv5/shuju/yuanshen/date/images/train/'# 输出文件夹
interval = 10  # 每间隔10帧取一张图片

if __name__ == '__main__':
    num =1
    video = cv2.VideoCapture(video_path)
    fps = video.get(cv2.CAP_PROP_FPS)#帧率
    frames = video.get(cv2.CAP_PROP_FRAME_COUNT)#总的帧数
    print("fps=",int(fps),"frames=",int(frames))#
    while video.isOpened():
        is_read, frame = video.read()
        if is_read:
            if num % interval == 1:
                file_name = '%d' % num
                cv2.imwrite(output_path + str(file_name) + '.jpg', frame)#输出图片
                cv2.waitKey(1)
            num += 1
        else:
            break

运行报错的话,可查看是否缺失cv库,缺失的话可更加实际系统查阅资料自行导入,以上以Windows10系统为参考

什么文件夹路径如下:

 

路径为英文路径

运行后可在images里面的train文件夹里面看到数据集、如下:

此时数据集制作完成进入下一步对数据集进行标注。

二、模注(labelImg)

1.打开软件、设置标注数据集的路径、存放路径

 其中数据集来源为此文件夹:Z:\YOLOv5\shuju\yuanshen\date\images\train

存放数据集为此文件夹:Z:\YOLOv5\shuju\yuanshen\date\labels\train

 

 2.开始标注

3.完成标注

三、YOLO v5lite-s文件处理(依赖安装、训练集文件夹位置、delect.py、train.py、expor.py配置)

1.打开data文件夹下的coco.yaml文件

 根据模型标注的数据字典修改对应的标签数和类别

数据字典位于class.txt中

修改后如下:

2.打开train.py

修改以下内容:

内容具体解释请参考以下博客: 本文链接:【Yolov5】1.认真总结6000字Yolov5保姆级教程(2022.06.28全新版本v6.1)_yolov5教程-CSDN博客

 3.开始训练

注册打开矩池云

上传完善好的YOLO 文件夹置矩池云的网盘,网盘位于我的工作空间里面

租借服务器,记得与网盘区域对应如上为1区,租借预装了YOLOv5环境的服务器,此处勾选vnc采用vnc登录

 此处若有疑问可参考以下链接 

https://doc.itprojects.cn/0007.zhishi.raspberrypi/02.doc/index.html#/c01.yolo5

 打开服务器,cd到对应文件内,运行

python train.py

发现有报错,这里尝试安装依赖

pip install -r requirements.txt 

 重新运行,依然有报错

 查看models发现名称错误,改为v5Lite-s.yaml

其后发现依然报错:这里路径改为绝对路径,且字典里面有几个标签,name也是有几个,这里漏了一个A,后续把路径结构改为如下,images存放训练集图片,labels存放标签,text存放测试集。

 解决报错后也是开始训练了,初步估计训练好后识别效果可能不佳,感觉数据集太少,而且太杂乱。

四、识别效果及部署技巧

1.训练完成后可以查看best.pt和last.pt位置

2.打开delect.py

配置一下权重路径、识别数据路径等

识别完成

3.打开这个文件夹Results saved to runs/detect/exp可以看到识别效果

识别效果很打脸,原以为很差,没想到也还是可以接受的比心理预期好太多

4.转换为onnx模型更轻量化的部署-基于配置了anconda YOLO环境的Windows电脑

利用export.py进行转换,打开后修改如下几个地方,首先是待转化best.pt的路径,图片大小(与训练时一致),batch size 这里设1,支持采用cpu

运行程序后出现: ONNX export success, saved as Z:\YOLOv5-Lite-s\runs\train\exp17\weights\best.onnx

转换成功,且存储在同一文件夹下。

 部署测试代码:只有模型名称和标签字典有改动,别的保持一致。

 摄像头实时识别代码:

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:'A',
                          1:'wanye',
                          2:'leishen',
                          3:'zhongli',
                          4:'hutao'

          }
    
    # 模型参数
    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() 

运行此代码,按q退出,按s开始识别,此处识别代码和onnx.pt要位同一个文件目录下:

 

运行效果:此处部署在Windows电脑上并采用摄像头实时识别,部署在别的设备上也是类似的可以参考另一篇博客:本文链接:基于Anaconda的Windows端yolov5模型部署(onnx模型部署黑色砝码识别)-树莓派5部署步骤同样适用_yolov5使用onnx模型在pc端跑-CSDN博客

多的也不说了,原神启动去了,文章有疑问或者问题可以私聊我,联系方式qq:3470445202,如有侵权联系删。

文章源码:链接:https://pan.baidu.com/s/1seDGdxkO7S7hMa_xN7u-Pw?pwd=1234 
提取码:1234

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值