由于原来配置过2017年10月份的ncnn,现在项目需要重新在VS2013上配置目前最新的版本。
各种功能不再阐述,可以参考官网介绍,这里直接切入正题,ncnn-20180129版本官网下载地址:https://github.com/Tencent/ncnn/releases
1、下载好后,在VS新建一个工程,把“src”整个目录拷贝到工程根目录下。然后全部把“src”的源文件全部包含进来,另外由于是在windows上用,把包含进来的文件-->"layer"-->"arm"全部“从项目中排出”,见下图:
2、把“platform.h.in”改名为“platform.h”,并且在里面修改为如下内容保存:
3、头文件包含,打开项目的属性,把2个头文件路径包含进来,记得分别在Debug和Release下。
4、不知道什么原因,20180129这个版本没有"layer_declaration.h"、“layer_registry.h”头文件,这个时候可以下载2017年10月份官网的ncnn,在src源目录里面找到这2个头文件包含进来,再尝试编译
5、可以尝试编译一下,如果出现error C3861: '_InterLockedCompareExchang‘,则需要包含系统xlocale头文件,在“benchmark.cpp”
6、新建一个main函数测试一下,当然记得配置好自己opencv的版本和准备好自己的模型。可以下载烂大街的Alexnet做测试。我这里是用自己训练出来的模型,转换成.param和.bin文件然后看提取的特征数据。
// 20180129版本的
// 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<functional> // 排序函数需要的
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<opencv2/opencv.hpp>
#include<iostream>
#include <fstream>
#include "src/net.h"
//#include "ltcnnprotonew.mem.h" // 导致编辑器堆空间不足
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(int argc, char** argv)
{
bool isValidiate = 1;
ncnn::Net net;
if (isValidiate)
{
// 适合快速复现
/*net.load_param("squeezenet_v1.1.param");
net.load_model("squeezenet_v1.1.bin");*/
net.load_param("F:/ncnn/smoke20180206/smoke_new_float.param");//"F:/ncnn/caffe2ncnn-windows/ltcnnprotonew.param"
//"F:/ncnn/smoke20180206/smoke_new_float.param"
net.load_model("F:/ncnn/smoke20180206/smoke_new_float.bin");
}
else
{
// 适合 APP 分发模型资源,模型名字改下即可
net.load_param("ltcnnprotonew.param.bin");
net.load_model("ltcnnprotonew.bin");
}
//
std::ifstream fid("F:\\Matlab_Files\\facerecognizition\\samePairPath_ourdata.txt");
std::ifstream fid2("F:\\Matlab_Files\\facerecognizition\\diffPairPath_ourdata.txt");
std::string stringLine, pairFirst, pairSecond;
std::vector<std::pair<std::string, std::string> > samepair, diffpair;
while (getline(fid, stringLine))
{
char a[255], b[255];
sscanf(stringLine.c_str(), "%s%s", a, b);
pairFirst = a;
pairSecond = b;
samepair.push_back(std::pair<std::string, std::string>(pairFirst, pairSecond));
}
fid.close();
while (getline(fid2, stringLine))
{
char a[255], b[255];
sscanf(stringLine.c_str(), "%s%s", a, b);
pairFirst = a;
pairSecond = b;
diffpair.push_back(std::pair<std::string, std::string>(pairFirst, pairSecond));
}
fid2.close();
int nums_same = 0;
std::vector<float> cls_scores1, cls_scores2;
cv::Mat imgGray1, imgGray2;
for (size_t i = 0; i < diffpair.size(); i++)
{
imgGray1 = cv::imread("C:/caffe/caffe-master/examples/smoke_train_large/20000000030_61_at61_2018-01-17_00_37_35_342.png", 0);//diffpair[i].first
//"C:/caffe/caffe-master/examples/smoke_train_large/20000000030_61_at61_2018-01-17_00_37_35_342.png"
imgGray2 = cv::imread("C:/caffe/caffe-master/examples/smoke_train_large/20000000030_61_at61_2018-01-17_00_37_35_342.png", 0);//diffpair[i].second
ncnn::Mat in1 = ncnn::Mat::from_pixels_resize(imgGray1.data, ncnn::Mat::PIXEL_GRAY, imgGray1.cols, imgGray1.rows, 112, 112);
ncnn::Mat in2 = ncnn::Mat::from_pixels_resize(imgGray2.data, ncnn::Mat::PIXEL_GRAY, imgGray2.cols, imgGray2.rows, 128, 128);
const float mean_vals[3] = { 0.f, 0.f, 0.f };
const float normal = 1. / 255.0f;
in1.substract_mean_normalize(mean_vals, &normal);
in2.substract_mean_normalize(mean_vals, &normal);
ncnn::Mat out1, out2;
ncnn::Extractor ex1 = net.create_extractor();
ex1.set_light_mode(true);
ex1.input("data", in1);
double time1 = cv::getTickCount();
ex1.extract("fc1", out1);// 原来是“prob”
printf("Time:(ms) %f\n", (cv::getTickCount() - time1) / cv::getTickFrequency() * 1000);
ncnn::Extractor ex2 = net.create_extractor();
ex2.set_light_mode(true);
ex2.input("data", in2);
ex2.extract("fc1", out2);
ncnn::Mat out_flatterned1 = out1.reshape(out1.w * out1.h * out1.c);
ncnn::Mat out_flatterned2 = out2.reshape(out2.w * out2.h * out2.c);
cls_scores1.resize(out_flatterned1.w);
for (int j = 0; j<out_flatterned1.w; j++)
{
cls_scores1[j] = out_flatterned1[j];
}
cls_scores2.resize(out_flatterned2.w);
for (int j = 0; j<out1.c; j++)
{
cls_scores2[j] = out_flatterned2[j];
}
cv::Mat pnew1 = cv::Mat(1, 256, CV_32FC1);
for (size_t idm = 0; idm < 256; idm++)
{
pnew1.at<float>(0, idm) = std::max(cls_scores1[idm], cls_scores1[idm + 256]);
}
cv::Mat prob1 = pnew1.clone();
cv::Mat pnew2 = cv::Mat(1, 256, CV_32FC1);
for (size_t idm = 0; idm < 256; idm++)
{
pnew2.at<float>(0, idm) = std::max(cls_scores2[idm], cls_scores2[idm + 256]);
}
cv::Mat prob2 = pnew2.clone();
float dist = prob1.dot(prob2) / sqrt(prob1.dot(prob1)*prob2.dot(prob2));
cv::Mat tmp = cv::Mat::zeros(imgGray1.rows, 2 * imgGray1.cols, CV_8U);
imgGray1.copyTo(tmp(cv::Rect(0, 0, imgGray1.cols, imgGray1.rows)));
imgGray2.copyTo(tmp(cv::Rect(imgGray2.cols, 0, imgGray2.cols, imgGray2.rows)));
cv::putText(tmp, std::to_string(dist), cv::Point(50, 40), 1, 1.5, cv::Scalar::all(255), 1);
cv::putText(tmp, "diff" , cv::Point(70, 80), 1, 1.5, cv::Scalar::all(255), 1);
imwrite("outputdata/" + std::to_string(dist) + "_diff_" + std::to_string(nums_same++) + ".jpg", tmp);
cv::imshow("tmp", tmp);
int key = cv::waitKey(20);
if (key == 27)
{
break;
}
if (key == ' ')
{
cv::waitKey();
}
}
return 0;
}
上面是我的自己训练的深度模型示例结果,成功调试跑通~