animesr.onnx
,所以我需要将 python 代码转换为 C++ 代码。这些是我的Python代码:
session = onnxruntime.InferenceSession('animesr.onnx')
img = cv2.imread('imgs/naruto.jpg')
ori_h, ori_w, _ = img.shape
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.resize(img, (512,512))
img = (np.array(img) / 255.0).astype(np.float32)
img = np.transpose(img, (2, 0, 1))
img = np.expand_dims(img, 0)
input_name = session.get_inputs()[0].name
output_name = session.get_outputs()[0].name
input_feed = {input_name: img}
output = session.run([output_name], input_feed)
output = output[0].clip(0, 1) * 255
output = output.astype(np.uint8)
output = np.squeeze(output)
output = np.transpose(output, (1, 2, 0))
output = cv2.cvtColor(output, cv2.COLOR_RGB2BGR)
output = cv2.resize(output, (ori_w*4, ori_h*4))
cv2.imwrite('naruto_animesr.jpg', output)
这是我的 C++ 代码:
Ort::Session session(env, ORT_TSTR(modelPath), sessionOptions);
cv::Mat inputImage = cv::imread(imagePath, cv::IMREAD_COLOR);
// cv::Mat blob = cv::dnn::blobFromImage(inputImage, 1.0/255, cv::Size(512,512), cv::Scalar(), true);
cv::Mat resizedImage;
cv::resize(inputImage, resizedImage, cv::Size(512,512));
cv::Mat floatImage;
resizedImage.convertTo(floatImage, CV_32FC3, 1.0/255.0);
Ort::MemoryInfo memoryInfo = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
std::vector<int64_t> inputShape = {1, 3, 512, 512};
Ort::Value inputTensor = Ort::Value::CreateTensor<float>(memoryInfo, (float*) floatImage.data, 3*512*512, inputShape.data(), inputShape.size());
std::vector<const char*> inputNames = {"input"};
std::vector<const char*> outputNames = {"output"};
std::vector<Ort::Value> outputTensor = session.Run(Ort::RunOptions{}, inputNames.data(), &inputTensor, 1, outputNames.data(), outputNames.size());
Ort::TensorTypeAndShapeInfo outputInfo = outputTensor[0].GetTensorTypeAndShapeInfo();
int channels = outputInfo.GetShape()[1]; // 3
int height = outputInfo.GetShape()[2]; // 2048
int width = outputInfo.GetShape()[3]; // 2048
const float* outputData = outputTensor[0].GetTensorMutableData<float>();
cv::Mat outputImage(height, width, CV_32FC(channels), const_cast<float*>(outputData));
cv::Mat uint8Image;
outputImage.convertTo(uint8Image, CV_8UC3, 255);
cv::Mat bgrOutput;
cv::cvtColor(uint8Image, bgrOutput, cv::COLOR_RGB2BGR);
cv::imwrite(outputPath, bgrOutput);
这就是结果 这是 cv::ddn::blobFromImage() 的结果
两者都是糟糕的结果,与我的Python结果不同。
我认为问题出在运行模型之前将图像作为输入进行预处理并将输出处理为CV图像,我不擅长矩阵运算,如变换、转置、重塑等。
你们能帮我提供正确的opencv c++处理图像代码吗
谢谢你
我已经检查了您的 C++ 代码。问题在于您的代码没有利用 cv::split 来分离张量数据的输入图像的通道。有必要分割通道并使用足够大的缓冲区来将数据重新排列为以下格式:[r0, r1, r2, ..., rn], [g0, g1, g2, ..., gn ], [b0, b1, b2, ..., bn]。此外,对于输出张量数据,您应该应用相反的过程并使用 cv::merge 将通道重新组装回 RGB 图像。