简体   繁体   English

将 Numpy 数组保存为图像

[英]Saving a Numpy array as an image

I have a matrix in the type of a Numpy array.我有一个 Numpy 数组类型的矩阵。 How would I write it to disk it as an image?我如何将它作为图像写入磁盘? Any format works (png, jpeg, bmp...).任何格式都有效(png、jpeg、bmp...)。 One important constraint is that PIL is not present.一个重要的限制是 PIL 不存在。

An answer using PIL (just in case it's useful).使用PIL的答案(以防万一它有用)。

given a numpy array "A":给定一个 numpy 数组“A”:

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

you can replace "jpeg" with almost any format you want.您可以用几乎任何您想要的格式替换“jpeg”。 More details about the formats here有关格式的更多详细信息,请点击此处

This uses PIL, but maybe some might find it useful:这使用了 PIL,但也许有些人会觉得它很有用:

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

EDIT : The current scipy version started to normalize all images so that min(data) become black and max(data) become white.编辑:当前的scipy版本开始对所有图像进行规范化,以便 min(data) 变为黑色,max(data) 变为白色。 This is unwanted if the data should be exact grey levels or exact RGB channels.如果数据应该是精确的灰度级或精确的 RGB 通道,则这是不需要的。 The solution:解决方案:

import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')

With matplotlib :使用matplotlib

import matplotlib

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

Works with matplotlib 1.3.1, I don't know about lower version.适用于 matplotlib 1.3.1,我不知道低版本。 From the docstring:从文档字符串:

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.

在此处输入图像描述

There's opencv for python ( documentation here ). python有opencv文档here )。

import cv2
import numpy as np

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

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

useful if you need to do more processing other than saving.如果您需要进行除保存以外的更多处理,这很有用。

Pure Python (2 & 3), a snippet without 3rd party dependencies.纯 Python (2 & 3),一个没有 3rd 方依赖的片段。

This function writes compressed, true-color (4 bytes per pixel) RGBA PNG's.此函数写入压缩的真彩色(每像素 4 个字节) RGBA PNG。

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'')])

... The data should be written directly to a file opened as binary, as in: ...数据应直接写入以二进制形式打开的文件,如下所示:

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

You can use PyPNG .您可以使用PyPNG It's a pure Python (no dependencies) open source PNG encoder/decoder and it supports writing NumPy arrays as images.它是一个纯 Python(无依赖项)开源 PNG 编码器/解码器,它支持将 NumPy 数组编写为图像。

If you have matplotlib, you can do:如果你有 matplotlib,你可以这样做:

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

This will save the plot (not the images itself).这将保存绘图(而不是图像本身)。 在此处输入图像描述

for saving a numpy array as image, U have several choices:要将 numpy 数组保存为图像,U 有几种选择:

1) best of other: OpenCV 1)最好的:OpenCV

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

2) Matplotlib 2) Matplotlib

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

3) PIL 3) 太平

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

4) ... 4) ...

scipy.misc gives deprecation warning about imsave function and suggests usage of imageio instead. scipy.misc提供有关imsave功能的弃用警告,并建议imageio

import imageio
imageio.imwrite('image_name.png', img)

You can use 'skimage' library in Python您可以在 Python 中使用“skimage”库

Example:例子:

from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)

Addendum to @ideasman42's answer: @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()

So you can do:所以你可以这样做:

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

Producing test_grid.png :制作test_grid.png

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

(Transparency also works, by reducing the high byte from 0xff .) (透明度也可以通过减少0xff的高字节来实现。)

For those looking for a direct fully working example:对于那些寻找直接完整工作示例的人:

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

also, if you want high quality jpeg's另外,如果您想要高质量的 jpeg
.save(file, subsampling=0, quality=100)

matplotlib svn has a new function to save images as just an image -- no axes etc. it's a very simple function to backport too, if you don't want to install svn (copied straight from image.py in matplotlib svn, removed the docstring for brevity): 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)

Imageio is a Python library that provides an easy interface to read and write a wide range of image data, including animated images, video, volumetric data, and scientific formats. Imageio是一个 Python 库,它提供了一个简单的界面来读取和写入各种图像数据,包括动画图像、视频、体积数据和科学格式。 It is cross-platform, runs on Python 2.7 and 3.4+, and is easy to install.它是跨平台的,在 Python 2.7 和 3.4+ 上运行,并且易于安装。

This is example for grayscale image:这是灰度图像的示例:

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)

