吐⾎总结:windows下libtorch调⽤pytorch模型,并读取本地图⽚进⾏预测
使⽤CV::imread() 读取图⽚时,如何保证python中torch模型输出的数据和libtorch输出的数据⼀模⼀样?
请⼤家关注,相互交流哈~
⽹上各种教程,全不说关键所在。吐⾎三天整出了代码核⼼
怀着鸡冻的⼼情写下这个博客,做个记录。
⽹上有出多使⽤这种s(1,3,64,64)来⽣成⼀个张量作为模型的输⼊数据,⽐较python和c++平台的输出结果是否⼀致。
这个也是有必要的,但这只是第⼀步。因为我们⼀般输⼊的数据不可能都是这样⽣成,往往都是读取图⽚,然后经过⼀系列处理才送进
module。在这个过程就会出现各种问题。这就是博主今天要总结的东西:
trance_module = torch.jit.load( os.path.join(PATH,"scriptmodule1.pt") )
output2 = traced_script_s(1,3,64,64).to((device))) #image
保证python和C++两个平台数据的⼀致性有两个关键:
1. 图⽚数据的预处理必须⼀致 如果输⼊数据都不⼀样,那还搞啥⼦! 所以,⼤家可以看到我的图⽚,读取图⽚得到 img
之后,我没有使⽤torch的transform来做处理。这是因为c++的libtorch在读取⾃⼰的数据集时我不会使⽤transform库(这⾥就是我的缺陷了,弄了很久还是不会跟python⼀样,调⽤torch⾃带的transform库来处理图⽚,有⼈知道的欢迎留⾔告诉我⼀样,谢谢啦~)
⼤家看图1中代码,我使⽤的是最原始的⽅法,整体处以255.0(线性归⼀化)。
之所这样是因为c++也能这样处理,⽽不⽤费⼒使⽤tranform。
2. cv::imread(“img”)。之后,有个关键:
这⾥的核⼼就在与 torch::from_blob( ),这个函数
不⼩⼼的话你会遇到跟博主⼀样的问题,折腾了所有⽅案就是搞不定,困恼好⼏天!!明明所以操作和处理⼀致,就是得不到⼀致的输出,⽽且,c++ libtorch的输出还特别⼤,都是 1.0e18级别的。 这⾥的关键就是(看代码):torch::kByte。
具体原因还来得及了解,欢迎⼤家交流~
torch::Tensor imgtransform;
imgtransform = torch::from_blob(img.data,{ws, ls,3 }, torch::kByte); //
imgtransform = imgtransform.permute({ 0,3,1,2 });
imgtransform = (torch::kFloat);
imgtransform = imgtransform.div(255.0);
上图就是图1了,这个博客⽹站我还不是很熟,不知道为什么不能加图标题,不过在做libtorch的朋友,⼀定很熟悉这个界⾯哈哈哈哈~
直接上全部代码:
python的。
imgPath ="E:/00_ComponentData/rule/test/01_Crankshaft"
img = cv.imread( os.path.join(imgPath,"063.jpg"))# ,cv.COLOR_BAYER_BG2RGB img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
img = cv.resize(img,(64,64))
img = torch.from_numpy(img)
img = img.permute(2,0,1)
img = (torch.float)
img = img.div(255.0)
image = torch.unsqueeze(img,0).to(device)
print((img_input.shape),' --- ',image.shape)
inputs =(torch.rand(1,3,224,224).to(device))
trance_module = torch.jit.load( os.path.join(PATH,"scriptmodule1.pt"))
output2 = trance_module (inputs).to((device)))
print(output2)
C++的代码:
// vc_torch_test02.cpp: 定义应⽤程序的⼊⼝点。
//
//#include "vc_torch_test02.h"
#include<iostream>
#include<string>
#include<memory>
#include<stdlib.h>
#include<assert.h>
//#include"torchNet.h"
#include<torch/torch.h>
#include<torch/script.h>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
using namespace torch;
//
java调用python模型int main()
{
cout <<"Hello World!\n";
torch::Tensor img_tensor = torch::rand({3,64,64});
cout << img_tensor[1][0][0]<< endl;
cv::Mat img = cv::imread("E:/00_ComponentData/rule/test/01_Crankshaft/063.jpg"); pty()||!img.data)
std::cout <<"read image fail"<< std::endl;
cv::cvtColor(img, img, cv::COLOR_BGR2RGB);
cv::resize(img, img, cv::Size(64,64),0,0);
cv::imshow("ds", img);
//cv::waitKey(2000);
string modelpath ="D:/Python/00-work/01-torch-test/trained_models/";
string modelname ="scriptmodule1.pt";
torch::jit::Module model = torch::jit::load(modelpath + modelname);
model.eval();
<(at::kCUDA);
//cv::normalize(img, img, 1, 1.0);
torch::Tensor imgtransform;
imgtransform = torch::from_blob(img.data,{ws, ls,3}, torch::kByte);// imgtransform = imgtransform.permute({0,3,1,2});
imgtransform = (torch::kFloat);
imgtransform = imgtransform.div(255.0);
//imgtransform = imgtransform.unsqueeze(0); //
//imgtransform = (0.5);
imgtransform = (torch::kCUDA);
auto output = model.forward({ imgtransform }).toTensor();
cout << output.slice(/*dim*/1,/*start*/0,/*end*/6)<< endl;
cv::waitKey(2000);
return0;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论