当前位置:   article > 正文

树莓派部署yolov5-lite全过程及踩坑记录_<__main__.yolov5_lite object at 0x7f1d05866460> [

<__main__.yolov5_lite object at 0x7f1d05866460> [ warn:0@0.642] global cap_v

前言:

YOLOv5-Lite模型相较于YOLOv5的优点主要体现在以下几个方面:

  1. 轻量级:YOLOv5-Lite模型通过一系列消融实验,使得模型更轻,具有更小的Flops,更低的内存占用和更少的参数。这意味着它更适合在资源受限的设备上运行,如树莓派。
  2. 速度快:YOLOv5-Lite模型在保持较高精度的同时,推理速度更快。通过加入shuffle channel,对yolov5 head进行通道裁剪等优化,使得在相同的硬件环境下,YOLOv5-Lite的推理速度可以更高。
  3. 易于部署:YOLOv5-Lite模型针对树莓派等嵌入式设备进行了优化,通过摘除Focus层和减少slice操作,使得模型更易部署,并且量化精度下降在可接受范围内。

将YOLOv5-Lite模型部署到树莓派上的优点主要包括:

  1. 实时性:由于YOLOv5-Lite模型轻量级和速度快的特点,它可以在树莓派上实现实时目标检测,适用于需要实时反馈的应用场景。
  2. 节约成本:使用树莓派等嵌入式设备部署模型可以节约服务器成本,同时降低能源消耗。
  3. 便携性:树莓派等嵌入式设备体积小巧,便于携带,可以灵活地应用于各种场景中。

总之,YOLOv5-Lite模型相较于YOLOv5更轻、更快、更易部署,将其部署到树莓派上可以实现实时目标检测,并节约成本和提供便携性。

具体过程

1.将yolov5-lite训练好的best.pt模型转化为best.onnx直接用yolov5-训练文件中的export.py转化文件即可。修改为自己的参数即可得到onnx文件

进入到树莓派开发环境中查询

 1.系统架构

2.位数:

3.Debian版本编号

根据下面链接下载相应的轮子(xxx.whl文件)

https://github.com/nknytk/built-onnxruntime-for-raspberrypi-linux

在树莓派中创建模型检测文件夹,将onnx模型和模型应用程序放在一个文件夹下

然后  pip install onnxxxxxxx.whl

安装好后,应用模型执行程序

视频检测test_video.py

  1. import cv2
  2. import numpy as np
  3. import onnxruntime as ort
  4. import time
  5. def plot_one_box(x, img, color=None, label=None, line_thickness=None):
  6. """
  7. description: Plots one bounding box on image img,
  8. this function comes from YoLov5 project.
  9. param:
  10. x: a box likes [x1,y1,x2,y2]
  11. img: a opencv image object
  12. color: color to draw rectangle, such as (0,255,0)
  13. label: str
  14. line_thickness: int
  15. return:
  16. no return
  17. """
  18. tl = (
  19. line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1
  20. ) # line/font thickness
  21. color = color or [random.randint(0, 255) for _ in range(3)]
  22. x = x.squeeze()
  23. c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
  24. cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
  25. if label:
  26. tf = max(tl - 1, 1) # font thickness
  27. t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
  28. c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
  29. cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA) # filled
  30. cv2.putText(
  31. img,
  32. label,
  33. (c1[0], c1[1] - 2),
  34. 0,
  35. tl / 3,
  36. [225, 255, 255],
  37. thickness=tf,
  38. lineType=cv2.LINE_AA,
  39. )
  40. def _make_grid( nx, ny):
  41. xv, yv = np.meshgrid(np.arange(ny), np.arange(nx))
  42. return np.stack((xv, yv), 2).reshape((-1, 2)).astype(np.float32)
  43. def cal_outputs(outs,nl,na,model_w,model_h,anchor_grid,stride):
  44. row_ind = 0
  45. grid = [np.zeros(1)] * nl
  46. for i in range(nl):
  47. h, w = int(model_w/ stride[i]), int(model_h / stride[i])
  48. length = int(na * h * w)
  49. if grid[i].shape[2:4] != (h, w):
  50. grid[i] = _make_grid(w, h)
  51. outs[row_ind:row_ind + length, 0:2] = (outs[row_ind:row_ind + length, 0:2] * 2. - 0.5 + np.tile(
  52. grid[i], (na, 1))) * int(stride[i])
  53. outs[row_ind:row_ind + length, 2:4] = (outs[row_ind:row_ind + length, 2:4] * 2) ** 2 * np.repeat(
  54. anchor_grid[i], h * w, axis=0)
  55. row_ind += length
  56. return outs
  57. def post_process_opencv(outputs,model_h,model_w,img_h,img_w,thred_nms,thred_cond):
  58. conf = outputs[:,4].tolist()
  59. c_x = outputs[:,0]/model_w*img_w
  60. c_y = outputs[:,1]/model_h*img_h
  61. w = outputs[:,2]/model_w*img_w
  62. h = outputs[:,3]/model_h*img_h
  63. p_cls = outputs[:,5:]
  64. if len(p_cls.shape)==1:
  65. p_cls = np.expand_dims(p_cls,1)
  66. cls_id = np.argmax(p_cls,axis=1)
  67. p_x1 = np.expand_dims(c_x-w/2,-1)
  68. p_y1 = np.expand_dims(c_y-h/2,-1)
  69. p_x2 = np.expand_dims(c_x+w/2,-1)
  70. p_y2 = np.expand_dims(c_y+h/2,-1)
  71. areas = np.concatenate((p_x1,p_y1,p_x2,p_y2),axis=-1)
  72. areas = areas.tolist()
  73. ids = cv2.dnn.NMSBoxes(areas,conf,thred_cond,thred_nms)
  74. if len(ids)>0:
  75. return np.array(areas)[ids],np.array(conf)[ids],cls_id[ids]
  76. else:
  77. return [],[],[]
  78. def infer_img(img0,net,model_h,model_w,nl,na,stride,anchor_grid,thred_nms=0.4,thred_cond=0.5):
  79. # 图像预处理
  80. img = cv2.resize(img0, [model_w,model_h], interpolation=cv2.INTER_AREA)
  81. img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
  82. img = img.astype(np.float32) / 255.0
  83. blob = np.expand_dims(np.transpose(img, (2, 0, 1)), axis=0)
  84. # 模型推理
  85. outs = net.run(None, {net.get_inputs()[0].name: blob})[0].squeeze(axis=0)
  86. # 输出坐标矫正
  87. outs = cal_outputs(outs,nl,na,model_w,model_h,anchor_grid,stride)
  88. # 检测框计算
  89. img_h,img_w,_ = np.shape(img0)
  90. boxes,confs,ids = post_process_opencv(outs,model_h,model_w,img_h,img_w,thred_nms,thred_cond)
  91. return boxes,confs,ids
  92. if __name__ == "__main__":
  93. # 模型加载
  94. model_pb_path = "best.onnx"
  95. so = ort.SessionOptions()
  96. net = ort.InferenceSession(model_pb_path, so)
  97. # 标签字典
  98. dic_labels= {0:'fall',
  99. 1:'fight'}
  100. # 模型参数
  101. model_h = 320
  102. model_w = 320
  103. nl = 3
  104. na = 3
  105. stride=[8.,16.,32.]
  106. anchors = [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]]
  107. anchor_grid = np.asarray(anchors, dtype=np.float32).reshape(nl, -1, 2)
  108. video = 0
  109. cap = cv2.VideoCapture(video)
  110. flag_det = False
  111. while True:
  112. success, img0 = cap.read()
  113. if success:
  114. if flag_det:
  115. t1 = time.time()
  116. 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)
  117. t2 = time.time()
  118. for box,score,id in zip(det_boxes,scores,ids):
  119. label = '%s:%.2f'%(dic_labels[id.item()],score)
  120. plot_one_box(box.astype(np.int16), img0, color=(255,0,0), label=label, line_thickness=None)
  121. str_FPS = "FPS: %.2f"%(1./(t2-t1))
  122. cv2.putText(img0,str_FPS,(50,50),cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),3)
  123. cv2.imshow("video",img0)
  124. key=cv2.waitKey(1) & 0xFF
  125. if key == ord('q'):
  126. break
  127. elif key & 0xFF == ord('s'):
  128. flag_det = not flag_det
  129. print(flag_det)
  130. cap.release()