The world probably doesn't need yet another package for writing a numpy array to a PNG file, but for those who can't get enough, I recently put up numpngw on github:世界可能不需要另一个包来将 numpy 数组写入 PNG 文件,但对于那些无法获得足够的人,我最近在 github 上放了numpngw

https://github.com/WarrenWeckesser/numpngw https://github.com/WarrenWeckesser/numpngw

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

The only external dependency is numpy.唯一的外部依赖是 numpy。

Here's the first example from the examples directory of the repository.这是存储库examples目录中的第一个示例。 The essential line is simply基本线很简单

write_png('example1.png', img)

where img is a numpy array.其中img是一个 numpy 数组。 All the code before that line is import statements and code to create img .该行之前的所有代码都是导入语句和创建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)

Here's the PNG file that it creates:这是它创建的PNG文件:

例子1.png

Also, I used numpngw.write_apng to create the animations in Voronoi diagram in Manhattan metric .此外,我使用numpngw.write_apng 在曼哈顿度量的 Voronoi 图中创建动画。

Assuming you want a grayscale image:假设您想要灰度图像:

im = Image.new('L', (width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")

If you happen to use [Py]Qt already, you may be interested in qimage2ndarray .如果您碰巧已经使用 [Py]Qt,您可能会对qimage2ndarray感兴趣。 Starting with version 1.4 (just released), PySide is supported as well, and there will be a tiny imsave(filename, array) function similar to scipy's, but using Qt instead of PIL.从 1.4 版(刚刚发布)开始,也支持 PySide,并且会有一个类似于 scipy 的微小的imsave(filename, array)函数,但使用 Qt 而不是 PIL。 With 1.3, just use something like the following:在 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/..

(Another advantage of 1.4 is that it is a pure python solution, which makes this even more lightweight.) (1.4 的另一个优点是它是一个纯 python 解决方案,这使得它更加轻量级。)

If you are working in python environment Spyder, then it cannot get more easier than to just right click the array in variable explorer, and then choose Show Image option.如果您在 python 环境 Spyder 中工作,那么只需右键单击变量资源管理器中的数组,然后选择 Show Image 选项,再简单不过了。

在此处输入图像描述

This will ask you to save image to dsik, mostly in PNG format.这将要求您将图像保存到 dsik,主要是 PNG 格式。

PIL library will not be needed in this case.在这种情况下将不需要 PIL 库。

Use cv2.imwrite .使用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  

With pygame使用 pygame

so this should work as I tested (you have to have pygame installed if you do not have pygame install it by using pip -> pip install pygame (that sometimes does not work so in that case you will have to download the wheel or sth but that you can look up on google)):所以这应该像我测试的那样工作(如果你没有 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')

just remember to change display width and height according to your array只要记住根据您的数组更改显示宽度和高度

here is an example, run this code:这是一个示例,运行以下代码:

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')

I attach an simple routine to convert a npy to an image.我附上了一个简单的例程来将 npy 转换为图像。 Works 100% and it is a piece of cake!工作 100%,这是小菜一碟!

from PIL import Image import matplotlib从 PIL 导入图像导入 matplotlib

img = np.load('flair1_slice75.npy') img = np.load('flair1_slice75.npy')

matplotlib.image.imsave("G1_flair_75.jpeg", img) matplotlib.image.imsave("G1_flair_75.jpeg", img)

In the folowing answer has the methods as proposed by @Nima Farhadi in time measurement.在以下答案中有@Nima Farhadi 在时间测量中提出的方法。

The fastest is CV2 , but it's important to change colors order from RGB to BGR.最快的是 CV2 ,但将颜色顺序从 RGB 更改为 BGR 很重要。 The simples is matplotlib.简单的是matplotlib。

It's important to assure, that the array have unsigned integer format uint8/16/32.确保数组具有无符号整数格式 uint8/16/32 很重要。

Code:代码:

#Matplotlib
from matplotlib import pyplot as plt
plt.imsave('c_plt.png', c.astype(np.uint8))

#PIL
from PIL import Image
image = Image.fromarray(c.astype(np.uint8))
image.save('c_pil.png')


#CV2, OpenCV
import cv2
cv2.imwrite('c_cv2.png', cv2.cvtColor(c, cv2.COLOR_RGB2BGR))

在此处输入图像描述

You can use this code for converting your Npy data into an image:您可以使用此代码将 Npy 数据转换为图像:

from PIL import Image
import numpy as np
data = np.load('/kaggle/input/objects-dataset/nmbu.npy')
im = Image.fromarray(data, 'RGB')
im.save("your_file.jpeg")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM