-
Notifications
You must be signed in to change notification settings - Fork 2.3k
quickstart_cpp
wangzhaode edited this page Mar 25, 2026
·
1 revision
本教程带你从源码编译到 C++ 推理,完成一个端到端的图像分类任务。
cd MNN
mkdir build && cd build
cmake .. -DMNN_BUILD_CONVERTER=ON
make -j8更多平台(iOS/Android/Windows)编译方式请参考 从源码构建。
./MNNConvert -f ONNX --modelFile mobilenet_v1.onnx --MNNModel mobilenet_v1.mnn --weightQuantBits 8使用推荐的 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;
}在 MNN build 目录下:
g++ -std=c++11 -o classify classify.cpp \
-I ../include \
-L . -lMNN -lMNN_Express
./classify mobilenet_v1.mnn test.jpg实际项目中使用 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>());- Module API 详解 — 完整的 C++ 推理接口说明
- LLM 部署指南 — 部署大语言模型
- 模型压缩 — 权值量化、离线量化等
- Session API — 低层推理接口(特殊场景使用)