---
# System prepended metadata

title: Ubuntu 建立 ncnn 模型環境

---

# Ubuntu 建立 ncnn 模型環境

### 先取得需轉換好的模型權重從 pth 到 onnx

https://docs.microsoft.com/zh-cn/windows/ai/windows-ml/tutorials/pytorch-convert-model

```python=
# Export the model
# torch_out = torch.onnx._export(model,  # model being run
#                                x.to(device),  # model input (or a tuple for multiple
#                                f='Magface.onnx',
#                                export_params=True,
#                                verbose=True,
#                                opset_version=11)
onnx_model = load_model("Magface.onnx")
trans_model = float16_converter.convert_float_to_float16(onnx_model, keep_io_types=True)
save_model(trans_model, "Magface_fp16.onnx")
```

### 建立 ncnn 編譯環境:

1. 先下載環境建置文件
https://github.com/BoshiLee/dockerfiles/tree/main/ncnn_python_ubuntu

2. 完成 TODO 事項

### 簡化 onnx 模型:
簡化非必要的 onnx 模型參數，也可以讓後續轉換更順利

* 參考Git 安裝過程
https://github.com/daquexian/onnx-simplifier

安裝好後可下:
```bash=
onnxsim onnx_models/v5s-p6_wider_face.onnx onnx_models/v5s-p6_wider_face_sim.onnx
```

### 將 onnx 編譯成 ncnn
```bash=
cd tools/onnx
./onnx example.onnx example.parm example.bin
```
或者使用模型轉換網站:
[省去编译转换工具的时间开箱即用，一键转换](https://www.convertmodel.com/#input=onnx&output=onnx)

### 導入模型

1. 建立CMake 專案:

```
cmake_minimum_required(VERSION 2.8)
project(yolo_ncnn)
# ncnn
set(ncnn_install_dir "/home/app/ncnn/build/install")
set(ncnn_DIR "${ncnn_install_dir}/lib/cmake/ncnn")
find_package(ncnn REQUIRED)
# open cv
find_package( OpenCV REQUIRED )
add_executable(yolo_ncnn main.cpp)

if(ncnn_FOUND)
    message(STATUS "ncnn library: ${ncnn_INSTALL_PATH}")
    message(STATUS "    version: ${ncnn_VERSION}")
    message(STATUS "    libraries: ${ncnn_LIBS}")
    message(STATUS "    include path: ${ncnn_INCLUDE_DIRS}")
    target_link_libraries(yolo_ncnn ncnn)
endif()
if(OpenCV_FOUND)
    message(STATUS "OpenCV library: ${OpenCV_INSTALL_PATH}")
    message(STATUS "    version: ${OpenCV_VERSION}")
    message(STATUS "    libraries: ${OpenCV_LIBS}")
    message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
    include_directories( ${OpenCV_INCLUDE_DIRS} )
    target_link_libraries(yolo_ncnn ${OpenCV_LIBS} )
endif()
```

2. 建立載入模型範例程式

```C++
//
// Created by boshi on 2022/6/6.
//
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "headers/net.h"

int main()
{
    cv::Mat img = cv::imread("face.jpg", cv::IMREAD_GRAYSCALE);
    int w = img.cols;
    int h = img.rows;

    // subtract 128, norm to -1 ~ 1
    ncnn::Mat in = ncnn::Mat::from_pixels_resize(img.data, ncnn::Mat::PIXEL_GRAY, w, h, 60, 60);
    float mean[1] = { 128.f };
    float norm[1] = { 1/128.f };
    in.substract_mean_normalize(mean, norm);

    ncnn::Net net;
    net.load_param("models/model.param");
    net.load_model("models/model.bin");

    ncnn::Extractor ex = net.create_extractor();
    ex.set_light_mode(true);
    ex.set_num_threads(4);
    
    // 這裡要修改成模型輸入的名稱，請找 model.param 的 input layer 是什麼名稱
    ex.input("images", in);

    ncnn::Mat feat;
    ex.extract("output", feat);
    printf("x = %d\n", feat);
    return 0;
}
```

[參考專案 Git](https://github.com/BoshiLee/yolov5s_ncnn_test) 

### 編譯專案
```bash=
cmake .
make
```

### 執行專案
```bash=
./yolo_ncnn
```