以单通道(灰度图)加载图片

如果我们想以单通道加载图片,设置加载数据集时的transform参数如下即可:

from torchvision import datasets, transforms
transform = transforms.Compose(
[ transforms.Grayscale(num_output_channels=1),
transforms.ToTensor()
]
)
data = datasets.CIFAR10(root=".", download=True,transform=transform)
print(type(data[0][0])) # <class 'torch.Tensor'>
print(data[0][0].shape) # torch.Size([1, 32, 32])
print(data[0][0])
# tensor([[[0.2392, 0.1765, 0.1882, ..., 0.5373, 0.5098, 0.5059],
# [0.0745, 0.0000, 0.0392, ..., 0.3725, 0.3529, 0.3686],
# [0.0941, 0.0353, 0.1216, ..., 0.3529, 0.3569, 0.3137],
# ...,
# [0.6784, 0.6039, 0.6157, ..., 0.5255, 0.1412, 0.1490],
# [0.5725, 0.5059, 0.5647, ..., 0.6000, 0.2706, 0.2353],
# [0.5922, 0.5373, 0.5765, ..., 0.7412, 0.4863, 0.3882]]])

可以看到我们得到了归一化后的单通道torch.Tensor对象。

PS:torch.Tensor对象可以以torch.tensor(...)torch.Tensor(...)两种方法初始化得到的,具体区别在于torch.Tensor(...)可接受多个参数,其参数表示Tensor各个维度的大小,比如torch.Tensor会返回一个为已初始化的存有10个数(类型为torch.float32)的Tensor对象,而torch.tensor(10)只能接受一个参数,该参数表示初始化的数据,比如torch.tensor(10)会返回一个包含单个值10(类型为torch.int64)的Tensor对象:

import torch

a = torch.Tensor(10)
print(a)
# tensor([0.0000e+00, 0.0000e+00, 0.0000e+00, 3.6734e-40, 0.0000e+00, 2.0000e+00,
# 0.0000e+00, 2.0000e+00, 7.3787e+2])
print(type(a)) # <class 'torch.Tensor'>
print(a.dtype) # torch.float32 b = torch.tensor(10)
print(b) # tensor(10)
print(type(b)) # <class 'torch.Tensor'>
print(b.dtype) # torch.int64 a = torch.Tensor(2, 3)
print(a)
# tensor([[1.6217e-19, 7.0062e+22, 6.3828e+28],
# [3.8016e-39, 0.0000e+00, 2.0000e+00]]) b = torch.tensor([2, 3])
print(b) # tensor([2, 3])
b = torch.tensor((2, 3))
print(b) # tensor([2, 3])

详情可参见Pytorch讨论区帖子:Difference between torch.tensor() and torch.Tensor()[1]

这里再多说一点,这里的transforms.ToTensor()接收PIL格式的数据, 或者是直接从PIL转来的np.ndarray格式数据, 只要保证进来的数据取值范围是[0, 255], 格式是HWC(H、W、C分别对应图片高度、宽度、通道数,这也就是我们在日常生活中存储图片的常用顺序), 像素顺序是RGB, 它就会帮我们完成下列的工作:

  • 取值范围[0, 255] / 255.0 => [0, 1.0], 数据格式从uint8变成了torch.float32
  • 形状(shape)转为CHW,但像素顺序依旧是RGB。

比如如果不加transforms.ToTensor(),就会直接得到PIL格式的图片:

from torchvision import datasets, transforms
import numpy as np transform = transforms.Compose(
[
transforms.Grayscale(num_output_channels=1),
]
)
data = datasets.CIFAR10(root=".", download=True,transform=transform) img = data[0][0]
print(type(img)) # <class 'PIL.Image.Image'>

然后我们可以尝试先将PIL.Image.Image对象转为np.ndarray,然后再转为torch.Tensor类型的对象:

np_img = np.asarray(img)
print(np_img.dtype) # uint8
tensor_from_np = transforms.ToTensor()(np_img)
print(type(tensor_from_np)) # <class 'torch.Tensor'>
print(tensor_from_np.dtype) # torch.float32
print(tensor_from_np.shape) # torch.Size([1, 32, 32])
print(tensor_from_np)
# tensor([[[0.2392, 0.1765, 0.1882, ..., 0.5373, 0.5098, 0.5059],
# [0.0745, 0.0000, 0.0392, ..., 0.3725, 0.3529, 0.3686],
# [0.0941, 0.0353, 0.1216, ..., 0.3529, 0.3569, 0.3137],
# ...,
# [0.6784, 0.6039, 0.6157, ..., 0.5255, 0.1412, 0.1490],
# [0.5725, 0.5059, 0.5647, ..., 0.6000, 0.2706, 0.2353],
# [0.5922, 0.5373, 0.5765, ..., 0.7412, 0.4863, 0.3882]]])

PS: 最后再提一下Tensorflow,Tensorflow虽然调用的tf.keras.datasets.cifar10.load_data()能直接得到类型为numpy.ndarray并按照HWC顺序存储的数据,但是需要手动去添加/255以对数据归一化,如下所示:

import tensorflow as tf
import numpy as np
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
print(type(x_train)) # <class 'numpy.ndarray'>
print(x_train.shape) # (50000, 32, 32, 3)
print(x_train)
# [[[[ 59 62 63]
# [ 43 46 45]
# [ 50 48 43]
# ...
# [179 177 173]
# [164 164 162]
# [163 163 161]]]]
x_train = x_train.astype(np.float32) / 255.0
print(x_train)
# [[[[0.23137255 0.24313726 0.24705882]
# [0.16862746 0.18039216 0.1764706 ]
# [0.19607843 0.1882353 0.16862746]
# ...
# [0.7019608 0.69411767 0.6784314 ]
# [0.6431373 0.6431373 0.63529414]
# [0.6392157 0.6392157 0.6313726 ]]]]