图片检测 test_one_img.py

  1. import cv2
  2. import numpy as np
  3. import onnxruntime as ort
  4. import math
  5. import time
  6. def plot_one_box(x, img, color=None, label=None, line_thickness=None):
  7. """
  8. description: Plots one bounding box on image img,
  9. this function comes from YoLov5 project.
  10. param:
  11. x: a box likes [x1,y1,x2,y2]
  12. img: a opencv image object
  13. color: color to draw rectangle, such as (0,255,0)
  14. label: str
  15. line_thickness: int
  16. return:
  17. no return
  18. """
  19. tl = (
  20. line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1
  21. ) # line/font thickness
  22. color = color or [random.randint(0, 255) for _ in range(3)]
  23. x = x.squeeze()
  24. c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
  25. cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
  26. if label:
  27. tf = max(tl - 1, 1) # font thickness
  28. t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
  29. c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
  30. cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA) # filled
  31. cv2.putText(
  32. img,
  33. label,
  34. (c1[0], c1[1] - 2),
  35. 0,
  36. tl / 3,
  37. [225, 255, 255],
  38. thickness=tf,
  39. lineType=cv2.LINE_AA,
  40. )
  41. def _make_grid( nx, ny):
  42. xv, yv = np.meshgrid(np.arange(ny), np.arange(nx))
  43. return np.stack((xv, yv), 2).reshape((-1, 2)).astype(np.float32)
  44. def cal_outputs(outs,nl,na,model_w,model_h,anchor_grid,stride):
  45. row_ind = 0
  46. grid = [np.zeros(1)] * nl
  47. for i in range(nl):
  48. h, w = int(model_w/ stride[i]), int(model_h / stride[i])
  49. length = int(na * h * w)
  50. if grid[i].shape[2:4] != (h, w):
  51. grid[i] = _make_grid(w, h)
  52. outs[row_ind:row_ind + length, 0:2] = (outs[row_ind:row_ind + length, 0:2] * 2. - 0.5 + np.tile(
  53. grid[i], (na, 1))) * int(stride[i])
  54. outs[row_ind:row_ind + length, 2:4] = (outs[row_ind:row_ind + length, 2:4] * 2) ** 2 * np.repeat(
  55. anchor_grid[i], h * w, axis=0)
  56. row_ind += length
  57. return outs
  58. def post_process_opencv(outputs,model_h,model_w,img_h,img_w,thred_nms,thred_cond):
  59. conf = outputs[:,4].tolist()
  60. c_x = outputs[:,0]/model_w*img_w
  61. c_y = outputs[:,1]/model_h*img_h
  62. w = outputs[:,2]/model_w*img_w
  63. h = outputs[:,3]/model_h*img_h
  64. p_cls = outputs[:,5:]
  65. if len(p_cls.shape)==1:
  66. p_cls = np.expand_dims(p_cls,1)
  67. cls_id = np.argmax(p_cls,axis=1)
  68. p_x1 = np.expand_dims(c_x-w/2,-1)
  69. p_y1 = np.expand_dims(c_y-h/2,-1)
  70. p_x2 = np.expand_dims(c_x+w/2,-1)
  71. p_y2 = np.expand_dims(c_y+h/2,-1)
  72. areas = np.concatenate((p_x1,p_y1,p_x2,p_y2),axis=-1)
  73. areas = areas.tolist()
  74. ids = cv2.dnn.NMSBoxes(areas,conf,thred_cond,thred_nms)
  75. return np.array(areas)[ids],np.array(conf)[ids],cls_id[ids]
  76. def infer_img(img0,net,model_h,model_w,nl,na,stride,anchor_grid,thred_nms=0.4,thred_cond=0.5):
  77. # 图像预处理
  78. img = cv2.resize(img0, [model_w,model_h], interpolation=cv2.INTER_AREA)
  79. img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
  80. img = img.astype(np.float32) / 255.0
  81. blob = np.expand_dims(np.transpose(img, (2, 0, 1)), axis=0)
  82. # 模型推理
  83. outs = net.run(None, {net.get_inputs()[0].name: blob})[0].squeeze(axis=0)
  84. # 输出坐标矫正
  85. outs = cal_outputs(outs,nl,na,model_w,model_h,anchor_grid,stride)
  86. # 检测框计算
  87. img_h,img_w,_ = np.shape(img0)
  88. boxes,confs,ids = post_process_opencv(outs,model_h,model_w,img_h,img_w,thred_nms,thred_cond)
  89. return boxes,confs,ids
  90. if __name__ == "__main__":
  91. # 模型加载
  92. model_pb_path = "best_lite_led.onnx"
  93. so = ort.SessionOptions()
  94. net = ort.InferenceSession(model_pb_path, so)
  95. # 标签字典
  96. dic_labels= {0:'led',
  97. 1:'buzzer',
  98. 2:'teeth'}
  99. # 模型参数
  100. model_h = 320
  101. model_w = 320
  102. nl = 3
  103. na = 3
  104. stride=[8.,16.,32.]
  105. anchors = [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]]
  106. anchor_grid = np.asarray(anchors, dtype=np.float32).reshape(nl, -1, 2)
  107. # 进行推理
  108. img0 = cv2.imread('3.jpg')
  109. t1 = time.time()
  110. 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)
  111. t2 = time.time()
  112. print("%.2f"%(t2-t1))
  113. # 结果绘图
  114. for box,score,id in zip(det_boxes,scores,ids):
  115. label = '%s:%.2f'%(dic_labels[id.item()],score)
  116. plot_one_box(box.astype(np.int), img0, color=(255,0,0), label=label, line_thickness=None)
  117. cv2.imshow('img',img0)
  118. cv2.waitKey(0)

