358

我有一个 Numpy 数组类型的矩阵。我如何将它作为图像写入磁盘?任何格式都有效(png、jpeg、bmp...)。一个重要的限制是不存在 PIL。

4

20 回答 20

363

使用PIL的答案(以防万一它有用)。

给定一个 numpy 数组“A”:

from PIL import Image
im = Image.fromarray(A)
im.save("your_file.jpeg")

您可以用几乎任何您想要的格式替换“jpeg”。有关格式的更多详细信息,请点击此处

于 2011-12-16T18:21:39.423 回答
273

这使用了 PIL,但也许有些人会觉得它很有用:

import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)

编辑:当前scipy版本开始对所有图像进行规范化,以便 min(data) 变为黑色,max(data) 变为白色。如果数据应该是精确的灰度级或精确的 RGB 通道,则这是不需要的。解决方案:

import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
于 2009-11-11T04:53:29.880 回答
113

matplotlib

import matplotlib

matplotlib.image.imsave('name.png', array)

适用于 matplotlib 1.3.1,我不知道低版本。从文档字符串:

Arguments:
  *fname*:
    A string containing a path to a filename, or a Python file-like object.
    If *format* is *None* and *fname* is a string, the output
    format is deduced from the extension of the filename.
  *arr*:
    An MxN (luminance), MxNx3 (RGB) or MxNx4 (RGBA) array.

在此处输入图像描述

于 2014-04-02T21:51:28.380 回答
78

opencvpython(文档here)。

import cv2
import numpy as np

img = ... # Your image as a numpy array 

cv2.imwrite("filename.png", img)

如果您需要进行除保存以外的更多处理,这很有用。

于 2014-11-24T23:10:45.907 回答
71

纯 Python (2 & 3),一个没有 3rd 方依赖的片段。

此函数写入压缩的真彩色(每像素 4 个字节)RGBAPNG。

def write_png(buf, width, height):
    """ buf: must be bytes or a bytearray in Python3.x,
        a regular string in Python2.x.
    """
    import zlib, struct

    # reverse the vertical line order and add null bytes at the start
    width_byte_4 = width * 4
    raw_data = b''.join(
        b'\x00' + buf[span:span + width_byte_4]
        for span in range((height - 1) * width_byte_4, -1, - width_byte_4)
    )

    def png_pack(png_tag, data):
        chunk_head = png_tag + data
        return (struct.pack("!I", len(data)) +
                chunk_head +
                struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head)))

    return b''.join([
        b'\x89PNG\r\n\x1a\n',
        png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)),
        png_pack(b'IDAT', zlib.compress(raw_data, 9)),
        png_pack(b'IEND', b'')])

...数据应直接写入以二进制形式打开的文件,如下所示:

data = write_png(buf, 64, 64)
with open("my_image.png", 'wb') as fh:
    fh.write(data)

于 2013-10-04T06:33:01.610 回答
65

您可以使用PyPNG。它是一个纯 Python(无依赖项)开源 PNG 编码器/解码器,它支持将 NumPy 数组编写为图像。

于 2009-05-24T00:26:05.093 回答
32

如果你有 matplotlib,你可以这样做:

import matplotlib.pyplot as plt
plt.imshow(matrix) #Needs to be in row,col order
plt.savefig(filename)

这将保存绘图(而不是图像本身)。 在此处输入图像描述

于 2009-06-10T17:29:37.580 回答
24

要将 numpy 数组保存为图像,U 有几种选择:

1)最好的:OpenCV

 import cv2   
 cv2.imwrite('file name with extension(like .jpg)', numpy_array)

2) Matplotlib

  from matplotlib import pyplot as plt
  plt.imsave('file name with extension(like .jpg)', numpy_array)

3) 太平

  from PIL import Image
  image = Image.fromarray(numpy_array)
  image.save('file name with extension(like .jpg)')

4) ...

于 2020-06-14T04:17:36.280 回答
19

scipy.misc给出关于函数的弃用警告imsave并建议使用 of imageio

import imageio
imageio.imwrite('image_name.png', img)
于 2018-08-25T09:38:46.030 回答
18

您可以在 Python 中使用“skimage”库

例子:

from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
于 2018-03-11T14:02:48.347 回答
13

@ideasman42 答案的附录:

def saveAsPNG(array, filename):
    import struct
    if any([len(row) != len(array[0]) for row in array]):
        raise ValueError, "Array should have elements of equal size"

                                #First row becomes top row of image.
    flat = []; map(flat.extend, reversed(array))
                                 #Big-endian, unsigned 32-byte integer.
    buf = b''.join([struct.pack('>I', ((0xffFFff & i32)<<8)|(i32>>24) )
                    for i32 in flat])   #Rotate from ARGB to RGBA.

    data = write_png(buf, len(array[0]), len(array))
    f = open(filename, 'wb')
    f.write(data)
    f.close()

所以你可以这样做:

saveAsPNG([[0xffFF0000, 0xffFFFF00],
           [0xff00aa77, 0xff333333]], 'test_grid.png')

生产test_grid.png

红色、黄色、深水蓝色、灰色的网格

(透明度也可以通过减少 . 的高字节来实现0xff。)

于 2014-01-10T00:33:20.280 回答
11

对于那些寻找直接完整工作示例的人:

from PIL import Image
import numpy

