当前位置:   article > 正文

树莓派5 yolov8 ncnn部署记录

树莓派5 yolov8

1.前言        

        之前在rpi5 上折腾了pytorch的yolov5lite,一开始使用imx219摄像头,结果在最新的raspberry pi os 上遇到了opencv-python不兼容libcamera的问题,无法通过python的opencv调用摄像头;然后就又破费买了USB摄像头,成功在480*320分辨率下实现10fps的实时检测。然后跟着教程把模型文件转换成onnx,结果测试时帧率反而降低了,之后便不了了之。。。后来闲着没事翻看国外论坛,发现树莓派5 ncnn下的yolov8nano在640*640分辨率下最高可达20fps,这就有了这篇文章的折腾过程。最终实际测试除非调小输入尺寸,不然只有10~15fps。

这里给出原帖链接Qengineering/YoloV8-ncnn-Raspberry-Pi-4: YoloV8 for a bare Raspberry Pi 4 (github.com)

2.部署NCNN

以下全部内容都在树莓派官方系统raspberry pi os 64bit (bookworm)上部署。

  1. # 检查更新
  2. sudo apt-get update
  3. sudo apt-get upgrade
  4. # 安装依赖
  5. sudo apt-get install cmake wget
  6. sudo apt-get install build-essential gcc g++
  7. sudo apt-get install libprotobuf-dev protobuf-compiler
  8. # 下载ncnn项目文件
  9. git clone --depth=1 https://github.com/Tencent/ncnn.git
  10. cd ncnn
  11. mkdir build
  12. cd build
  13. # 编译ncnn
  14. cmake -D NCNN_DISABLE_RTTI=OFF -D NCNN_BUILD_TOOLS=ON \
  15. -D CMAKE_TOOLCHAIN_FILE=../toolchains/aarch64-linux-gnu.toolchain.cmake ..
  16. make -j4
  17. make install
  18. # 把文件移到/usr/local/目录
  19. sudo mkdir /usr/local/lib/ncnn
  20. sudo cp -r install/include/ncnn /usr/local/include/ncnn
  21. sudo cp -r install/lib/libncnn.a /usr/local/lib/ncnn/libncnn.a

3.编译OpenCV

        这一步耗时最长,花了我一个多小时,如果手上的树莓派内存不是8GB的,在进行这一步之前应先调制系统的交换空间大小(交换空间大小+可用内存需大于5.8GB),由于我的树莓派的内存是8GB的,故无需此操作。各版本opencv的编译自动化脚本见文章最上面,运行后一键编译+安装。

  1. # 把下载的opencv编译脚本放到根目录
  2. # 赋予权限
  3. sudo chmod 755 OpenCV-4-9-0.sh
  4. # 运行脚本
  5. bash OpenCV-4-9-0.sh

4.打开项目并成功运行

opencv编译成功后,再通过wget下载yolov8项目文件

wget https://github.com/Qengineering/YoloV8-ncnn-Raspberry-Pi-4/archive/refs/heads/main.zip

解压后,使用code::blocks打开.cbp格式文件,如果没安装,输入如下命令:

sudo apt-get install codeblocks

然后将debug模式改成release,点击编译后运行,成功对测试图像进行检测。

最后修改yolov8main.cpp代码,测试下视频的检测。

  1. #include "yoloV8.h"
  2. #include <opencv2/core/core.hpp>
  3. #include <opencv2/highgui/highgui.hpp>
  4. #include <opencv2/imgproc/imgproc.hpp>
  5. #include <iostream>
  6. #include <stdio.h>
  7. #include <vector>
  8. YoloV8 yolov8;
  9. int target_size = 640; //416; //320; must be divisible by 32.
  10. int main(int argc, char** argv)
  11. {
  12. const char* videopath = "/path/to/video.mp4";
  13. cv::VideoCapture cap(videopath);
  14. if (!cap.isOpened())
  15. {
  16. fprintf(stderr, "Failed to open video file\n");
  17. return -1;
  18. }
  19. yolov8.load(target_size);
  20. cv::Mat frame;
  21. std::vector<Object> objects;
  22. while (cap.read(frame))
  23. {
  24. yolov8.detect(frame, objects);
  25. yolov8.draw(frame, objects);
  26. cv::imshow("Video", frame);
  27. cv::waitKey(1);
  28. objects.clear();
  29. }
  30. cap.release();
  31. return 0;
  32. }

结果如下,target_size设置为640,输入视频大小为1280*720 30fps,输出视频目测只有5~10fps,此时cpu占用75%左右;对比pytorch下原生yolov5 cpu 100%占用而只有0.3fps,已经是巨大提升了。

接下来是摄像头实时检测

  1. #include "yoloV8.h"
  2. #include <opencv2/core/core.hpp>
  3. #include <opencv2/highgui/highgui.hpp>
  4. #include <opencv2/imgproc/imgproc.hpp>
  5. #include <iostream>
  6. #include <stdio.h>
  7. #include <vector>
  8. #include <chrono>
  9. YoloV8 yolov8;
  10. int target_size = 640; //416; //320; must be divisible by 32.
  11. int main()
  12. {
  13. // 设置摄像头分辨率
  14. int desired_width = 800;
  15. int desired_height = 600;
  16. cv::VideoCapture cap(0); // Open the default camera (index 0)
  17. if (!cap.isOpened()) // 检查摄像头是否打开
  18. {
  19. std::cerr << "Error: Failed to open camera" << std::endl;
  20. return -1;
  21. }
  22. // 摄像头分辨率
  23. cap.set(cv::CAP_PROP_FRAME_WIDTH, desired_width);
  24. cap.set(cv::CAP_PROP_FRAME_HEIGHT, desired_height);
  25. yolov8.load(target_size); // Load model (once)
  26. cv::Mat frame;
  27. double fps = 0;
  28. while (true)
  29. {
  30. auto start = std::chrono::steady_clock::now();
  31. cap >> frame;
  32. if (frame.empty())
  33. {
  34. std::cerr << "Error: Failed to capture frame" << std::endl;
  35. break;
  36. }
  37. std::vector<Object> objects;
  38. yolov8.detect(frame, objects);
  39. yolov8.draw(frame, objects);
  40. // 计算FPS
  41. auto end = std::chrono::steady_clock::now();
  42. auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
  43. fps = 1000.0 / duration;
  44. // 显示帧率
  45. cv::putText(frame, "FPS: " + std::to_string(fps), cv::Point(10, 30), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0), 2);
  46. cv::imshow("Camera", frame);
  47. if (cv::waitKey(1) == 27) // ESC退出循环
  48. break;
  49. }
  50. cap.release(); // 释放摄像头
  51. cv::destroyAllWindows(); // 关闭窗口
  52. return 0;
  53. }

测试结果

target_size为640,摄像头分辨率为1280*720时帧率为6.5。

target_size为480,摄像头分辨率为800*600时帧率为10。

不知道什么原因,并没有达到所说的20fps

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

闽ICP备14008679号