Index 目录索引

  • 写在前面
  • 所需原材料
  • 按步骤开始配置
  • 步骤一:找到工具
  • 步骤二:编译protobuf
  • 步骤三:编译ncnn
  • 步骤三:在VS开发环境中配置ncnn
  • 环境测试
  • 报错及解决方法
  • 报错一:无法打开 net.h
  • 参考文章



写在前面

ncnn是 Tencent nihui 大佬推出的一个用于深度学习部署加速推理的框架,本文将介绍该框架环境的配置方法1

所需原材料

正所谓 “兵马未动,粮草先行”,在配置环境之前,先把所需的文件下载齐全,配置该环境编译的时候需要 protobuf ncnn 这两个文件。

NCC 应用架构_人工智能

按步骤开始配置

步骤一:找到工具

第一步,打开电脑左下角的开始菜单,找到工具适用于 VS 2017 的 x64 本机工具命令提示,然后右键使用管理员模式打开:

NCC 应用架构_环境配置_02

步骤二:编译protobuf

① 在上面这个命令行中,使用cd命令移动到解压出来的protobuf-3.4.0目录:

NCC 应用架构_环境配置_03

② 依次执行以下命令:

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

NCC 应用架构_NCC 应用架构_04


nmake

NCC 应用架构_#include_05

NCC 应用架构_NCC 应用架构_06


nmake install

NCC 应用架构_人工智能_07


至此,protobuf 编译完毕,protobuf 会被安装在 build-vs2017/install 里。


步骤三:编译ncnn

① 在适用于 VS 2017 的 x64 本机工具命令提示这个工具命令行中,使用cd命令移动到解压出来的ncnn目录,而不是在刚才的 protobuf 编译目录接着编译ncnn,否则就会报错(如下图所示):

NCC 应用架构_#include_08


② 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 ..

NCC 应用架构_#include_09


NCC 应用架构_NCC 应用架构_10


nmake

NCC 应用架构_环境配置_11


NCC 应用架构_人工智能_12

nmake install

NCC 应用架构_深度学习_13


NCC 应用架构_#include_14


至此,ncnn环境已全部配置完毕,ncnn 会被安装在 build-vs2017/install 里,ncnn 转换工具在 build-vs2017/tools 里。


步骤三:在VS开发环境中配置ncnn

接下来是在VS开发环境中配置ncnn,即配置.props文件。

① 包含目录(不会配置的小伙伴,可以点击参考之前的这篇文章

NCC 应用架构_人工智能_15


实际中,为了防止出现“找不到net.h”而报错的情况,包含目录需要进行如下配置:

NCC 应用架构_人工智能_16


NCC 应用架构_环境配置_17

② 库目录

NCC 应用架构_深度学习_18

③ 附加依赖项(链接器->输入->附加依赖项)

NCC 应用架构_#include_19


至此,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");   // ncnn加速所需的转换后的模型文件之一
	squeezenet.load_model("./squeezenet_v1.1.bin");     // ncnn加速所需的转换后的模型文件之二

	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()
{
	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环境配置成功。

NCC 应用架构_#include_20

报错及解决方法

报错一:无法打开 net.h

出现这种情况的报错是因为,ncnn环境中包含目录未配置完整,导致外部依赖项不全,因为VS IDE的包含目录下面所填写的include或其他目录所包含的是配置环境所需的.h头文件等其他文件,所以该报错的解决方法是找到项目的 属性—VC++目录—包含目录,将缺少的.h头文件目录路径添加进包含目录中即可。

NCC 应用架构_环境配置_21


NCC 应用架构_#include_22

NCC 应用架构_深度学习_23


上图中以 blob.h 为例,说明了项目属性中的包含目录,会对应显示在IDE的外部依赖项中。


写到这里,差不多本文也就要结束了。如果我的这篇文章帮助到了你,那我也会感到很高兴,一个人能走多远,在于与谁同行