TypeError: img should be PIL Image. Got <class ‘dict‘>/Got<class ‘Torch.Tensor‘>/Got<class ‘numpy.n>

代码运行至下列语句时:

for i, data in enumerate(train_loader):

有时会遇到以下三种报错:

TypeError: img should be PIL Image. Got <class 'dict'>
TypeError: img should be PIL Image. Got <class 'Torch.Tensor'>
TypeError: img should be PIL Image. Got <class 'numpy.ndarray'>

这类问题往往出错在 datasetgetitem 函数处,因为这里涉及到对数据做 transformtransform 中又涉及到一些图像转换的问题。

class Resize(object):
    """Resize the input PIL Image to the given size.

    Args:
        size (sequence or int): Desired output size. If size is a sequence like
            (h, w), output size will be matched to this. If size is an int,
            smaller edge of the image will be matched to this number.

            i.e, if height > width, then image will be rescaled to
            (size * height / width, size)
        interpolation (int, optional): Desired interpolation. Default is
            .Image.BILINEAR
"""

    def __init__(self, size, interpolation=Image.BILINEAR):
        assert isinstance(size, int) or (isinstance(size, Iterable) and len(size) == 2)
        self.size = size
        self.interpolation = interpolation

    def __call__(self, img):
"""
        Args:
            img (PIL Image): Image to be scaled.

        Returns:
            PIL Image: Rescaled image.

"""
        return F.resize(img, self.size, self.interpolation)

    def __repr__(self):
        interpolate_str = _pil_interpolation_to_str[self.interpolation]
        return self.__class__.__name__ + '(size={0}, interpolation={1})'.format(self.size, interpolate_str)

我们来看 call() 方法,这里有几行注释,大致意思是, call 方法接受一个 PIL Image 格式的输入,经过 resize 方法后 返回一个 PIL Image 格式的输出,也就是说, pytorch 官方 中的 transform 默认是需要一个 PIL Image 格式输入的 。而有很多朋友会采用不同的方式读取 image ,比如使用 cv2.imread() 函数,我们可以来测试一下:

import cv2

img = cv2.imread('data/davis2016/JPEGImages/480p/train/00000.jpg')
type(img)

可以看见,使用 cv2.imread 函数读取的 imagenumpy.ndarray 格式的,这时候如果直接对这个 imagetransform 就会出现类型不匹配问题,这时候,需要在你写的 train_transform 中加一个 transform.ToPILImage() 函数,例如:

train_transforms = t.Compose([t.ToPILImage(),
                              t.RandomHorizontalFlip(),
                              t.Resize((480, 852)),
                              t.ToTensor()])

依次可以类推, transform.Compose() 方法其实就是把一系列我们要对 image 做的操作(数据预处理,数据增强等)排列到一起,因此,我们要保证其从第一个函数到最后一个函数的输入都要是 PIL Image 格式。那些遇见错误的同学,要么是没有将 PIL Image 格式的图像做为 transform.Compose() 方法输入,要么是虽然输入了 PIL Image 格式图像,但是在一些列操作未结束之前就将其转为了 Tensor,见下列代码:

train_transforms = t.Compose([t.ToPILImage(),
                              t.RandomHorizontalFlip(),
                              t.ToTensor(),
                              t.Resize((480, 852))])

这时,不用运行,我们就知道,这里肯定出错了,因为刚刚我们验证过 transform.Resize()call 方法需要接受一个 PIL Image 格式的图像,而你提前使用了 transform.ToTensor() 方法将其转为了 torch.Tensor 格式,这就肯定错了。

TypeError: img should be PIL Image. Got <class 'numpy.ndarray'>

你应该检查你的图像是否为 PIL Image 格式,如果不是,可以使用 transform.ToPILImage() 方法。

TypeError: img should be PIL Image. Got <class 'Torch.Tensor'>

你应该检查你的 transform.ToTensor() 方法是否写在了你要做的操作之前,如果是,调换一下它们的位置。

TypeError: img should be PIL Image. Got <class 'dict'>

这个应该很少有人会遇见,这是我需要将一个 img 和它的 gt 做为一个字典一起返回的时候遇见的一个错误:

    def __getitem__(self, idx):
        img = readImage(self.img_list[idx], channel=3)
        gt = readImage(self.mask_list[idx], channel=1)
        sample = {'images': img, 'gts': gt}

        if self.transform is not None:
            sample = self.transform(sample)

        return sample

解决方法是,先分别对 imggttransform 再把它们组合到一个字典里:

    def __getitem__(self, idx):
        img = readImage(self.img_list[idx], channel=3)
        gt = readImage(self.mask_list[idx], channel=1)

        if self.transform is not None:
            img = self.transform(img)
            gt = self.transform(gt)

        sample = {'images': img, 'gts': gt}

        return sample
import PIL.Image
def readImage(img_path, channel=3):
    """Keep reading image until succeed.

    This can avoid IOError incurred by heavy IO process."""
    got_img = False
    if not os.path.exists(img_path):
        raise IOError("{} does not exist".format(img_path))
    while not got_img:
        if channel == 3:
            try:
                img = Image.open(img_path).convert('RGB')
                got_img = True
            except IOError:
                print("IOError incurred when reading '{}'. Will redo. Don't worry. Just chill.".format(img_path))
                pass
        elif channel == 1:
            try:
                img = Image.open(img_path).convert('1')
                got_img = True
            except IOError:
                print("IOError incurred when reading '{}'. Will redo. Don't worry. Just chill.".format(img_path))
                pass
    return img
