在深度学习训练时,我们常需要对某层的输出或最终模型的预测结果进行输出查看,如featmap、output、predict结果等。在pytorch的设定中有tensor类型变量,不可直接查看和保存图片。

虽然有 torchvision.utils.save_image 方法可以方便地保存tensor类型图片,调用方法如下:

from torchvision.utils import save_imagesave_image(tensor , filename , padding =0)

这个方法不仅可以保存图片,而且可以保存多个图片拼接后输出。但是对于不同通道不同类型,如RGB和灰度图,的图片,仍然有不方便使用的地方,于是我自己写了几个函数,适用于图片的输出保存、拼接。

from PIL import Imagedef joint_img_vertical(imgs):# print(imgs.ndim)if imgs.ndim ==4:     #RGB imgwidth, height = imgs[0][0].shaperesult = Image.new('L', (width, height*imgs.shape[0]))# Add 0.5 after unnormalizing to [0, 255] to round to nearest integerimgs = imgs.mul_(255).add_(0.5).clamp_(0, 255).cpu().numpy().transpose((0, 2, 3, 1))elif imgs.ndim ==3:   #single channel imgwidth, height = imgs[0].shaperesult = Image.new('L', (width, height*imgs.shape[0]))imgs =imgs*255for i in range(imgs.shape[0]):im = Image.fromarray((imgs[i]).astype(np.uint8))result.paste(im, box=(0, i * height))# 取消注释以下代码可直接保存图片# im = Image.fromarray((img * 255).astype(np.uint8))# im.save(filename)# result.save(filename)return resultdef joint_img_horizontal(img,output,mask):# print(img.size, output.size, mask.size)if img.size == output.size == mask.size:width, height = img.sizeresult = Image.new('L', (width * 3, height))result.paste(img, box=(0, 0))result.paste(output, box=(width, 0))result.paste(mask, box=(2 * width, 0))return resultdef save_img(img,filename):'''it is used to save an img in filename directory:param img: the img should be Image type .:param filename: like "**.png"'''img.save(filename)

第一个函数的作用是垂直拼接一个Batch的tensor图片。我做的是一个分割任务,在我的程序中,有RGB图片(原图)和单通道图片(mask和output),对于RGB图片,维度是(batch , channel ,width ,height)。对于单通道图片,维度是(batch , width ,height)。

对于tensor类型,要转化为numpy类型,方法是tensor.cpu().numpy.transpose((0,2,3,1)) 。注意要保存为numpy后转为PIL中的Image类型。对于三通道图,要transpose为(width, height, channel )类型。

(这里我额外写了一个去Normalization的操作,个人视情况添加,我的代码中如果不添加这一步,会导致保存图片色彩失真,可能是我事先对数据做了数据增强的缘故)

第二个函数的作用是水平拼接三个Image类型的图片,即第一个函数的三个输出。这是为了将Image,output,mask三个图片放在同一个图片中做分割或检测效果对比观察。用到了new函数创建画布,paste方法粘贴图片到画布上。

Tip :查看tensor或numpy类型数组的大小尺寸。用tensor.shape 、numpy.shape ,而查看Image类型图片的大小,用img.size。

第三个函数的作用是保存Image图片类型到本地,注意只有Image类型的图片才有save方法,tensor和numpy类型的自然是没有的。因为本文对于图片的操作都用PIL来实现,所以保存图片也用的此方法。同样的思想,还可以用opencv库来实现。

同时调用以上三个函数就可以实现对一个Batch类型的图片批量拼接保存。

batch_img = joint_img_vertical(data)        #data是tensor类型
batch_output = joint_img_vertical(output)   #output是array类型
batch_mask = joint_img_vertical(predict)    #predict是array类型
img_for_save = joint_img_horizontal(batch_img, batch_output,batch_mask)
save_img(img_for_save, os.path.join(save_dir,"img_out_mask_%d.png"% i))

【补充】为什么有时候保存图片会失真?

在make_grid那里,你需要设置参数normalize = True。

