NCNN 入门 (1) 安装以及第一个样例squeezenet

1. 安装

  • 目前只关心在linux上的安装,内容可以参考 官方教程
  • 步骤:
# 第一步:下载源码
git clone https://github.com/Tencent/ncnn.git
cd ncnn
git submodule update --init

# 第二步:配置 Vulkan 环境
wget https://sdk.lunarg.com/sdk/download/1.2.154.0/linux/vulkansdk-linux-x86_64-1.2.154.0.tar.gz?Human=true -O vulkansdk-linux-x86_64-1.2.154.0.tar.gz
tar -xf vulkansdk-linux-x86_64-1.2.154.0.tar.gz
# 这个最好放到 ~/.bashrc 中
export VULKAN_SDK=$(pwd)/1.2.154.0/x86_64

# 第三步:编译
cd ncnn
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DNCNN_VULKAN=ON -DNCNN_SYSTEM_GLSLANG=ON -DNCNN_BUILD_EXAMPLES=ON ..
make -j
  • 这些步骤都很简单,有问题也是一些C++、CMake的问题

2. 第一个样例 squeezenet

  • 运行:在编译好后,在 /path/to/ncnn/examples 目录下运行 ../build/examples/squeezenet ../images/256-ncnn.png 即可。
  • 程序入口在 /path/to/ncnn/examples/squeezenet.cpp,源码如下
#include "net.h"

#include <algorithm>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>
#include <vector>

static int detect_squeezenet(const cv::Mat& bgr, std::vector<float>& cls_scores)
{
    // 这里只是创建一个 Net 对象,里面还是空的
    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的尺寸扩展为至少 out.w 这么大,并复制所有结果到 cls_scores
    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)
{
    // 输入的是一个 float vector
    // 所以先构建一个 pair vector,包括 score, class_id
    // 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);
    }

    // 根据score排序,不是整个都排序,而是 partial sort,只获取前topk结果
    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)
{
    // 命令行参数处理
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s [imagepath]\n", argv[0]);
        return -1;
    }

    // 读取图片
    const char* imagepath = argv[1];
    cv::Mat m = cv::imread(imagepath, 1);
    if (m.empty())
    {
        fprintf(stderr, "cv::imread %s failed\n", imagepath);
        return -1;
    }

    // 获取模型结果
    std::vector<float> cls_scores;
    detect_squeezenet(m, cls_scores);

    // 结果后处理,获取top-3的结果
    print_topk(cls_scores, 3);

    return 0;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值