当前位置:网站首页>pc端ncnn搭建与测试
pc端ncnn搭建与测试
2022-08-09 07:50:00 【HySmiley】
目录
在PC使用NCNN框架推理加速模型,需要先获取ncnn编译后的动静态库。
一、本文系统配置
windows10
VS2019
CMake 3.18.4
二、编译
编译前需要先下载protobuf和ncnn源码。
参考:
Windows下ncnn环境配置(VS2019)_逮仔的博客-CSDN博客_ncnn vs2019
(一)ncnn | Windows(VS2019)编译_Silence_Zzz的博客-CSDN博客_vs2019编译ncnn
ncnn和opencv在vs2022上创建工程推理示例_三叔家的猫的博客-CSDN博客_ncnn
如果不想编译也可以使用官方编译好的文件:Releases · Tencent/ncnn · GitHub
三、测试
1、配置ncnn、protobuf、opencv
新建VS空项目工程。
以上编译是release版本,VS配置器选择Realease x64平台
VC++目录-包含目录:
VC++目录-库目录
链接器-输入-附加依赖项:
2、模型文件拷贝
将ncnn下的example文件加下的模型及标签文件拷贝到VS创建的工程下,找一张分类图片做测试
3、代码测试
// 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 "net.h"
#include <algorithm>
#if defined(USE_NCNN_SIMPLEOCV)
#include "simpleocv.h"
#else
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<opencv2/opencv.hpp>
#endif
#include <stdio.h>
#include <vector>
static int detect_squeezenet(const cv::Mat& bgr, std::vector<float>& cls_scores)
{
ncnn::Net squeezenet;
squeezenet.opt.use_vulkan_compute = true;
// the ncnn model https://github.com/nihui/ncnn-assets/tree/master/models
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, std::vector<int>& indexs, std::vector<float>& scores)
{
// 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);
indexs.push_back(index);
scores.push_back(score);
}
return 0;
}
static int load_labels(std::string path, std::vector<std::string>& labels)
{
FILE* fp = fopen(path.c_str(), "r");
while (!feof(fp))
{
char str[1024];
fgets(str, 1024, fp);
std::string str_s(str);
if (str_s.length() > 0)
{
for (int i = 0; i < str_s.length(); i++)
{
if (str_s[i] == ' ')
{
std::string strr = str_s.substr(i, str_s.length() - i - 1);
labels.push_back(strr);
i = str_s.length();
}
}
}
}
}
int main(int argc, char** argv)
{
/*if (argc != 2)
{
fprintf(stderr, "Usage: %s [imagepath]\n", argv[0]);
return -1;
}*/
clock_t start = clock();
std::vector<std::string>labels;
load_labels("synset_words.txt", labels);
const char* imagepath = "rabbit.jpg";
cv::Mat m = cv::imread(imagepath, 1);
if (m.empty())
{
fprintf(stderr, "cv::imread %s failed\n", imagepath);
return -1;
}
std::vector<int>index;
std::vector<float>score;
std::vector<float> cls_scores;
detect_squeezenet(m, cls_scores);
print_topk(cls_scores, 3,index,score);
for (int i = 0; i < index.size(); i++)
{
cv::putText(m, labels[index[i]], cv::Point(10, 10 + i * 30), 0, 0.5, cv::Scalar(255, 100, 100), 2, 2);
}
clock_t end = clock();
std::cout << "运行时间:" << (double)(end - start) / CLOCKS_PER_SEC << std::endl;
cv::imshow("m", m);
//imwrite("dog_result.jpg", m);
cv::waitKey(0);
return 0;
}
运行结果:
边栏推荐
- 贪吃蛇小游戏——C语言
- pip安装更换镜像
- 3.MySQL插入数据, 读取数据、Where子句和Order By关键字
- es6 基础知识详解 变量 字符串 解构赋值 函数 对象 从入门到精通
- 教你更好的使用 idea 2021.2.3
- Codeforces Round #359 (Div. 2) C. Robbers' watch Violent Enumeration
- 数据库索引原理
- C language: detailed explanation of soda bottle
- DIMP:Learning Discriminative Model Prediction for Tracking 学习判别模型预测的跟踪
- 接口测试概念
猜你喜欢
随机推荐
MYSQLWorkbench看数据库ER图
resourcemanager启动失败,别的节点成功
Anaconda 使用代理
Colors that Tkinter can choose from
list and string conversion
线程API
查看日志常用命令
Pytorch中 nn.BatchNorm2d() 归一化操作
Luogu P1110 report statistics multiset stl good question
C#基础学习
postgresql Window Functions
oracle存储过程问题解答
Codeforces Round #359 (Div. 2) C. Robbers' watch Violent Enumeration
链表专项练习(四)
One-click login server script
Data storage implementation of SDRAM and read and write operations on its data
记录一次客户的APP数据库版本号升级失败的情况
The String class objects created by the JVM memory allocation and the difference between equals and = =
Codeforces Round #359 (Div. 2) C. Robbers' watch 暴力枚举
VOC format label to YOLO format