我有一个Numpy数组类型的矩阵。我如何将其作为图像写入磁盘?任何格式都有效(png,jpeg,bmp ......)。一个重要的限制是PIL不存在。
答案 0 :(得分:235)
这使用PIL,但也许有些人可能觉得它很有用:
import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)
编辑:当前的scipy
版本开始规范化所有图片,以便min(数据)变为黑色,max(数据)变为白色。如果数据应该是精确的灰度级或精确的RGB通道,则这是不希望的。解决方案:
import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
答案 1 :(得分:157)
使用PIL的答案(以防它有用)。
给出一个numpy数组“A”:
from PIL import Image
im = Image.fromarray(A)
im.save("your_file.jpeg")
你可以用几乎任何你想要的格式替换“jpeg”。有关格式here
的更多详细信息答案 2 :(得分:56)
使用matplotlib
:
import matplotlib
matplotlib.image.imsave('name.png', array)
使用matplotlib 1.3.1,我不知道较低版本。来自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.
答案 3 :(得分:54)
Pure Python(2& 3),一个没有第三方依赖关系的片段。
此函数写入压缩的真彩色(每像素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'')])
...数据应直接写入以二进制形式打开的文件,如:
data = write_png(buf, 64, 64)
with open("my_image.png", 'wb') as fd:
fd.write(data)
答案 4 :(得分:47)
答案 5 :(得分:34)
python(documentation here)opencv
。
import cv2
import numpy as np
cv2.imwrite("filename.png", np.zeros((10,10)))
如果您需要进行除保存以外的其他处理,则非常有用。
答案 6 :(得分:30)
如果你有matplotlib,你可以这样做:
import matplotlib.pyplot as plt
plt.imshow(matrix) #Needs to be in row,col order
plt.savefig(filename)
答案 7 :(得分:15)
为了将一个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)PIL
from PIL import Image image = Image.fromarray(numpy_array) image.save('file name with extension(like .jpg)')
4)...
答案 8 :(得分:11)
@ 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
的高字节。)
答案 9 :(得分:10)
你可以使用&#39; skimage&#39; Python中的库
示例:
from skimage.io import imsave
imsave('Path_to_your_folder/File_name.jpg',your_array)
答案 10 :(得分:5)
scipy.misc
会提供有关imsave
函数的过时警告,并建议改为使用imageio
。
import imageio
imageio.imwrite('image_name.png', img)
答案 11 :(得分:4)
matplotlib svn有一个新功能,可以将图像保存为图像 - 没有轴等。如果你不想安装svn,它也是一个非常简单的backport函数(直接从mat.lpn中直接从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)
答案 12 :(得分:4)
对于那些正在寻找直接工作的示例的人:
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)
答案 13 :(得分:2)
世界可能不需要另一个用于将numpy数组写入PNG文件的包,但是对于那些无法获得足够数据的人,我最近在github上提出了numpngw
:
https://github.com/WarrenWeckesser/numpngw
和pypi:https://pypi.python.org/pypi/numpngw/
唯一的外部依赖是numpy。
这是存储库的examples
目录中的第一个示例。基本路线就是
write_png('example1.png', img)
其中img
是一个numpy数组。该行之前的所有代码都是import语句和用于创建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文件:
答案 14 :(得分:2)
假设你想要一个灰度图像:
im = Image.new('L', (width, height))
im.putdata(an_array.flatten().tolist())
im.save("image.tiff")
答案 15 :(得分: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
答案 16 :(得分:1)
如果您恰好使用[Py] Qt,您可能会对qimage2ndarray感兴趣。从版本1.4(刚刚发布)开始,PySide也受支持,并且会有一个类似于scipy的小imsave(filename, array)
函数,但是使用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解决方案,这使得它更轻巧。)
答案 17 :(得分:0)
如果您在python环境Spyder中工作,那么与仅在变量资源管理器中右键单击数组,然后选择“显示图像”选项相比,它变得更加容易。
这将要求您将图像保存为dsik,主要是PNG格式。
在这种情况下,不需要PIL库。
答案 18 :(得分:0)
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)
答案 19 :(得分:0)
使用pygame
因此这应该可以按照我的测试进行(如果您没有使用pip安装pygame,则必须安装pygame-> pip install pygame(有时不起作用,因此在这种情况下,您必须下载滚轮或某物,但您可以在Google上查询)):
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')