参考

Pytorch:以单通道(灰度图)加载图片的更多相关文章

  1. Caffe python利用classify.py实现对单通道(灰度图)的数据进行分类

    比如你在mnist的prototxt中定义图输入是单通道的,也就是channel=1,然后如果直接调用classify.py脚本来测试的话,是会报错,错误跟一下类似. Source param sha ...

  2. SDL2.0的加载图片贴图

    加载图片贴图,采用了SDL_Window.SDL_Renderer.SDL_Texture和SDL_Image库 实例: #include <stdio.h> #include <m ...

  3. RX系列四 | RxAndroid | 加载图片 | 提交表单

    RX系列四 | RxAndroid | 加载图片 | 提交表单 说实话,学RxJava就是为了我们在Android中运用的更加顺手一点,也就是RxAndroid,我们还是先一步步来,学会怎么去用的比较 ...

  4. swift -- 单例+ lazy懒加载 + 第三方库

    //工具类单例 static let goods : NHGoods = { let good = NHGoods() return good }() //懒加载 lazy var registerB ...

  5. vue第七单元(vue的单文件组件形式-单文件组件的加载原理-vue-cli构建的开发环境以及生命周期)

    第七单元(vue的单文件组件形式-单文件组件的加载原理-vue-cli构建的开发环境以及生命周期) #课程目标 掌握安装 vue-cli 命令行工具的方法,掌握使用命令行在本地搭建开发环境,使用命令行 ...

  6. Listview 异步加载图片之优化篇(有图有码有解释)

    在APP应用中,listview的异步加载图片方式能够带来很好的用户体验,同时也是考量程序性能的一个重要指标.关于listview的异步加载,网上其实很多示例了,中心思想都差不多,不过很多版本或是有b ...

  7. jquery实现表单验证与页面加载之后执行渲染

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. BitmapFactory 加载图片到内存

    Bitmap占用内存分析 Android的虚拟机是基于寄存器的Dalvik,它的最大堆(单个进程可用内存)大小一般是16M,当然不同设备是不一样的,可以查看/system/build.prop文件,[ ...

  9. android 加载图片框架--Glide使用详解

    一.简介 Glide,一个被google所推荐的图片加载库,作者是bumptech.这个库被广泛运用在google的开源项目中,包括2014年的google I/O大会上发布的官方app.(PS:众所 ...

  10. Glide 加载图片

    //通过model获取到图片的url,将Url转换成bitmap对象: //设置不保存内存和硬盘缓存, 1 Glide.with(mContext).load(model.getVideoUrl()) ...

随机推荐

  1. 在nginx中使用proxy protocol协议

    目录 简介 proxy protocol在nginx中应用 在nginx中配置使用proxy protocol 在nginx中启用proxy protocol 使用Real‑IP modules 请求 ...

  2. Python 变量:创建、类型、命名规则和作用域详解

    变量 变量是用于存储数据值的容器. 创建变量 Python没有用于声明变量的命令. 变量在您第一次为其分配值时被创建. 示例 x = 5 y = "John" print(x) p ...

  3. 报表格式太难?一文教你Excel融合分析

    Excel是我们最经常使用的处理报表工具了,尤其是金融行业更是需要天天和报表打交道.但是Excel有一个问题,如果面对的数据庞杂,则处理起来就会相当麻烦,当需要从多个数据源获取数据来制作一个报表时,这 ...

  4. 玩转HarmonyOS专项测试,轻松上架“五星”高品质应用

      作者:David,华为测试服务专家 随着信息技术的高速发展,移动应用与人们生活日益紧密,面向各类场景的应用层出不穷,什么样的应用更受用户青睐呢?在满足用户功能需求之上,一个好的应用要能运行稳定.流 ...

  5. HarmonyOS如何使用异步并发能力进行开发

      一.并发概述 并发是指在同一时间段内,能够处理多个任务的能力.为了提升应用的响应速度与帧率,以及防止耗时任务对主线程的干扰,HarmonyOS系统提供了异步并发和多线程并发两种处理策略. ● 异步 ...

  6. HarmonyOS API Version 7版本特性说明

    2020年9月11日,HarmonyOS SDK发布了首个Beta版本,支持基于HarmonyOS的华为智慧屏.智能穿戴.车机设备开发,让广大的开发者正式步入了HarmonyOS应用开发之旅. 开发者 ...

  7. Mysql之SQL语句初级用法

    前言 本文通过简单的示例去了解Mysql的DDL.DML.DCL的语句用法. 一.DDL语句 DDL(Data Definition Language)语句: 数据定义语言,主要是进行定义/改变表的结 ...

  8. lowdb 在electron 使用中注意的问题

    前言 可能很多人都没有听说过这个lowdb,但是它的确存在,而且在electron 中用到还是挺多的. 如何在electron 的render 进程中是引用electron 模块. 我们知道一个问题, ...

  9. 【Azure Developer】.Net 简单示例 "文字动图显示" Typing to SVG

    问题描述 看见一个有趣的页面,可以把输入的文字信息,直接输出SVG图片,还可以实现动图模式. 示例URL:  https://readme-typing-svg.demolab.com/?font=F ...

  10. OS如何保持对计算机的控制权?

    前面我们提到:OS希望在保持控制权的同时,为用户提供高性能的并发. 那么OS究竟是如何保持对计算机的控制权呢?这似乎是一个令人迷惑(但很重要!)的问题:OS也是进程,自然也需要计算资源.那既然我们希望 ...