我有一个Numpy数组类型的矩阵。我怎么把它作为映像写到磁盘上呢?任何格式都可以(png, jpeg, bmp…)一个重要的限制是PIL不存在。


当前回答

使用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  

其他回答

下面的答案中有@Nima Farhadi在时间测量方面提出的方法。

最快的是CV2,但重要的是要改变颜色顺序从RGB到BGR。简单的是matplotlib。

重要的是要确保数组有unsigned integer format uint8/16/32。

代码:

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

这个世界可能不需要另一个包来将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数组。该行之前的所有代码都是导入语句和创建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文件:

另外,我使用了numpngw。write_apng在Voronoi图表中创建动画。

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

使用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  

纯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 fh:
    fh.write(data)

原始来源 参见:Rust Port来自这个问题。 感谢@Evgeni Sergeev的示例用法:https://stackoverflow.com/a/21034111/432509