树莓派5 yolov8 ncnn部署记录

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)上部署。

# 检查更新
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

3.编译OpenCV

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

# 把下载的opencv编译脚本放到根目录
# 赋予权限
sudo chmod 755 OpenCV-4-9-0.sh
# 运行脚本
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代码,测试下视频的检测。

#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

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值