pytorch拼接与保存图片相关推荐

  1. pytorch拼接函数:torch.stack()和torch.cat()--详解及例子

    原文链接: https://blog.csdn.net/xinjieyuan/article/details/105205326 https://blog.csdn.net/xinjieyuan/ar ...

  2. [PyTorch] 拼接多个tensor:torch.cat((A,B),axis)

    注:参考博客Pytorch中的torch.cat()函数.本人在其基础上增加了更为详细的解释. torch.cat((A,B),axis)是对A, B两个tensor进行拼接. 参数axis指定拼接的 ...

  3. pytorch拼接与拆分

    ** 一.拼接 ** cat/stack cat在指定的维度上进行连接: stack创建了新的维度进行连接. In [1]: import torchIn [2]: a = torch.rand(4, ...

  4. 用c#每日更换“必应背景图片”为“桌面壁纸”

    在线工具 必应每天都会更换背景图片,都非常漂亮,有的时候还十分惊艳,同时还会根据每个地区的特色不同应用不同的图片. 下面用c#抓取必应每天的背景图片,并实现桌面壁纸的每天自动切换 实现思路 1.通过获 ...

  5. Pytorch List Tensor转Tensor,,reshape拼接等操作

    Pytorch List Tensor转Tensor,reshape拼接等操作 持续更新一些常用的Tensor操作,比如List,Numpy,Tensor之间的转换,Tensor的拼接,维度的变换等操 ...

  6. PyTorch cat() 函数实现维度拼接

    PyTorch cat() 函数实现维度拼接 需要保证(除需要合并的维度外)其他维度均相等.参数dim指定需要合并的维度的索引号. 如下例子为合并第三维. import torch a = torch ...

  7. torch的拼接函数_从零开始深度学习Pytorch笔记(13)—— torch.optim

    前文传送门: 从零开始深度学习Pytorch笔记(1)--安装Pytorch 从零开始深度学习Pytorch笔记(2)--张量的创建(上) 从零开始深度学习Pytorch笔记(3)--张量的创建(下) ...

  8. 【PyTorch】torch.cat==>张量拼接,在图像的应用上可以有效利用原始图像结构信息

    1. 字面理解:torch.cat是将两个张量(tensor)拼接在一起,cat 是 concatenate 的意思,即拼接,联系在一起. 使用torch.cat((A,B),dim)时,除拼接维数d ...

  9. Pytorch:保存图片

    1. 直接保存Tensor #!/usr/bin/env python # _*_ coding:utf-8 _*_ import torch from torchvision import util ...

最新文章

  1. sap 给集团分配一个逻辑系统
  2. swift如何动态创建对象
  3. lucene7.5的数据结构
  4. 扬州大学计算机考研难考吗,扬州大学(专业学位)计算机技术考研难吗
  5. 前端学习(3209):react中类中方法的this指向
  6. Ubuntu 下PySpark安装
  7. STM32 - 定时器的设定 - 基础 01 - Timer Base - Prescaler description - Upcounting mode
  8. python产品发布会_大型发布会现场的 Wi-Fi 应该如何搭建?
  9. 初次使用nginx 搭建http2.0
  10. java 发送邮件带附件
  11. java判断是否失效_java – 如何在输入有效之前检查无效输入和循环?
  12. 享元模式在 Java String 中的应用
  13. RSA算法的Java实现
  14. Fiddler 4监听手机数据
  15. 内存卡数据恢复,如何从内存卡恢复数据
  16. 怎样把文件转成bt文件?
  17. JavaScript推箱子游戏开发笔记
  18. HTML学生个人网站作业设计:电影网站设计——电影动漫言叶之庭(4页) HTML+CSS+JavaScript 简单DIV布局个人介绍网页模板代码 DW学生个人网站制作成品下载
  19. GALAXY OJ NOIP2019联合测试2-普及组
  20. [Tushare]使用分享

热门文章

  1. 怎么让win10隐藏任务栏不会在程序有消息时自动弹出
  2. 拓尔思信息科技股份有限公司2019校园春季招聘
  3. Ubuntu 18.04 新手教程_火狐浏览器flash插件安装
  4. 无线蜂窝通信模组是什么?
  5. 微信小游戏保存自定义分享图到相册实例
  6. C++中的开辟/释放动态空间new/delete
  7. echarts城市地图加标注
  8. ciscn_2019_n_4
  9. 【转】《与MySQL的零距离接触》第四章:操作数据表中的记录 (4-2:MySQL 插入记录INSERT)
  10. 压敏电阻原理、参数、选型