[深度学习] ncnn安装和调用基础教程
ztj100 2025-04-29 06:57 5 浏览 0 评论
1 介绍
ncnn是腾讯开发的一个为手机端极致优化的高性能神经网络前向计算框架,无第三方依赖,跨平台,但是通常都需要protobuf和opencv。ncnn目前已在腾讯多款应用中使用,如 QQ,Qzone,微信,天天P图等。ncnn主要基于C++和caffe,ncnn项目地址见:
https://github.com/Tencent/ncnn
本文主要介绍ncnn在Ubuntu 18和Windows10下安装和使用。ncnn实测win10和Ubuntu18下C++调用squeezenet进行分类越比opencv dnn模块调用squeeznet快3到5倍。
ncnn常见的主流系统平台和常见硬件平台都支持,包括树莓派。
其他平台安装教程见:
https://github.com/Tencent/ncnn/wiki/how-to-build#build-for-windows-x64-using-visual-studio-community-2017
2 Ubuntu 18下ncnn安装和使用
2.1 Ubuntu 18下ncnn编译安装
ncnn在linux平台需要protobuf和较低的gcc版本支持(根据评论区baiyu33的回复,最新ncnn版本在gcc/g++ 7.5环境,不需要降级为4.8.5,就可以编译安装protobuf 2.6.1和ncnn,2020年7月7日更新),如果你的系统可以运行caffe,可以跳过第一第二步,直接第三步。第一第二步具体安装protobuf见:
(1)将gcc、g++降级为4.8.5版本(最新版本ncnn可以跳过该阶段)。
(2)安装protobuf
(3)编译源码
先下载源码
git clone https://github.com/Tencent/ncnn
然后进入ncnn安装即可
cd ncnn
mkdir build
cd build
cmake ..
make –j12
make install
2.2 Ubuntu 18下ncnn使用
(1) 模型更新
ncnn对caffe模型支持度比其他平台模型支持度更高。所以一般都是将caffe的模型转为ncnn格式。对于比较老的caffe模型需要将其转换为最新的caffe模型(相对来说),不过一般都不需要。以alexnet为例
alexnet 的 deploy.prototxt 可以在这里下载:
https://github.com/BVLC/caffe/tree/master/models/bvlc_alexnet
alexnet 的 caffemodel 可以在这里下载 :
http://dl.caffe.berkeleyvision.org/bvlc_alexnet.caffemodel
caffe自带了工具可以把老版本的caffe 网络和模型转换为新版(ncnn的工具只认识新版),转换方法为将你需要转换的prototxt和caffemodel放在你电脑的caffe/build/tools目录下,然后终端进入caffe/build/tools,执行命令:.
./upgrade_net_proto_text old_deploy.prototxt new_deploy.prototxt
./upgrade_net_proto_binary old.caffemodel new.caffemodel
执行完成之后你就可以在caffe/build/tools下找到你的new_deploy.prototxt和new.caffemodel文件了。注意完成之后打开你的new_deploy.prototxt文件看一下,因为一般每次只需要做一个数据样本的识别,所以如果第一个 dim 不为1,要将其设为
layer {
name: "data"
type: "Input"
top: "data"
input_param { shape: { dim: 1 dim: 3 dim: 227 dim: 227 } }
}
(2)模型转换
模型转换具体使用见:
new.caffemodel文件后,需要将prototxt转换为ncnn支持的param文件,caffemodel转换为bin文件。Ncnn中使用 caffe2ncnn 工具转换为ncnn的网络描述和模型。将上面转化的new_deploy.prototxt和new.caffemodel放到ncnn/build/tools/caffe下。然后命令行输入以下命令:
./caffe2ncnn new_deploy.prototxt new.caffemodel ncnn.param ncnn.bin
或者在以下网站转换模型:
https://convertmodel.com/?tdsourcetag=s_pcqq_aiomsg
(3)运用模型分类
上面提到的是alexnet,在实际本文使用的是squeezenet。ncnn调用模型的一般过程都是参考ncnn/examples/下各个示例cpp文件,选择自己的模型,然后根据该目录下的CMakeLists.txt文件修改参数。本文就不修改参数了,直接选用squeezenet.cpp使用。
然后打开ncnn根目录下的CMakeLists.txt文件,将编译examples语句的注释打开(默认是被注释掉的),如图:
终端进入ncnn/build后执行:
make
然后把所获得ncnn参数和模型文件复制到ncnn/build/examples目录下,本文所用的squeezenet的ncnn文件在ncnn/examples中有提供。将模型.param和.bin文件复制到ncnn/build/examples目录下,然后终端cd到ncnn/build/examples,执行:
./squeezenet imagepath
Imagepath为图像路径。就可以得到结果。
具体调用代码直接参考ncnn/examples中的示例cpp文件,但是使用时最好使用examples所提到的模型。
(4)ncnn工程使用
如果想建立工程,需要自己新建一个目录然后编写你自己的cpp文件。比如使用
ncnn/examples/squeezenet.cpp,将其放入本机任意路径新的文件夹。对于ncnn编译,需要添加opencv和openmp,编写如下CMakeLists.txt进行编译,然后cmake .就可以在当前目录运行生成的可执行文件ncnnTest。
# 设置cmake版本
cmake_minimum_required(VERSION 3.2)
# ncnn工程
project(ncnnTest)
# 调用opencv
find_package(OpenCV REQUIRED)
# 调用openmp
FIND_PACKAGE( OpenMP REQUIRED)
if(OPENMP_FOUND)
message("OPENMP FOUND")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif()
# 包含ncnn的头文件
include_directories(/home/user/ncnn/build/install/include/ncnn)
# 包含ncnn的链接文件
link_directories(/home/user/ncnn/build/install/lib)
# 生成可执行文件
add_executable(ncnnTest squeezenet.cpp)
# 链接ncnn静态链接库
target_link_libraries(ncnnTest ncnn ${OpenCV_LIBS} /home/user/ncnn/build/install/lib/libncnn.a)
3 Windows 10下ncnn安装和使用
Win10下安装和ncnn最好都基于visual studio2015以上平台,本文用的vs2017。
3.1 Windows 10下ncnn编译安装
(1)protobuf编译
Win10下需要首先编译ncnn所使用到的protobuf库。Protobuf3.4.0下载路径为:
https://github.com/google/protobuf/archive/v3.4.0.zip
然后选择vs2017自带的命令提示符工具,对于命令提示符工具选择,用于后期可能会用到opencv或者其他软件包。需要确定是x86还是x64平台,本文由于用的x64平台,选择适用于vs2017的x64本机工具。如下所示:
特别要注意的在编译文件前,一定要确定命令工具所使用的是x64还是x86。
protobuf编译步骤为:
cd <protobuf-root-dir>
mkdir build-vs2017
cd build-vs2017
cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%cd%/install -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=OFF ../cmake
nmake
nmake install
上面protobuf-root-dir为你的protobuf文件路径,比如我的是
D:/packages/protobuf-3.4.0,文件路径最好纯英文,protobuf设置的release格式。
(2)ncnn编译
下载ncnn源码,
https://github.com/Tencent/ncnn 然后用上面提到的开发工具进入ncnn安装即可,具体步骤如下:
cd <ncnn-root-dir>
mkdir build-vs2017
cd build-vs2017
cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%cd%/install -DProtobuf_INCLUDE_DIR=<protobuf-root-dir>/build-vs2017/install/include -DProtobuf_LIBRARIES=<protobuf-root-dir>/build-vs2017/install/lib/libprotobuf.lib -DProtobuf_PROTOC_EXECUTABLE=<protobuf-root-dir>/build-vs2017/install/bin/protoc.exe -DNCNN_VULKAN=OFF ..
nmake
nmake install
注意<protobuf-root-dir>要替换为你的protobuf文件绝对路径,比如我的是
D:/packages/protobuf-3.4.0。DCMAKE_BUILD_TYPE=Release确定编译的是release文件。
3.2 Windows 10下ncnn使用
ncnn使用类似opencv在windows下的使用。打开vs2017建立工程文件。项目-属性-VC++目录。设置配置文件,VC++目录在包含目录下输入以下路径,调用opencv,ncnn,protobuf头文件。
d:\opencv\build\include\opencv
d:\opencv\build\include
d:\opencv\build\include\opencv2
d:\packages\ncnn\build-vs2017\install\include
d:\packages\ncnn\build-vs2017\install\include\ncnn
d:\packages\protobuf-3.4.0\build-vs2017\install\include
d:\packages\protobuf-3.4.0\build-vs2017\install\include\google
具体如图所示:
接着配置库目录,输入以下路径配置链接文件
d:\opencv\build\x64\vc15\lib
d:\packages\ncnn\build-vs2017\install\lib
d:\packages\protobuf-3.4.0\build-vs2017\install\lib
但是额外要配置配置Windows运行库目录,主要是要protobuf配置文件:
d:\packages\protobuf-3.4.0\build-vs2017\install\bin
最后链接器-输入-附加依赖项配置附加依赖项。Protobuf相关依赖项已经调用了其动态库,就不需要再调用了。
opencv_world341.lib
ncnn.lib
这样ncnn就配置好了。输入代码,直接ncnn/examples中选用一个示例调用cpp就行了。但是只能在release x64下调用ncnn,具体编译ncnn时所选择的编译模式。比如squeezenet.cpp,直接复制过来,设置param和bin文件路径就行了。其他模型依葫芦画瓢。
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
// linux平台调用
// #include "platform.h"
// #include "net.h"
// windows平台调用
#include <net.h>
#include <platform.h>
#if NCNN_VULKAN
#include "gpu.h"
#endif // NCNN_VULKAN
static int detect_squeezenet(const cv::Mat& bgr, std::vector<float>& cls_scores)
{
ncnn::Net squeezenet;
#if NCNN_VULKAN
squeezenet.opt.use_vulkan_compute = true;
#endif // NCNN_VULKAN
// squeezenet的ncnn模型文件路径
squeezenet.load_param("squeezenet_v1.1.param");
squeezenet.load_model("squeezenet_v1.1.bin");
ncnn::Mat in = ncnn::Mat::from_pixels_resize(bgr.data, ncnn::Mat::PIXEL_BGR, bgr.cols, bgr.rows, 227, 227);
const float mean_vals[3] = {104.f, 117.f, 123.f};
in.substract_mean_normalize(mean_vals, 0);
ncnn::Extractor ex = squeezenet.create_extractor();
ex.input("data", in);
ncnn::Mat out;
ex.extract("prob", out);
cls_scores.resize(out.w);
for (int j=0; j<out.w; j++)
{
cls_scores[j] = out[j];
}
return 0;
}
static int print_topk(const std::vector<float>& cls_scores, int topk)
{
// partial sort topk with index
int size = cls_scores.size();
std::vector< std::pair<float, int> > vec;
vec.resize(size);
for (int i=0; i<size; i++)
{
vec[i] = std::make_pair(cls_scores[i], i);
}
std::partial_sort(vec.begin(), vec.begin() + topk, vec.end(),
std::greater< std::pair<float, int> >());
// print topk and score
for (int i=0; i<topk; i++)
{
float score = vec[i].first;
int index = vec[i].second;
fprintf(stderr, "%d = %f\n", index, score);
}
return 0;
}
int main()
{
String imagepath = "./image/cat.jpg";
cv::Mat m = cv::imread(imagepath);
if (m.empty())
{
fprintf(stderr, "cv::imread %s failed\n", imagepath);
return -1;
}
#if NCNN_VULKAN
ncnn::create_gpu_instance();
#endif // NCNN_VULKAN
std::vector<float> cls_scores;
detect_squeezenet(m, cls_scores);
#if NCNN_VULKAN
ncnn::destroy_gpu_instance();
#endif // NCNN_VULKAN
print_topk(cls_scores, 3);
return 0;
}
4 参考
- https://github.com/Tencent/ncnn/wiki/how-to-build#build-for-linux-x86
- https://github.com/Tencent/ncnn/wiki/ncnn
- 上一篇:用rust实现经典的冒泡排序和快速排序
- 下一篇:C 语言的标准库有哪些
相关推荐
- 如何将数据仓库迁移到阿里云 AnalyticDB for PostgreSQL
-
阿里云AnalyticDBforPostgreSQL(以下简称ADBPG,即原HybridDBforPostgreSQL)为基于PostgreSQL内核的MPP架构的实时数据仓库服务,可以...
- Python数据分析:探索性分析
-
写在前面如果你忘记了前面的文章,可以看看加深印象:Python数据处理...
- C++基础语法梳理:算法丨十大排序算法(二)
-
本期是C++基础语法分享的第十六节,今天给大家来梳理一下十大排序算法后五个!归并排序...
- C 语言的标准库有哪些
-
C语言的标准库并不是一个单一的实体,而是由一系列头文件(headerfiles)组成的集合。每个头文件声明了一组相关的函数、宏、类型和常量。程序员通过在代码中使用#include<...
- [深度学习] ncnn安装和调用基础教程
-
1介绍ncnn是腾讯开发的一个为手机端极致优化的高性能神经网络前向计算框架,无第三方依赖,跨平台,但是通常都需要protobuf和opencv。ncnn目前已在腾讯多款应用中使用,如QQ,Qzon...
- 用rust实现经典的冒泡排序和快速排序
-
1.假设待排序数组如下letmutarr=[5,3,8,4,2,7,1];...
- ncnn+PPYOLOv2首次结合!全网最详细代码解读来了
-
编辑:好困LRS【新智元导读】今天给大家安利一个宝藏仓库miemiedetection,该仓库集合了PPYOLO、PPYOLOv2、PPYOLOE三个算法pytorch实现三合一,其中的PPYOL...
- C++特性使用建议
-
1.引用参数使用引用替代指针且所有不变的引用参数必须加上const。在C语言中,如果函数需要修改变量的值,参数必须为指针,如...
- Qt4/5升级到Qt6吐血经验总结V202308
-
00:直观总结增加了很多轮子,同时原有模块拆分的也更细致,估计为了方便拓展个管理。把一些过度封装的东西移除了(比如同样的功能有多个函数),保证了只有一个函数执行该功能。把一些Qt5中兼容Qt4的方法废...
- 到底什么是C++11新特性,请看下文
-
C++11是一个比较大的更新,引入了很多新特性,以下是对这些特性的详细解释,帮助您快速理解C++11的内容1.自动类型推导(auto和decltype)...
- 掌握C++11这些特性,代码简洁性、安全性和性能轻松跃升!
-
C++11(又称C++0x)是C++编程语言的一次重大更新,引入了许多新特性,显著提升了代码简洁性、安全性和性能。以下是主要特性的分类介绍及示例:一、核心语言特性1.自动类型推导(auto)编译器自...
- 经典算法——凸包算法
-
凸包算法(ConvexHull)一、概念与问题描述凸包是指在平面上给定一组点,找到包含这些点的最小面积或最小周长的凸多边形。这个多边形没有任何内凹部分,即从一个多边形内的任意一点画一条线到多边形边界...
- 一起学习c++11——c++11中的新增的容器
-
c++11新增的容器1:array当时的初衷是希望提供一个在栈上分配的,定长数组,而且可以使用stl中的模板算法。array的用法如下:#include<string>#includ...
- C++ 编程中的一些最佳实践
-
1.遵循代码简洁原则尽量避免冗余代码,通过模块化设计、清晰的命名和良好的结构,让代码更易于阅读和维护...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- node卸载 (33)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- exceptionininitializererror (33)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)