opencv_dnn测试性能

1.前几章我们交叉编译opencv,移植到开发板gec6818,现在跑一下模型测试一下速度。

2.首先我们拿resnet18进行简单测试。这是开源的resnet18.onnx模型,opencv可以直接加载onnx模型,进行推理。

模型链接:resnet_18.onnx: https://url25.ctfile.com/f/34628125-651522033-53f138?p=3005 (访问密码: 3005)

3.验证的代码如下:

#include "iostream"
#include "opencv2/highgui.hpp"
#include "opencv2/dnn/dnn.hpp"
#include "opencv2/imgproc.hpp"
#include "string.h"
#include <chrono>

#define TONGJISHIJIAN 1
#define GREEN "\033[32;1m"
#define NONE "\033[0m\n"
// 加载模型
void load_model(const char* model_path, cv::dnn::Net& model){
    model = cv::dnn::readNetFromONNX(model_path);
}


int main(){
    std::string model_path = "./resnet_18.onnx";
    cv::dnn::Net model;
    load_model(model_path.c_str(), model);

    std::string img_path = "./1.jpg";
    cv::Mat image = cv::imread(img_path);
    cv::cvtColor(image, image, cv::COLOR_BGR2RGB);
    cv::dnn::blobFromImage(image,image,1.0/255,cv::Size(224,224));

    model.setInput(image);
#if TONGJISHIJIAN
    auto start_time = std::chrono::steady_clock::now();
#endif
    int count = 10;
    for(int i = 0; i < count; ++i){
        cv::Mat result = model.forward();
        cv::Point classIdPoint;
        double confidence;
        cv::minMaxLoc(result.reshape(1,1),0, &confidence, 0, &classIdPoint);
        std::cout << classIdPoint.x << std::endl;
    }

#if TONGJISHIJIAN
    auto end_time = std::chrono::steady_clock::now();
    printf(GREEN "total time: %f ms" NONE, std::chrono::duration<double>(end_time - start_time).count());
    printf(GREEN "per time: %f ms" NONE, std::chrono::duration<double>(end_time - start_time).count()/count);
#endif

    return 0;
}

复制

qt的话需要添加opencv的环境,在.pro文件下添加路径:

image-20220819233720576

在这个过程中,如果出现:libopencv*.so(opencv的动态库文件)not found,则需要给opencv的动态库文件添加环境

# 在terminal中打开
vi /etc/ld.so.conf
# 添加动态库路径如下图
/mnt/opencv_qt_4.6/lib
#保存并退出
sudo ldconfig
复制

image-20220819234001176

4.在pc端验证的结果为:

image-20220819234434173

image-20220819234434173

单次时间在0.016s

5.交叉编译opencv_dnn 在gec6818上测试一下速度,CMakeList.txt如下:

#设置CMAKE最`在这里插入代码片`低版本
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3)
#设置交叉编译的系统
SET(CMAKE_SYSTEM_NAME arm-none-linux-gnueabi)
set(compile arm-none-linux-gnueabi)
#指定c++编译器
set(CMAKE_C_COMPILER "/usr/local/arm/5.4.0/usr/bin/arm-none-linux-gnueabi-gcc")
set(CMAKE_CXX_COMPILER "/usr/local/arm/5.4.0/usr/bin/arm-none-linux-gnueabi-g++")
set(CMAKE_CXX_COMPILER_TARGET ${compile})
#设置项目名称
SET(PROJECT_NAME opencv_dnn)
#采用c++11标准
set(CMAKE_CXX_STANDARD 11)
#建立项目
PROJECT(${PROJECT_NAME})
#寻找OpenCV库
SET(OpenCV_INCLUDE_DIRS /mnt/release/include/opencv4)
SET(OpenCV_LIBS /mnt/release/lib)
INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})

MESSAGE(STATUS "Src file: ${DIR_SRCS}")
#编译可执行程序
ADD_EXECUTABLE(${PROJECT_NAME} main.cpp)
#添加链接库
TARGET_LINK_LIBRARIES(${PROJECT_NAME}
    ${OpenCV_LIBS}
    ${OpenCV_LIBS}/libopencv_core.so
    ${OpenCV_LIBS}/libopencv_imgproc.so
    ${OpenCV_LIBS}/libopencv_highgui.so
    ${OpenCV_LIBS}/libopencv_dnn.so
    ${OpenCV_LIBS}/libopencv_imgcodecs.so)
复制

之后在main.cpp、CMakeList.txt同级目录下做以下操作

# 设置环境,如果出现下面图的情况就是没有设置交叉编译链的环境,环境路径记得和你的交叉编译链一致,改为你自己电脑的路径
export LD_LIBRARY_PATH=/usr/local/arm/5.4.0/usr/lib
#进入build目录,build目录同级下是main.cpp 和 CMakeList.txt
mkdir build && cd build
cmake ..
make -j
# 没报错的话在build目录下可以看见opencv_dnn,如下图
复制

image-20220819234848694

image-20220819235224617

6.传送至开发板

scp opencv_dnn root@192.168.0.150:/mnt/sd/code/202208/opencv_dnn
复制

7.在6818上运行opencv_dnn,查看时间

[root@GEC6818 /mnt/sd/code/202208/opencv_dnn]#./opencv_dnn 
复制

image-20220819235417515

单次时间在20s,是电脑的1000倍。并且6818的cpu是满负荷运行

image-20220819235514604

opencv 添加-mfpu=vfpv3,在速度上有提升
链接:opencv_vfpv3.tar.gz: https://url25.ctfile.com/f/34628125-668497981-2c4b79?p=3005 (访问密码: 3005)

在这里插入图片描述