【问题标题】:Importing PNG files into Numpy?将PNG文件导入Numpy?
【发布时间】:2015-10-01 21:04:57
【问题描述】:

我在这样的目录中存储了大约 200 张灰度 PNG 图像。

1.png
2.png
3.png
...
...
200.png

我想将所有 PNG 图像导入为 NumPy 数组。 我该怎么做?

【问题讨论】:

    标签: python image numpy png


    【解决方案1】:

    根据docscipy.misc.imread 从 SciPy 1.0.0 开始已被弃用,并将在 1.2.0 中删除。考虑改用imageio.imread

    例子:

    import imageio
    
    im = imageio.imread('my_image.png')
    print(im.shape)
    

    您还可以使用 imageio 从精美的来源加载:

    im = imageio.imread('http://upload.wikimedia.org/wikipedia/commons/d/de/Wikipedia_Logo_1.0.png')
    

    编辑:

    要加载特定文件夹中的所有*.png 文件,您可以使用glob 包:

    import imageio
    import glob
    
    for im_path in glob.glob("path/to/folder/*.png"):
         im = imageio.imread(im_path)
         print(im.shape)
         # do whatever with the image here
    

    【讨论】:

    • 投反对票的人,如果您能告诉我需要改进的地方,请帮助我改进这个答案,我们将不胜感激!
    • 我不是downvoter,但问题是在文件夹中加载图像列表。您能否修改您的答案以反映这一点,而不仅仅是 1 - 200.png,但如果 png 具有随机名称怎么办,这将对我有很大帮助。我确定我可以使用osls 并获取文件名,但有更好的方法吗?也许你应该编辑添加glob
    • 另外,记得添加一个 try catch,因为 imread 可能会抛出 ValueError。我没有编辑权限,否则我会为您更新它。 :)
    • 开发人员应该选择是否在这种情况下引发异常并停止执行或以特定方式处理。没有上下文,加注是首选。
    • 好吧,glob 仅在目录树中找到与某个“通配符”路径(可以包含通配符等)匹配的文件,所以我不确定您所说的“无效 png”是什么意思glob 会忽略错误”,因为 glob 只查看文件名,而对您的图像一无所知。
    【解决方案2】:

    仅使用 scipy、glob 并安装 PIL (pip install pillow),您可以使用 scipy 的 imread 方法:

    from scipy import misc
    import glob
    
    for image_path in glob.glob("/home/adam/*.png"):
        image = misc.imread(image_path)
        print image.shape
        print image.dtype
    

    更新

    根据文档,从 SciPy 1.0.0 开始不推荐使用 scipy.misc.imread,并将在 1.2.0 中删除。考虑使用imageio.imread instead。见the answer by Charles

    【讨论】:

    • 改成glob.glob("./train/*.png")
    【解决方案3】:

    这也可以通过PIL libraryImage 类来完成:

    from PIL import Image
    import numpy as np
    
    im_frame = Image.open(path_to_file + 'file.png')
    np_frame = np.array(im_frame.getdata())
    

    注意:.getdata() 可能不需要 - np.array(im_frame) 也应该可以工作

    【讨论】:

    • 我认为甚至不需要.getdata()np.array(im_frame) 也应该可以工作。
    • 感谢您的贡献:我将您的评论作为评论添加到我的答案中以突出显示。
    • 我投了赞成票,但是 .getdata() 导致错误,所以必须在没有 .getdata() 的情况下使用(Rob 的方法),两个代码都不一样! : raise TypeError('Input type {} is not supported'.format(npimg.dtype)) TypeError: Input type int64 is not supported
    • 您的输入类型似乎有问题。
    【解决方案4】:

    首选使用(非常)常用的包:

    import matplotlib.pyplot as plt
    im = plt.imread('image.png')
    

    【讨论】:

    • 我大部分时间已经导入了matplotlib,所以这个基本没有额外费用。 matplotlib 不总是有 imread 什么的吗?其他答案中使用的包有什么优势?
    【解决方案5】:

    如果您正在加载图像,您可能会使用matplotlibopencv 之一或两者来操作和查看图像。

    出于这个原因,我倾向于使用他们的图像阅读器并将它们附加到列表中,我从中创建一个 NumPy 数组。

    import os
    import matplotlib.pyplot as plt
    import cv2
    import numpy as np
    
    # Get the file paths
    im_files = os.listdir('path/to/files/')
    
    # imagine we only want to load PNG files (or JPEG or whatever...)
    EXTENSION = '.png'
    
    # Load using matplotlib
    images_plt = [plt.imread(f) for f in im_files if f.endswith(EXTENSION)]
    # convert your lists into a numpy array of size (N, H, W, C)
    images = np.array(images_plt)
    
    # Load using opencv
    images_cv = [cv2.imread(f) for f in im_files if f.endswith(EXTENSION)]
    # convert your lists into a numpy array of size (N, C, H, W)
    images = np.array(images_cv)
    

    需要注意的唯一区别如下:

    • opencv 加载频道首先
    • matplotlib 加载频道最后

    因此,大小为 256*256 的单个图像将使用 opencv 生成大小为 (3, 256, 256) 的矩阵,使用 matplotlib 生成 (256, 256, 3) 大小的矩阵。

    【讨论】:

      【解决方案6】:

      我做了一点改动,它就像这样工作,转储到一个数组中,前提是所有图像都具有相同的尺寸。

      png = []
      for image_path in glob.glob("./train/*.png"):
          png.append(misc.imread(image_path))    
      
      im = np.asarray(png)
      
      print 'Importing done...', im.shape
      

      【讨论】:

      • 完美。伟大的多合一解决方案。我已将图像存储到 np.array 中,但随后遇到了麻烦,因为数组具有 (shape == (num_images,) 与每个图像 (shape == (32,32,3))。您的解决方案(加上 im = np.reshape(num_images,32,32,3)效果很好!:-)
      • 错字:我什至不需要上面的 reshape 调用。在我烦恼的黑客中,将其按摩成所需的形状变得很乱。感谢您的直接路径。
      【解决方案7】:

      我喜欢内置的 pathlib 库,因为有 directory= Path.cwd() 这样的快速选项 与 opencv 一起,将 pngs 读取到 numpy 数组非常容易。 在此示例中,您甚至可以检查图像的前缀。

      from pathlib import Path
      import cv2
      prefix = "p00"
      suffix = ".png"
      directory= Path.cwd()
      file_names= [subp.name for subp in directory.rglob('*') if  (prefix in subp.name) & (suffix == subp.suffix)]
      file_names.sort()
      print(file_names)
      
      all_frames= []
      for file_name in file_names:
          file_path = str(directory / file_name)
          frame=cv2.imread(file_path)
          all_frames.append(frame)
      print(type(all_frames[0]))
      print(all_frames[0] [1][1])
      

      输出:

      ['p000.png', 'p001.png', 'p002.png', 'p003.png', 'p004.png', 'p005.png', 'p006.png', 'p007.png', 'p008.png', 'p009.png']
      <class 'numpy.ndarray'>
      [255 255 255]
      

      【讨论】:

        【解决方案8】:

        读取一张图片:

        im = PIL.Image.open('path/to/your/image')
        im = np.array(im)
        

        迭代读取多个图像。

        这类似于this,但更简单(不需要.getdata())。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-03-25
          • 2021-12-13
          • 1970-01-01
          • 2020-03-22
          • 1970-01-01
          • 2019-08-03
          • 2019-03-25
          • 1970-01-01
          相关资源
          最近更新 更多