博客
关于我
[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实现double factorial recursive双阶乘递归算法(附完整源码)
    查看>>
    Objective-C实现double hash双哈希算法(附完整源码)
    查看>>
    Objective-C实现double linear search recursion双线性搜索递归算法(附完整源码)
    查看>>
    Objective-C实现DoublyLinkedList双链表的算法(附完整源码)
    查看>>
    Objective-C实现DPLL(davisb putnamb logemannb loveland)算法(附完整源码)
    查看>>
    Objective-C实现Edmonds-Karp算法(附完整源码)
    查看>>
    Objective-C实现EEMD算法(附完整源码)
    查看>>
    Objective-C实现EM算法(附完整源码)
    查看>>
    Objective-C实现EM算法(附完整源码)
    查看>>
    Objective-C实现entropy熵算法(附完整源码)
    查看>>
    Objective-C实现euclidean distance欧式距离算法(附完整源码)
    查看>>
    Objective-C实现Euclidean GCD欧几里得最大公约数算法(附完整源码)
    查看>>
    Objective-C实现euclideanDistance欧氏距离算法(附完整源码)
    查看>>
    Objective-C实现euler method欧拉法算法(附完整源码)
    查看>>
    Objective-C实现eulerianPath欧拉路径算法(附完整源码)
    查看>>
    Objective-C实现eval函数功能(附完整源码)
    查看>>
    Objective-C实现Exceeding words超词(差距是ascii码的距离) 算法(附完整源码)
    查看>>
    Objective-C实现extended euclidean algorithm扩展欧几里得算法(附完整源码)
    查看>>
    Objective-C实现Factorial digit sum阶乘数字和算法(附完整源码)
    查看>>
    Objective-C实现factorial iterative阶乘迭代算法(附完整源码)
    查看>>