将PNG文件导入Numpy?

Posted

技术标签:

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

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

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

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

【问题讨论】:

【参考方案1】:

根据doc,scipy.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 library 的Image 类来完成:

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())。

【讨论】:

以上是关于将PNG文件导入Numpy?的主要内容,如果未能解决你的问题,请参考以下文章

如何将数组从.txt文件导入到numpy数组?

将 bz2 压缩二进制文件导入为 numpy 数组

cx_freeze 将项目构建为 .exe 文件,出现 numpy 导入错误

如何在python中将csv文件导入为numpy.array? [复制]

Java:如何用导入的 PNG 文件替换“椭圆”或“矩形”图形?

python怎么导入库包?