写在前面
ncnn 是 Tencent nihui 大佬推出的一个用于深度学习部署加速推理的框架,本文将介绍该框架环境的配置方法。
所需原材料
正所谓 “兵马未动,粮草先行”,在配置环境之前,先把所需的文件下载齐全,配置该环境编译的时候需要 protobuf 和 ncnn 这两个文件。
按步骤开始配置
步骤一:找到工具
第一步,打开电脑左下角的开始菜单 ,找到工具适用于 VS 2017 的 x64 本机工具命令提示 ,然后右键 使用管理员模式 打开:
步骤二:编译protobuf
① 在上面这个命令行中,使用cd 命令移动到解压出来的protobuf-3.4.0目录:
② 依次执行以下命令:
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
详细演示如下: 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 编译完毕,protobuf 会被安装在 build-vs2017/install 里。
步骤三:编译ncnn
① 在适用于 VS 2017 的 x64 本机工具命令提示 这个工具命令行中,使用cd 命令移动到解压出来的ncnn 目录,而不是在刚才的 protobuf 编译目录接着编译ncnn,否则就会报错(如下图所示): ② ncnn正确的配置路径及配置方法如下所示,依次执行以下命令:
mkdir build-vs2017
cd build-vs2017
cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%cd%/install -DProtobuf_INCLUDE_DIR=C:\software\protobuf-3.4.0/build-vs2017/install/include -DProtobuf_LIBRARIES=C:\software\protobuf-3.4.0/build-vs2017/install/lib/libprotobuf.lib -DProtobuf_PROTOC_EXECUTABLE=C:/software/protobuf-3.4.0/build-vs2017/install/bin/protoc.exe ..
nmake
nmake install
其中,cmake 命令中的三个 protobuf 路径要对应相应修改成自己的,详细演示如下: mkdir build-vs2017
cd build-vs2017
cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%cd%/install -DProtobuf_INCLUDE_DIR=C:/Users/xxxxxx/Documents/Documents_of_VS/files_of_props/ncnn/protobuf-3.4.0/build-vs2017/install/include -DProtobuf_LIBRARIES=C:/Users/xxxxxx/Documents/Documents_of_VS/files_of_props/ncnn/protobuf-3.4.0/build-vs2017/install/lib/libprotobuf.lib -DProtobuf_PROTOC_EXECUTABLE=C:/Users/xxxxxx/Documents/Documents_of_VS/files_of_props/ncnn/protobuf-3.4.0/build-vs2017/install/bin/protoc.exe .. nmake
nmake install
至此,ncnn环境已全部配置完毕,ncnn 会被安装在 build-vs2017/install 里,ncnn 转换工具在 build-vs2017/tools 里。
步骤三:在VS开发环境中配置ncnn
接下来是在VS 开发环境中配置ncnn ,即配置.props 文件。
① 包含目录(不会配置的小伙伴,可以点击参考之前的这篇文章) 实际中,为了防止出现“找不到net.h” 而报错的情况,包含目录需要进行如下配置:
② 库目录
③ 附加依赖项(链接器->输入->附加依赖项) 至此,ncnn.props 文件已配置完毕,也即ncnn 环境配置完成。
环境测试
环境配置完毕后,需要进行测试,以查看配置是否正确。 找到 ncnn/examples 里的 squeezenet.cpp ,内容如下:
#include <opencv2/opencv.hpp>
#include <map>
#include <vector>
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <net.h>
#include "opencv2/imgcodecs/legacy/constants_c.h"
static int detect_squeezenet(const cv::Mat& bgr, std::vector<float>& cls_scores)
{
ncnn::Net squeezenet;
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)
{
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> >());
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()
{
std::string imagepath = "./1.jpg";
cv::Mat m = cv::imread(imagepath, CV_LOAD_IMAGE_COLOR);
if (m.empty())
{
std::cout << "cv::imread " << imagepath << " failed\n" << std::endl;
return -1;
}
std::vector<float> cls_scores;
detect_squeezenet(m, cls_scores);
print_topk(cls_scores, 3);
return 0;
}
运行程序,如果能够输出下面的结果,则说明ncnn环境配置成功。
报错及解决方法
报错一:无法打开 net.h
出现这种情况的报错是因为,ncnn环境中包含目录未配置完整,导致外部依赖项不全,因为VS IDE的包含目录 下面所填写的include 或其他目录所包含的是配置环境所需的.h 头文件等其他文件,所以该报错的解决方法是找到项目的 属性—VC++目录—包含目录 ,将缺少的.h 头文件目录路径添加进包含目录 中即可。
上图中以 blob.h 为例,说明了项目属性中的包含目录 ,会对应显示在IDE的外部依赖项 中。
写到这里,差不多本文也就要结束了。如果我的这篇文章帮助到了你,那我也会感到很高兴,一个人能走多远,在于与谁同行。
参考文章
|