Skip to content

quickstart_cpp

wangzhaode edited this page Mar 25, 2026 · 1 revision

C++ 快速开始

本教程带你从源码编译到 C++ 推理,完成一个端到端的图像分类任务。

1. 编译 MNN

cd MNN
mkdir build && cd build
cmake .. -DMNN_BUILD_CONVERTER=ON
make -j8

更多平台(iOS/Android/Windows)编译方式请参考 从源码构建

2. 转换模型

./MNNConvert -f ONNX --modelFile mobilenet_v1.onnx --MNNModel mobilenet_v1.mnn --weightQuantBits 8

3. 编写推理代码

使用推荐的 Module API 进行推理(参考 demo/exec/pictureRecognition_module.cpp):

#include <stdio.h>
#include <MNN/expr/Module.hpp>
#include <MNN/expr/Executor.hpp>
#include <MNN/expr/ExprCreator.hpp>
#include <MNN/ImageProcess.hpp>

using namespace MNN;
using namespace MNN::Express;

int main(int argc, const char* argv[]) {
    if (argc < 3) {
        printf("Usage: ./classify model.mnn input.jpg\n");
        return 1;
    }

    // 1. 创建 RuntimeManager 配置后端
    ScheduleConfig sConfig;
    sConfig.type = MNN_FORWARD_CPU;
    sConfig.numThread = 4;
    auto rtmgr = std::shared_ptr<Executor::RuntimeManager>(
        Executor::RuntimeManager::createRuntimeManager(sConfig));

    // 2. 加载模型(空 vector 表示自动检测输入输出名)
    std::shared_ptr<Module> net(
        Module::load({}, {}, argv[1], rtmgr));
    if (!net) {
        printf("Failed to load model\n");
        return 1;
    }

    // 3. 创建输入 (NC4HW4 是 MNN 内部优化格式)
    int width = 224, height = 224;
    auto input = _Input({1, 3, height, width}, NC4HW4);

    // 4. 图像预处理(使用 MNN ImageProcess)
    // 实际项目中用 stb_image/opencv 读图后用 ImageProcess 转换
    // 此处简化为填充测试数据
    auto inputPtr = input->writeMap<float>();
    // ... 填充预处理后的图像数据到 inputPtr ...
    input->unMap();

    // 5. 推理
    auto outputs = net->onForward({input});

    // 6. 读取输出
    auto output = _Convert(outputs[0], NHWC);
    output = _Reshape(output, {0, -1});
    auto outputPtr = output->readMap<float>();
    // 找到概率最大的类别
    int classId = 0;
    float maxVal = outputPtr[0];
    int outputSize = output->getInfo()->size;
    for (int i = 1; i < outputSize; i++) {
        if (outputPtr[i] > maxVal) {
            maxVal = outputPtr[i];
            classId = i;
        }
    }
    printf("预测类别编号: %d, 置信度: %f\n", classId, maxVal);
    return 0;
}

4. 编译并运行

在 MNN build 目录下:

g++ -std=c++11 -o classify classify.cpp \
    -I ../include \
    -L . -lMNN -lMNN_Express

./classify mobilenet_v1.mnn test.jpg

5. 完整的图像处理示例

实际项目中使用 ImageProcess 完成图像解码和预处理,参考 demo/exec/pictureRecognition_module.cpp,核心流程:

#include <MNN/ImageProcess.hpp>

// 配置预处理参数
MNN::CV::ImageProcess::Config imgConfig;
imgConfig.filterType = MNN::CV::BILINEAR;
imgConfig.sourceFormat = MNN::CV::RGBA;
imgConfig.destFormat = MNN::CV::RGB;
imgConfig.mean[0] = 103.94f;
imgConfig.mean[1] = 116.78f;
imgConfig.mean[2] = 123.68f;
imgConfig.normal[0] = 0.017f;
imgConfig.normal[1] = 0.017f;
imgConfig.normal[2] = 0.017f;

auto pretreat = std::shared_ptr<MNN::CV::ImageProcess>(
    MNN::CV::ImageProcess::create(imgConfig));

// 设置缩放矩阵
MNN::CV::Matrix trans;
trans.setScale((float)(inputWidth - 1) / (width - 1),
               (float)(inputHeight - 1) / (height - 1));
pretreat->setMatrix(trans);

// 转换图像数据到 input VARP
pretreat->convert(imageData, inputWidth, inputHeight, 0,
                  input->writeMap<float>(), width, height, 4, 0,
                  halide_type_of<float>());

下一步

Clone this wiki locally