文章目录
- [1 概要](#1 概要)
- [2 NCNN](#2 NCNN)
-
- [2.1 NCNN介绍](#2.1 NCNN介绍)
- [2.1 NCNN环境搭建](#2.1 NCNN环境搭建)
- [2.2 调用交叉编译工具链部署 NCNN 框架](#2.2 调用交叉编译工具链部署 NCNN 框架)
- [2.3 进行交叉编译,获得arm框架开发板(stm32mp157)可使用的可执行程序和库等](#2.3 进行交叉编译,获得arm框架开发板(stm32mp157)可使用的可执行程序和库等)
- [2.4 将相关包传至stm32mp157上](#2.4 将相关包传至stm32mp157上)
- [3 其他章节链接](#3 其他章节链接)
1 概要
准备使用STM32MP157做目标检测项目,考虑到嵌入式设备资源有限,因此选择腾讯推出的ncnn深度学习框架来进行目标检测的实现,整个工程实现步骤大体如下:
(1) 搭建开发环境
(2) 搭建NCNN框架
(3) 实现自己的目标检测网络
(4) 实现qt可视化展示
硬件配置:
嵌入式端:STM32MP157 arm32架构
PC端:windows11 x86架构
2 NCNN
2.1 NCNN介绍
ncnn(Ncnn Convolutional Neural Network)是一个轻量级的高性能深度学习框架,由腾讯公司开发。它专门为移动设备和嵌入式设备优化,旨在提供高效的推理性能和低内存占用。
以下是ncnn的一些主要特点和优势:
轻量级和高性能:ncnn被设计为轻量级框架,具有高效的推理性能。它使用优化的计算图和内存管理策略,以最大程度地减少内存占用和计算开销。
跨平台支持:ncnn支持多种操作系统和硬件平台,包括Android、iOS、Linux、Windows等。它可以在不同的处理器架构上运行,如ARM、x86和MIPS等。
硬件加速支持:ncnn提供对多种硬件加速库的支持,包括OpenMP、Vulkan、ARM Compute Library和Metal等。这些硬件加速库可以提供更高的计算性能,同时保持较低的功耗。
灵活的模型转换工具:ncnn提供了模型转换工具,可以将主流深度学习框架(如Caffe、TensorFlow、ONNX等)的模型转换为ncnn的模型格式。这使得用户可以方便地在ncnn上部署已有的模型。
开源和活跃的社区支持:ncnn是开源的,其源代码托管在GitHub上。它拥有一个活跃的社区,用户可以在社区中获取支持、提问问题和贡献代码。
总而言之,ncnn是一个专注于移动设备和嵌入式设备的高性能深度学习框架。它的轻量级和高效性能使得它在资源受限的环境中具有很好的应用潜力,特别适用于移动应用、嵌入式设备和边缘计算等场景。
2.1 NCNN环境搭建
(1) 首先拉取 NCNN 代码:
python
git clone https://github.com/Tencent/ncnn.git
(2) 安装相关依赖:
python
sudo apt update
sudo apt install build-essential git cmake libprotobuf-dev protobuf-compiler libvulkan-dev vulkan-utils libopencv-dev
(3)编译 Vulkan 后端(可选,如果有gpu的话,如果没有,跳至(2.2)):
python
wget https://sdk.lunarg.com/sdk/download/1.2.182.0/linux/vulkansdk-linux-x86_64-1.2.182.0.tar.gz
tar xvf vulkansdk-linux-x86_64-1.2.182.0.tar.gz
export VULKAN_SDK=$(pwd)/1.2.182.0/x86_64
拉取 NCNN 子模块:
python
cd ncnn
git submodule update --init
2.2 调用交叉编译工具链部署 NCNN 框架
经过第二节交叉工具链安装后,我们可以通过交叉编译工具来编译出可以在STM32MP157上可执行的程序。
首先验证交叉编译工具链是否安装成功,终端输入命令:
bash
arm-none-linux-gnueabihf-gcc -v
若输出如下则表示安装成功:
2.3 进行交叉编译,获得arm框架开发板(stm32mp157)可使用的可执行程序和库等
在配置好 stm32mp157开发板所需的交叉编译工具链后,就可以使用cmake命令来生成编译所需的makefile文件了,为了方便,我们在后续编译的同时生成样例程序:
首先进入到你下载的ncnn文件中:
在toolchains目录下,我们可以看到很多其它开发板的编译配置文件:
参照其它开发板的配置文件,为 stm32mp157 开发板添加配置文件arm-none-linux-gnueabihf.toolchain.cmake:(因为我们的交叉编译工具名字前缀叫arm-none-linux-gnueabihf)
终端打开此页面,执行下述命令:
python
vi arm-none-linux-gnueabihf.toolchain.cmake
执行之后自动进入该文件,复制粘贴如下内容
python
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER "arm-none-linux-gnueabihf-gcc")
set(CMAKE_CXX_COMPILER "arm-none-linux-gnueabihf-g++")
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
endif()
set(CMAKE_C_FLAGS "-march=armv7-a -mfloat-abi=hard -mfpu=neon")
set(CMAKE_CXX_FLAGS "-march=armv7-a -mfloat-abi=hard -mfpu=neon")
add_definitions(-D__STDC_CONSTANT_MACROS)
# cache flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags")
执行如下命令:
python
cd .. #重新进入到ncnn目录
mkdir -p build-stm32mp157
cd build-stm32mp157
cmake -DCMAKE_BUILD_TYPE=Release -DNCNN_SIMPLEOCV=ON -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-none-linux-gnueabihf.toolchain.cmake -DNCNN_BUILD_EXAMPLES=ON ..
开始编译:
python
make -j4
查看编译结果
编译完成后,在build-stm32mp157目录下,我们可以看到benchmark目录和example目录,前者目录中的benchncnn就是 NCNN 的基准测试工具,后者目录中是编译完成的样例程序。
2.4 将相关包传至stm32mp157上
(1) 首先在stm32mp157任意目录下创建xxx/ncnn目录
把build-stm32mp157/benchmark目录下的benchncnn整个文件夹复制到开发板的/home/root/ncnn/目录下。
把ncnn/benchmark下的.param文件也放入到/home/root/ncnn/目录下。
(2) 因为stm32mp157为多核,因此需要把PC中编译得到的libgomp.so.1文件复制到开发板的/usr/lib下,这个文件是并行计算库,ncnn编译时用到了这个库,这个库在多核处理器上能够支持执行并行计算。
执行如下命令:
bash
sudo find / -name "libgomp.so.1" 2>/dev/null
输出如下:
进入到arm版本执行文件的目录中:
打包下面的链接文件:
bash
tar -czvf gcc_libs.tar.gz ./*
之后将压缩包传到开发板的/lib目录中,执行如下解压文件:
bash
tar -xzvf gcc_libs.tar.gz
(3) 最终进入到之前的ncnn目录中的benchmark运行如下指令,执行可执行程序,输出检测结果
python
./benchncnn
稍后即可看到基准测试的结果: