如何将cv::Mat转换为torch::Tensor并输入至LibTorch模型?
在C++中将cv::Mat转换为Torch Tensor并输入模型的方法
Torch C++ API里没有和Python中torch.Tensor()完全一致的直接构造函数,但可以通过torch::from_blob()高效完成cv::Mat到Tensor的转换,同时处理好模型要求的维度、通道顺序和数据格式,具体步骤如下:
核心转换流程
- 预处理图像:调整OpenCV图像的通道顺序(BGR转RGB)、数据类型(通常转为float32)并归一化
- 从内存创建Tensor:利用
torch::from_blob()直接复用cv::Mat的内存,避免冗余拷贝 - 调整维度适配模型:将OpenCV的HWC(高度、宽度、通道)格式转为PyTorch常用的CHW(通道、高度、宽度)格式,再添加batch维度
完整代码示例
#include <opencv2/opencv.hpp> #include <torch/torch.h> #include <torch/jit.h> int main() { // 读取图像 cv::Mat img = cv::imread("test_image.jpg"); if (img.empty()) { std::cerr << "Failed to read image" << std::endl; return -1; } // 1. 图像预处理:BGR转RGB + 转为float32 + 归一化到[0,1] cv::cvtColor(img, img, cv::COLOR_BGR2RGB); img.convertTo(img, CV_32F, 1.0 / 255.0); // 2. 从cv::Mat内存创建Tensor,此时维度为(H, W, C) torch::Tensor input_tensor = torch::from_blob( img.data, {img.rows, img.cols, img.channels()}, torch::kFloat32 ); // 3. 调整维度:HWC -> CHW,再添加batch维度变为(B, C, H, W) input_tensor = input_tensor.permute({2, 0, 1}).unsqueeze(0); // 加载预训练模型(示例为TorchScript模型) torch::jit::script::Module model; try { model = torch::jit::load("model.pt"); } catch (const c10::Error& e) { std::cerr << "Failed to load model" << std::endl; return -1; } // 设置模型为评估模式 model.eval(); // 4. 前向传播 torch::NoGradGuard no_grad; // 推理时禁用梯度计算 torch::Tensor output = model.forward({input_tensor}).toTensor(); // 后续处理输出... return 0; }
关键注意事项
- 内存管理:
torch::from_blob()是浅拷贝,必须保证cv::Mat对象在Tensor的生命周期内不被销毁。如果需要独立的Tensor,可在创建后调用input_tensor.clone()完成深拷贝。 - 数据类型匹配:模型通常接受float32类型输入,因此需要将OpenCV默认的CV_8U(8位无符号整数)通过
convertTo()转为CV_32F。 - 通道顺序:OpenCV读取的图像默认是BGR通道顺序,而大多数PyTorch模型是基于RGB训练的,必须用
cv::cvtColor()转换通道。 - 维度要求:PyTorch模型的输入一般是批量格式
[B, C, H, W],因此需要用permute()调整维度顺序,再用unsqueeze(0)添加batch维度(单张图像时batch size为1)。
内容的提问来源于stack exchange,提问作者Twain
相关产品推荐
相关产品推荐