w,h = 200,100
img = numpy.zeros((h,w,3),dtype=numpy.uint8) # has to be unsigned bytes

img[:] = (0,0,255) # fill blue

x,y = 40,20
img[y:y+30, x:x+50] = (255,0,0) # 50x30 red box

Image.fromarray(img).convert("RGB").save("art.png") # don't need to convert

另外,如果您想要高质量的 jpeg
.save(file, subsampling=0, quality=100)

于 2018-12-27T03:27:14.087 回答
6

matplotlib svn 有一个新功能,可以将图像保存为图像 - 没有轴等。如果您不想安装 svn(直接从 matplotlib svn 中的 image.py 复制,删除了为简洁起见的文档字符串):

def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None, origin=None):
    from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
    from matplotlib.figure import Figure

    fig = Figure(figsize=arr.shape[::-1], dpi=1, frameon=False)
    canvas = FigureCanvas(fig)
    fig.figimage(arr, cmap=cmap, vmin=vmin, vmax=vmax, origin=origin)
    fig.savefig(fname, dpi=1, format=format)
于 2009-06-10T21:43:06.447 回答
5

Imageio是一个 Python 库,它提供了一个简单的界面来读取和写入各种图像数据,包括动画图像、视频、体积数据和科学格式。它是跨平台的,在 Python 2.7 和 3.4+ 上运行,并且易于安装。

这是灰度图像的示例:

import numpy as np
import imageio

# data is numpy array with grayscale value for each pixel.
data = np.array([70,80,82,72,58,58,60,63,54,58,60,48,89,115,121,119])

# 16 pixels can be converted into square of 4x4 or 2x8 or 8x2
data = data.reshape((4, 4)).astype('uint8')

# save image
imageio.imwrite('pic.jpg', data)
于 2019-01-12T09:32:34.977 回答
4

世界可能不需要另一个包来将 numpy 数组写入 PNG 文件,但对于那些无法获得足够的人,我最近numpngw在 github 上提出:

https://github.com/WarrenWeckesser/numpngw

在 pypi 上:https ://pypi.python.org/pypi/numpngw/

唯一的外部依赖是 numpy。

examples这是存储库目录中的第一个示例。基本线很简单

write_png('example1.png', img)

哪里img是一个 numpy 数组。该行之前的所有代码都是导入语句和要创建的代码img

import numpy as np
from numpngw import write_png


# Example 1
#
# Create an 8-bit RGB image.

img = np.zeros((80, 128, 3), dtype=np.uint8)

grad = np.linspace(0, 255, img.shape[1])

img[:16, :, :] = 127
img[16:32, :, 0] = grad
img[32:48, :, 1] = grad[::-1]
img[48:64, :, 2] = grad
img[64:, :, :] = 127

write_png('example1.png', img)

这是它创建的PNG文件:

例子1.png

另外,我曾经在曼哈顿度量numpngw.write_apng的 Voronoi 图中创建动画。

于 2015-09-29T20:56:04.150 回答
3

假设您想要灰度图像:

im = Image.new('L', (width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
于 2017-05-02T08:05:05.113 回答
1

如果您碰巧已经使用 [Py]Qt,您可能会对qimage2ndarray感兴趣。从 1.4 版(刚刚发布)开始,也支持 PySide,并且会有一个imsave(filename, array)类似于 scipy 的小功能,但使用 Qt 而不是 PIL。在 1.3 中,只需使用如下内容:

qImage = array2qimage(image, normalize = False) # create QImage from ndarray
success = qImage.save(filename) # use Qt's image IO functions for saving PNG/JPG/..

(1.4 的另一个优点是它是一个纯 python 解决方案,这使得它更加轻量级。)

于 2014-08-19T06:46:08.333 回答
1

如果您在 python 环境 Spyder 中工作,那么只需右键单击变量资源管理器中的数组,然后选择“显示图像”选项,再简单不过了。

在此处输入图像描述

这将要求您将图像保存到 dsik,主要是 PNG 格式。

在这种情况下将不需要 PIL 库。

于 2018-07-02T07:05:54.073 回答
1

使用cv2.imwrite.

import cv2
assert mat.shape[2] == 1 or mat.shape[2] == 3, 'the third dim should be channel'
cv2.imwrite(path, mat) # note the form of data should be height - width - channel  
于 2018-10-08T07:17:57.133 回答
0

使用 pygame

所以这应该像我测试的那样工作(如果你没有 pygame,你必须安装 pygame 使用 pip -> pip install pygame 安装它(有时不起作用,所以在这种情况下你将不得不下载轮子或某事但是你可以在谷歌上查找)):

import pygame


pygame.init()
win = pygame.display.set_mode((128, 128))
pygame.surfarray.blit_array(win, yourarray)
pygame.display.update()
pygame.image.save(win, 'yourfilename.png')

只要记住根据您的数组更改显示宽度和高度

这是一个示例,运行以下代码:

import pygame
from numpy import zeros


pygame.init()
win = pygame.display.set_mode((128, 128))
striped = zeros((128, 128, 3))
striped[:] = (255, 0, 0)
striped[:, ::3] = (0, 255, 255)
pygame.surfarray.blit_array(win, striped)
pygame.display.update()
pygame.image.save(win, 'yourfilename.png')
于 2020-10-28T08:50:30.390 回答