赞
踩
之前在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)
以下全部内容都在树莓派官方系统raspberry pi os 64bit (bookworm)上部署。
- # 检查更新
- sudo apt-get update
- sudo apt-get upgrade
- # 安装依赖
- sudo apt-get install cmake wget
- sudo apt-get install build-essential gcc g++
- sudo apt-get install libprotobuf-dev protobuf-compiler
- # 下载ncnn项目文件
- git clone --depth=1 https://github.com/Tencent/ncnn.git
- cd ncnn
- mkdir build
- cd build
-
- # 编译ncnn
- cmake -D NCNN_DISABLE_RTTI=OFF -D NCNN_BUILD_TOOLS=ON \
- -D CMAKE_TOOLCHAIN_FILE=../toolchains/aarch64-linux-gnu.toolchain.cmake ..
-
- make -j4
- make install
- # 把文件移到/usr/local/目录
- sudo mkdir /usr/local/lib/ncnn
- sudo cp -r install/include/ncnn /usr/local/include/ncnn
- sudo cp -r install/lib/libncnn.a /usr/local/lib/ncnn/libncnn.a

这一步耗时最长,花了我一个多小时,如果手上的树莓派内存不是8GB的,在进行这一步之前应先调制系统的交换空间大小(交换空间大小+可用内存需大于5.8GB),由于我的树莓派的内存是8GB的,故无需此操作。各版本opencv的编译自动化脚本见文章最上面,运行后一键编译+安装。
- # 把下载的opencv编译脚本放到根目录
- # 赋予权限
- sudo chmod 755 OpenCV-4-9-0.sh
- # 运行脚本
- bash OpenCV-4-9-0.sh
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代码,测试下视频的检测。
- #include "yoloV8.h"
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <opencv2/imgproc/imgproc.hpp>
- #include <iostream>
- #include <stdio.h>
- #include <vector>
-
- YoloV8 yolov8;
- int target_size = 640; //416; //320; must be divisible by 32.
-
- int main(int argc, char** argv)
- {
- const char* videopath = "/path/to/video.mp4";
-
- cv::VideoCapture cap(videopath);
- if (!cap.isOpened())
- {
- fprintf(stderr, "Failed to open video file\n");
- return -1;
- }
-
- yolov8.load(target_size);
-
- cv::Mat frame;
- std::vector<Object> objects;
-
- while (cap.read(frame))
- {
- yolov8.detect(frame, objects);
- yolov8.draw(frame, objects);
-
- cv::imshow("Video", frame);
- cv::waitKey(1);
-
- objects.clear();
- }
-
- cap.release();
-
- return 0;
- }

结果如下,target_size设置为640,输入视频大小为1280*720 30fps,输出视频目测只有5~10fps,此时cpu占用75%左右;对比pytorch下原生yolov5 cpu 100%占用而只有0.3fps,已经是巨大提升了。
接下来是摄像头实时检测
- #include "yoloV8.h"
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <opencv2/imgproc/imgproc.hpp>
- #include <iostream>
- #include <stdio.h>
- #include <vector>
- #include <chrono>
-
- YoloV8 yolov8;
- int target_size = 640; //416; //320; must be divisible by 32.
-
- int main()
- {
- // 设置摄像头分辨率
- int desired_width = 800;
- int desired_height = 600;
-
- cv::VideoCapture cap(0); // Open the default camera (index 0)
- if (!cap.isOpened()) // 检查摄像头是否打开
- {
- std::cerr << "Error: Failed to open camera" << std::endl;
- return -1;
- }
-
- // 摄像头分辨率
- cap.set(cv::CAP_PROP_FRAME_WIDTH, desired_width);
- cap.set(cv::CAP_PROP_FRAME_HEIGHT, desired_height);
-
- yolov8.load(target_size); // Load model (once)
-
- cv::Mat frame;
- double fps = 0;
- while (true)
- {
- auto start = std::chrono::steady_clock::now();
-
- cap >> frame;
- if (frame.empty())
- {
- std::cerr << "Error: Failed to capture frame" << std::endl;
- break;
- }
-
- std::vector<Object> objects;
- yolov8.detect(frame, objects);
- yolov8.draw(frame, objects);
-
- // 计算FPS
- auto end = std::chrono::steady_clock::now();
- auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
- fps = 1000.0 / duration;
-
- // 显示帧率
- cv::putText(frame, "FPS: " + std::to_string(fps), cv::Point(10, 30), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0), 2);
-
- cv::imshow("Camera", frame);
-
- if (cv::waitKey(1) == 27) // ESC退出循环
- break;
- }
-
- cap.release(); // 释放摄像头
- cv::destroyAllWindows(); // 关闭窗口
- return 0;
- }

测试结果
target_size为640,摄像头分辨率为1280*720时帧率为6.5。
target_size为480,摄像头分辨率为800*600时帧率为10。
不知道什么原因,并没有达到所说的20fps
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。