You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C++通过ONNX Runtime加载超分辨率ONNX模型

C++中用ONNX Runtime加载超分辨率ONNX模型实现图像超分

一、环境准备

  • 安装ONNX Runtime C++库:可下载官方预编译包,或通过vcpkg安装(执行vcpkg install onnxruntime)
  • 依赖OpenCV库:用于图像的读取、预处理与后处理

二、完整实现代码

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
#include <onnxruntime_cxx_api.h>

int main() {
    // 1. 初始化ONNX Runtime环境
    Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "SuperResolution");
    Ort::SessionOptions session_options;
    session_options.SetIntraOpNumThreads(4); // 设置推理线程数
    session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL); // 启用所有图优化

    // 2. 加载ONNX模型
    const std::string model_path = "Model.onnx";
    Ort::Session session(env, model_path.c_str(), session_options);

    // 3. 获取模型输入输出信息
    Ort::AllocatorWithDefaultOptions allocator;
    const char* input_name = session.GetInputName(0, allocator);
    const char* output_name = session.GetOutputName(0, allocator);
    std::vector<const char*> input_names = {input_name};
    std::vector<const char*> output_names = {output_name};

    // 获取输入张量形状:[batch, channel, height, width]
    Ort::TypeInfo input_type_info = session.GetInputTypeInfo(0);
    auto input_tensor_info = input_type_info.GetTensorTypeAndShapeInfo();
    std::vector<int64_t> input_shape = input_tensor_info.GetShape();
    int input_h = input_shape[2];
    int input_w = input_shape[3];

    // 4. 读取并预处理输入图像
    cv::Mat img = cv::imread("input.jpg");
    if (img.empty()) {
        std::cerr << "读取图像失败!" << std::endl;
        return -1;
    }

    // 调整图像尺寸匹配模型输入
    cv::Mat resized_img;
    cv::resize(img, resized_img, cv::Size(input_w, input_h));

    // BGR转RGB、归一化到[0,1]、转换为CHW格式
    cv::Mat rgb_img;
    cv::cvtColor(resized_img, rgb_img, cv::COLOR_BGR2RGB);
    rgb_img.convertTo(rgb_img, CV_32F, 1.0 / 255.0);

    std::vector<float> input_data(3 * input_h * input_w);
    int idx = 0;
    for (int c = 0; c < 3; ++c) {
        for (int h = 0; h < input_h; ++h) {
            for (int w = 0; w < input_w; ++w) {
                input_data[idx++] = rgb_img.at<cv::Vec3f>(h, w)[c];
            }
        }
    }

    // 5. 创建输入张量
    auto memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
    Ort::Value input_tensor = Ort::Value::CreateTensor<float>(
        memory_info, input_data.data(), input_data.size(), input_shape.data(), input_shape.size());

    // 6. 执行模型推理
    auto output_tensors = session.Run(Ort::RunOptions{nullptr}, input_names.data(), &input_tensor, 1, output_names.data(), 1);

    // 7. 处理输出张量并保存图像
    float* output_data = output_tensors[0].GetTensorMutableData<float>();
    auto output_shape = output_tensors[0].GetTensorTypeAndShapeInfo().GetShape();
    int output_h = output_shape[2];
    int output_w = output_shape[3];

    // CHW转HWC、反归一化到[0,255]、RGB转BGR
    cv::Mat output_img(output_h, output_w, CV_32FC3);
    idx = 0;
    for (int c = 0; c < 3; ++c) {
        for (int h = 0; h < output_h; ++h) {
            for (int w = 0; w < output_w; ++w) {
                output_img.at<cv::Vec3f>(h, w)[c] = output_data[idx++] * 255.0;
            }
        }
    }
    output_img.convertTo(output_img, CV_8UC3);
    cv::cvtColor(output_img, output_img, cv::COLOR_RGB2BGR);

    cv::imwrite("output_sr.jpg", output_img);
    std::cout << "超分图像已保存为output_sr.jpg" << std::endl;

    return 0;
}

三、关键步骤说明

  • 预处理:模型要求输入为RGB格式、CHW布局、归一化到[0,1]的float32张量,需将OpenCV默认读取的BGR图像做格式转换
  • 模型加载:通过ONNX Runtime的Session类加载模型,启用图优化可提升推理效率
  • 推理执行:调用Run方法传入输入张量,直接获取模型输出张量
  • 后处理:将输出的CHW张量转回HWC图像格式,反归一化到[0,255]后转成BGR格式保存

编译示例(g++)

g++ -std=c++17 main.cpp -o super_resolution -I/your/onnxruntime/include -L/your/onnxruntime/lib -lonnxruntime `pkg-config --cflags --libs opencv4`

替换/your/onnxruntime为你的ONNX Runtime库实际路径,OpenCV的pkg-config参数根据版本调整(如用opencv替代opencv4)

内容的提问来源于stack exchange,提问作者Seyed Amirreza Kabodian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 00:20:31