首先讲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
的使用方式,以正确解析预测结果。