博客
关于我
[LibTorch] Tensor 转为 Mat
阅读量:224 次
发布时间:2019-02-28

本文共 2546 字,大约阅读时间需要 8 分钟。

Torch框架与OpenCV结合实现图像处理输出

在使用Torch框架进行图像处理任务时,通常会遇到如何将模型输出转换为OpenCV支持的矩阵并保存为图片文件的问题。本文将详细介绍实现过程,包括单通道、三通道输出的处理方法以及CUDA到CPU数据转移的技巧。

单通道输出处理

假设模型输出的Tensor为单通道图像,通道数为1。以下是实现过程的代码示例:

#include 
#include
// 初始化模型torch::jit::script::Module net = torch::jit::load("../models/poolnet.pt");net.to(device);net.eval();// 读取并转换图片格式cv::Mat img = cv::imread(fileName);cv::cvtColor(img, img, cv::COLOR_BGR2RGB);// 创建Tensor并调整形状auto img_tensor = torch::from_blob(img.data, {1, img.rows, img.cols, 3}, torch::TensorOptions().dtype(torch::kByte)).to(device);img_tensor = img_tensor.permute({0, 3, 1, 2});img_tensor = img_tensor.toType(torch::kFloat);// 前向传播并获取输出torch::NoGradGuard no_grad;auto result = net.forward({img_tensor}).toTensor();// 数据转移与格式转换result = result.squeeze().sigmoid().mul(255.0).toType(torch::kByte).to(torch::kCPU);// 创建并保存结果图片cv::Mat img_C1;img_C1.create(cv::Size(img.cols, img.rows), CV_8UC1);memcpy(img_C1.data, result.data_ptr(), result.numel() * sizeof(torch::kByte));cv::imwrite(saveName, img_C1);

三通道输出处理

对于输出通道数为3的模型,处理方式几乎与单通道类似,但需要注意通道维度的调整:

#include 
#include
// 初始化模型torch::jit::script::Module net = torch::jit::load("../models/poolnet2.pt");net.to(device);net.eval();// 读取并转换图片格式cv::Mat img = cv::imread(fileName);cv::cvtColor(img, img, cv::COLOR_BGR2RGB);// 创建Tensor并调整形状auto img_tensor = torch::from_blob(img.data, {1, img.rows, img.cols, 3}, torch::TensorOptions().dtype(torch::kByte)).to(device);img_tensor = img_tensor.permute({0, 3, 1, 2});img_tensor = img_tensor.toType(torch::kFloat);// 前向传播并获取输出torch::NoGradGuard no_grad;auto result = net.forward({img_tensor}).toTensor();// 数据转移与格式转换result = result.squeeze().sigmoid().mul(255.0).toType(torch::kByte).permute({1, 2, 0}).to(torch::kCPU);// 创建并保存结果图片cv::Mat img_C3;img_C3.create(cv::Size(img.cols, img.rows), CV_8UC3);memcpy(img_C3.data, result.data_ptr(), result.numel() * sizeof(torch::kByte));cv::imwrite(saveName, img_C3);

CUDA到CPU数据转移问题

在完成模型推理后,需要将GPU上的Tensor数据转移到CPU上,以便使用memcpycv::Mat进行操作。以下是两种常见转移方法:

// 方法一:直接转移result = result.to(torch::kCPU);// 方法二:使用cudaMemcpy(需要包含cuda_runtime.h)cudaMemcpy(pred.data, out.data_ptr(), out.numel(), cudaMemcpyDeviceToHost);

数据转移性能建议

  • 通道数量:通道数量越大,转移时间越长。建议减少模型输出的通道数或优化网络架构。
  • 网络深度:深层网络输出的张量规模较大,转移时间自然增加。
  • 硬件配置:使用高性能显卡(如GTX 1080 Ti)和支持CUDA 11.2的环境可以显著缩短转移时间。
  • 性能优化

    如果对转移时间要求较高,可以考虑以下优化方法:

  • 减少输出通道数:通过调整模型输出层的通道数量减少数据量。
  • 使用更高效的数据类型:直接声明Tensor为CUDAFloatType类型,减少数据转移时间。
  • 通过以上方法,可以实现Torch框架输出的Tensor数据高效转换为OpenCV支持的矩阵,并成功保存为图片文件。

    转载地址:http://goep.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现借记款项功能(附完整源码)
    查看>>
    Objective-C实现关系矩阵A和B的乘积(附完整源码)
    查看>>
    Objective-C实现关系矩阵乘法(附完整源码)
    查看>>
    Objective-C实现关系矩阵乘法(附完整源码)
    查看>>
    Objective-C实现内存映射文件(附完整源码)
    查看>>
    Objective-C实现内存泄露检查(附完整源码)
    查看>>
    Objective-C实现内格尔·施雷肯伯格算法(附完整源码)
    查看>>
    Objective-C实现几何级数的总和算法 (附完整源码)
    查看>>
    Objective-C实现分块查找算法(附完整源码)
    查看>>
    Objective-C实现分块查找算法(附完整源码)
    查看>>
    Objective-C实现分水岭算法(附完整源码)
    查看>>
    Objective-C实现分解质因数(附完整源码)
    查看>>
    Objective-C实现切换数字的符号switchSign算法(附完整源码)
    查看>>
    Objective-C实现列主元高斯消去法(附完整源码)
    查看>>
    Objective-C实现创建多级目录(附完整源码)
    查看>>
    Objective-C实现删除重复的字母字符算法(附完整源码)
    查看>>
    Objective-C实现判断32位的数字是否为正数isPositive算法(附完整源码)
    查看>>
    Objective-C实现十进制转N进制算法(附完整源码)
    查看>>
    Objective-C实现十进制转八进制算法(附完整源码)
    查看>>
    Objective-C实现华氏温度转摄氏温度(附完整源码)
    查看>>