c++ opencv 部署推理minist模型(c++ opencv 自学笔记)

首先讲pytorch中的训练好的模型.pth文件转成onnx文件。转换代码如下

if __name__ == '__main__':
    for epoch in range(1):
        train(epoch)

        if epoch % 10 == 9:
            test()

    torch.save(model.state_dict(), "model.pth")
    model.cpu()#GPU训练转到cpu
    model.eval()
    x = torch.randn(1,1,  28, 28)#minist数据集是单通道,28*28
    torch.onnx.export(model, x, "model.onnx")

将转换好的onnx文件保存到VS2019的代码同一级下。

 开始推理

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <string>

using namespace std;
using namespace cv;
using namespace dnn;

int main() {
    

    // 加载ONNX模型
    Net net = readNetFromONNX("model.onnx"); // 确保模型文件路径正确
    if (net.empty()) {
        cout<< "Failed to load model." << endl;
        return -1;
    }

    // 设置后端和目标设备
    net.setPreferableBackend(DNN_BACKEND_OPENCV);
    net.setPreferableTarget(DNN_TARGET_CPU);

    // 读取图片
    Mat image = imread("D:/yanjiushen/PHOTO/手写字.webp");
    if (image.empty()) {
        cout << "Image not found or the path is incorrect." << endl;
        return -1;
    }

    // 转换为灰度图
    Mat gray;
    cvtColor(image, gray, COLOR_BGR2GRAY);

    // 根据模型要求调整图像大小
    Mat resized = Mat(28, 28, CV_8UC1); // 创建一个28x28的空白图像
    cv::resize(gray, resized, resized.size()); // 将灰度图调整到指定大小

    // 归一化图像数据
    Mat blob;
    float scalefactor = 1.0f / 255.0f; // 归一化因子
    blobFromImage(resized, blob, scalefactor, Size(), Scalar(), true, false, CV_32F);// 归一化并转换为blob

    // 设置模型输入
    net.setInput(blob);// 将blob数据设置为网络的输入

    // 执行推理
    Mat predict = net.forward();

    // 输出预测结果
    cout << "Prediction result: " << endl;
    for (int i = 0; i < predict.total(); i++) {// 遍历预测结果数组
        cout << predict.at<float>(i) << " ";// 输出每个元素的值
    }
    cout << endl;

    // 找到概率最高的索引(即预测的数字)
    double maxVal;
    minMaxLoc(predict, 0, &maxVal, 0, 0);
    cout << "Predicted class: " << maxVal << endl;

    return 0;
}

输入为数字8

 

输出结果。

因为模型之训练了一轮,不考率精度,但预测结果是对的。

minist 是10分类的0-9十个数字,数字8对应的预测结果为数组的下标为7即0.384404。

注意点 预测时要对输入的图片大小进行处理,以及归一化等操作

  • dnn::initModule() 用于初始化DNN模块,确保DNN功能可以正常使用。
  • readNetFromONNX("model.onnx") 需要有效的ONNX模型文件路径。
  • cvtColor 用于颜色空间转换,确保原图像是BGR格式。
  • cv::resize 用于改变图像大小,适应模型输入尺寸。
  • blobFromImage 用于将图像数据转换为网络输入所需的blob格式,并进行归一化。这里假设了均值为0(实际上Minist数据集通常使用均值127进行归一化,根据你的模型调整)。
  • net.setInput(blob) 设置网络的输入数据。
  • net.forward() 执行前向传播,获取预测结果。
  • minMaxLoc 用于找到预测结果中的最大值,这里假设最大值的索引对应预测的类别。
  • 确保图像路径和模型路径正确,且图像文件确实存在于该路径下。
  • 根据你的模型输出,可能需要调整minMaxLoc的使用方式,以正确解析预测结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值