运行test_video.py程序,按下s键开始实时检测

成功运行,帧数在4左右。ps:如果你发现摄像头很模糊,记得手动调焦距,转动摄像头的旋钮即可。



遇到问题

1.onnxruntime安装

首先是转换onnx模型。之后在树莓派上进行部署时发生了问题

于是查找资料,查询自己树莓派的

1.系统架构

2.位数:

3.Debian版本编号

根据下面链接下载相应的轮子

https://github.com/nknytk/built-onnxruntime-for-raspberrypi-linux

根据上面只能大概知道要下载轮子,但是具体型号我是最后试出来的.

我尝试了好几个

2.关于树莓派中python版本切换的问题

一般树莓派中会有两个python版本,我的树莓派是一个python2.7,一个python3.7,一开始默认的是python2.7,需要改为3.7再去安装onnxruntime,因为安装onnxruntime需要pytho3.xx以上版本

通过whereis python命令可以看到,我的树莓派中还有python3,.7的版本,

其实系统中是都安装了python2.7和python3.7版本的,我们只需要切换一下python版本即可

先将python的链接删了

Sudo rm /usr/bin/python

将python3软链接接上去

Sudo ln -s /usr/bin/python3.7 /usr/bin/python

这样就可以了,成功切换了python版本.

3.检测程序遇到问题

1.运行test_video.py程序出错

修改后如下图,在红色框中的id后面加了 .item()

2.另外的报错

修改后如下图,多加了一段程序  x = x.squeeze()  在c1,c2前面。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/140358?site
推荐阅读
相关标签
  

闽ICP备14008679号