train_transforms = t.Compose([t.RandomHorizontalFlip(),
                              t.Resize((480, 852)),
                              t.ToTensor()])

注意: transform.ToTensor() 最好写在最后。

ps:其实…也有一些方法(例如,随即擦除,标准化等)不需要输入格式为 PIL.Image,下面这样写是可以的:

    transform_train = T.Compose([
        T.Random2DTranslation((256, 128)),
        T.RandomHorizontalFlip(),
        T.ToTensor(),
        T.RandomErasing(),
        T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
    ])

具体情况还是要自己多试一试,多去看看官方的写法。

Original: https://blog.csdn.net/weixin_43793510/article/details/120564907
Author: InactionWorld
Title: TypeError: img should be PIL Image. Got <class ‘dict‘>/Got<class ‘Torch.Tensor‘>/Got<class ‘numpy.n>

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/757605/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 机器学习Numpy库入门25例

    导入numpy import numpy as np 打印numpy的版本和配置信息 print(np.version) <module ‘numpy.version’ fr…

    Python 2023年8月27日
    026
  • python可视化动态图表: 关于pyecharts的sankey桑基图绘制

    最近因工作原因,需要处理一些数据,顺便学习一下动态图表的绘制。本质是使具有源头的流动信息能够准确找到其上下级关系和流向。 数据来源是csv文件 导入成为dataframe之后,列为…

    Python 2023年6月3日
    079
  • Django 简介和版本介绍

    一、简介 官方地址:https://www.djangoproject.com Django 是一个由Python 编写的具有完整架站能力的开源Web框架。使用 Django,只要…

    Python 2023年11月1日
    036
  • 佳缘线上超市网站

    成品详细信息 开发工具(eclipse/idea/vscode等):数据库(sqlite/mysql/sqlserver等):功能模块(请用文字描述,至少200字): 基于SPRI…

    Python 2023年10月7日
    035
  • 场景之多数据源查询及数据下载问题

    前言:本文将介绍常用后台功能中的数据获取以及下载的一些注意事项和实现。 承接上文数据分页查询当通过分页查询到数据之后,接着还会遇到其他需求: 继续其他数据源查询:分页查询到的数据并…

    Python 2023年6月16日
    089
  • 天呐,我居然可以隔空作画了

    摘要:本案例将使用YOLOX、SCNet两个模型,实现一个简单的隔空作画趣味应用 本文分享自华为云社区《ModelBox开发案例 – 隔空作画》,作者:吴小鱼。 本案例…

    Python 2023年10月29日
    034
  • django中的request对象方法

    1.什么是request对象 在django中,当一个页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象;Django会将这个对象自动传递给响应的…

    Python 2023年11月1日
    057
  • windows下conda pycharm pip联用方法

    文章目录 * – conda配置【以下操作都在anaconda PowerShell Prompt】: – + 1. 常用指令 + 2. 配置文件 + 3….

    Python 2023年9月9日
    059
  • JDK8中String的intern()方法详细解读【内存图解+多种例子+1.1w字长文】

    一、前言 String字符串在我们日常开发中最常用的,当然还有他的两个兄弟 StringBuilder&#x548C;StringBuilder。他三个的区别也是面试中经常…

    Python 2023年10月21日
    048
  • 序章-准备工作

    为什么选择自己开发一个词典 市面上的词典都不太彳亍,有Golden Dict和欧陆词典这类注重词典文件的,有有道词典这类电子词典,前者对于查词更偏向于内容整合,后者则是释义与例句。…

    Python 2023年10月30日
    045
  • python+scrapy+MongoDB爬取网站数据

    假设前置条件:个人PC安装好python、scrapy、MongoDB等环境 1.创建项目 scrapy startproject tutorial 创建完后的文件夹如下: 其中红…

    Python 2023年10月4日
    042
  • Python 学习笔记(五)

    我们经常需要从文件读取数据或向文件写入数据,但要做到这一点,我们需要检查文件是否存在。 [En] We often need to read data from or write …

    Python 2023年5月25日
    055
  • 自动化测试练手项目推荐

    转载请注明出处❤️ 作者:测试蔡坨坨 原文链接:caituotuo.top/80599ac8.html 你好,我是测试蔡坨坨。 最近收到许多自学自动化测试的小伙伴私信,学习了理论知…

    Python 2023年10月20日
    057
  • scrapy 自定义UA、代理中间件

    中间件(代理、UA) 我自己编写了一个IP池子,代理IP放在redis当中,需要在请求的时候从redis当中随机获取到一条代理IP(我有两个代理池环境 一个正式环境一个测试环境 如…

    Python 2023年10月3日
    088
  • Python基础PTA习题答案

    文章目录 一、前言 二、函数题 * 4-1 jmu-python-函数-找钱 4-2 缩写词 4-3 使用函数求素数和 4-4 使用函数输出指定范围内Fibonacci数的个数 三…

    Python 2023年8月1日
    01.4K
  • 使用阿里云OSS给图片添加水印

    一、需求。 1.1、Laravel下给图片添加水印; 二、分析。 2.1、给图片添加水印,一个是可以用PHP的GD库处理,Laravel下可以直接通过Composer安装别人写好的…

    Python 2023年6月12日
    0171
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球