Numpy配列を画像として保存する


261

Numpy配列のタイプの行列があります。イメージとしてディスクに書き込むにはどうすればよいですか?どの形式でも機能します(png、jpeg、bmp ...)。重要な制約の1つは、PILが存在しないことです。


12
以下の回答のいくつか、そして確かにこの質問に来て見つけている人々の一部は、上記のPILない という制約を満たさないことに注意してください。一部の質問者と一部の回答はどちらもこの制約を回避しているため、PILを使用しても問題がない場合は、以下に目を通すことをお勧めします。元の制約を満たす回答と区別するための回答のタイプ。
2013年

回答:


54

PyPNGを使用できます。純粋なPython(依存関係なし)のオープンソースPNGエンコーダー/デコーダーであり、NumPy配列を画像として書き込むことができます。


4
値をPNGの正しい範囲(通常は0..255)にスケーリングすることを忘れないでください。ニューラルネットワークの値の範囲は、多くの場合0..1または-1..1。です。
トマーシュGavenčiak

8
PyPNGは純粋なPythonであり、外部依存関係を減らしますが、PILおよびその派生クラスよりもはるかに遅くなります。たとえば、私のマシンに3000x4000の画像を保存すると、PyPNGで4.05秒かかりましたが、scipy.misc.imsaveで0.59秒しかかかりませんでした(6倍高速)。
Zvika

@TomášGavenčiak-新しいバージョンのScipyでは、scipy.misc.imsaveが非推奨になりました。以下のいくつかのコメントの代替案は、imageio.imwrite( 'image_file.jpg'、array)を使用することです
Psi-Ed

259

これは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')

19
imsaveはPILを使用する... / scipy / misc / pilutil.pyにあります
denis

5
JPGに変換するときは注意が必要です。これは、損失が多く、画像の生成に使用された正確なデータを復元できない可能性があるためです。
Feanil、

8
これはscipy 0.19で非推奨になりました-scipy.io.imwrite
g.stevo

6
「imsaveはSciPy 1.0.0で非推奨になり、1.2.0で削除されます(Scipy 1.1.0 doc
noobar

15
scipy.misc.imsaveは非推奨です。import imageioを使用します。imageio.imwrite( 'file_name.jpg'、nmupy_array)
ChaosPredictor

228

PILを使用した回答(役に立つ場合に備えて)。

numpy配列 "A"が与えられた場合:

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

「jpeg」は、ほぼすべての形式に置き換えることができます。フォーマットの詳細はこちら


5
画像はPILのモジュールです。「Print Image .__ file__」を実行してください
Juh_

10
ここをさまよい、PILを持っている私たちにとって非常に役立ちます-私はfrom PIL import Imageそれを明確に保つために使用すると思います...
sage

4
あなたはRGBイメージを持っていれば、あなたは、IM = Image.fromarrayを使用して画像を取得することができます(A).convert( 'RGB')さらに詳しい情報:stackoverflow.com/questions/4711880/...
ロジャーVeciana

uint8の配列の3番目の軸を使用してRGBをコード化すると、この方法で機能します。モジュールPILは、「pip install pillow」を使用してインストールできます。
-bli

1
@Ludovico Verniani画像を歪めませんが、色の順序がRGBではなくBGRである、あまり一般的ではないカラーエンコーディングを使用します。
Zvika

88

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.

ここに画像の説明を入力してください


これを使用します。しかし、メモリリークに悩まされている
SolessChong 2014

新しいバージョンのmatplotlib.imsave()
Vinay Lodha 2018

6
それmatplotlib.pyplot.imsaveはmatplotlib 2+にあります
アレクセイペトレンコ2018

1
@HughPerkins がPython 3のPILの代替としてPillowを試す
christianbrodbeck

10
import matplotlib.pyplot as pltその後plt.imsave('name.png', array)
アレッサンドロ

61

Pure Python(2&3)、サードパーティの依存関係のないスニペット。

この関数は、圧縮されたトゥルーカラー(ピクセルあたり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)


2
これはまさに私が探しているもののようですが、コメントを追加できますか?これがファイルに書き込む方法はわかりません。以前に開いたファイルに出力を書き込む必要がありますか?ありがとう!
PhilMacKay 2013年

1
@PhilMacKay、データはバイナリファイルに書き込む必要があります。コメントを追加しました。
ideasman42

1
誰かが画像(buf)の形式を指定できますか?それは派手な配列ではないようです...
christianbrodbeck

1
@ christianmbrodbeck、bytearray(RGBARGBA ...)
ideasman42

1
ありがとう@ ideasman42。このコードをBlenderで使用できるように移植しました
emackey 2016

57

opencvpython があります(ドキュメントはこちら)。

import cv2
import numpy as np

cv2.imwrite("filename.png", np.zeros((10,10)))

保存以外の処理を行う必要がある場合に役立ちます。


1
サイズ10の配列を使用する理由 このソリューションで使用される10の選択につながったのは何ですか?
ガチド2017年

3
@Gathide任意の乱暴な行列をファイルに書き込む例と同じです。実際の生活の中np.zeros((10,10))であなたのイメージに置き換えてください。
Xocoatzin

5
cmap="gray"cv2を使用して画像を保存するときに、のようなものをどのように追加できますか?
Mona Jalal 2017年

@Xocoatzinリンク切れ?
jtlz2 2018年

1
@ jtlz2更新されたリンク。
Xocoatzin

30

あなたがmatplotlibを持っているなら、あなたはすることができます:

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

これにより、プロットが保存されます(画像自体ではありません)。 ここに画像の説明を入力してください


10
いいえ、pyplotインターフェースの場合、plt.figure()は不要です。また、図ウィンドウも表示したい場合は、plt.show()のみが必要です。この場合、画像ファイルの保存のみが必要でしたので、show()を呼び出す必要はありませんでした。
DopplerShift 2011

7
結果の画像ファイルには、ピクセルデータだけでなく、matlplotlibの図の座標軸と灰色の領域が含まれることに注意してください。
Dave

1
リモートホストでスクリプトを実行し、グラフィカルインターフェイスのサポートなしでsshを実行すると、機能しません。
Temak

ノートブックで画像を表示したい場合は、次を追加できます:>> "from IPython.display import Image"次に>> "Image(filename = filename)"
Robert

軸を削除するには:plt.axis('off')
yakout

15

Pythonで 'skimage'ライブラリを使用できます

例:

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

15

scipy.miscimsave関数に関する非推奨の警告を表示し、imageio代わりに使用方法を提案します。

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

12

@ 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ます。)


8

直接完全に機能する例を探している人のために:

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)


6

matplotlib svnには、画像を単なる画像として保存する新しい機能があります-Axesなどはありません。svnをインストールしたくない場合は、バックポートするのも非常に簡単な機能です(matplotlib svnのimage.pyから直接コピーし、簡潔にするためにdocstring):

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)

3

世界はおそらくnumpy配列をPNGファイルに書き込むためのさらに別のパッケージを必要としないでしょうnumpngw

https://github.com/WarrenWeckesser/numpngw

そしてpypi上:https://pypi.python.org/pypi/numpngw/

唯一の外部依存関係はnumpyです。

これexamplesがリポジトリのディレクトリからの最初の例です。本質的なラインは単純です

write_png('example1.png', img)

どこimgnumpyの配列です。その行の前のすべてのコードは、インポート文と作成するコード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ファイルです。

example1.png


私は好奇心旺盛です、あなたのlibは他の人とどう違うのですか?速いですか?豪華な機能はありますか?
F Lekschas 2018年

いくつかの機能:(1)numpy配列を使用します。(2)pythonとnumpyのみを使用して記述されているため、Cライブラリをインストールする必要はありません。(3)アニメーションのPNGファイルを作成できます。(4)matplotlibアニメーションをアニメーションPNGファイルとして書き込むためのクラスを提供します。
Warren Weckesser 2018年

ありがとう!純粋なpythonであるパフォーマンスの点で、それがstackoverflow.com/a/19174800/981933とどのように比較されるのか知りたいです。前者の方法はPILよりも2倍高速であり、非常に優れています。それがあなたの目標ではないかどうか気にしないでください:)
F Lekschas

2

グレースケールイメージが必要だと仮定します。

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

2

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)

1

[Py] Qtをすでに使用している場合は、qimage2ndarrayに興味があるかもしれません。バージョン1.4(リリースされたばかり)から、PySideもサポートされ、imsave(filename, array)scipyと同様の小さな関数がありますが、PILの代わりにQtを使用します。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のもう1つの利点は、これが純粋なpythonソリューションであることにより、これがさらに軽量になることです。)


1.4リリースは現在出ています。:
hans_meine '20

1

Python環境のSpyderで作業している場合は、変数エクスプローラーで配列を右クリックして[画像の表示]オプションを選択するよりも簡単です。

ここに画像の説明を入力してください

これにより、画像をdsikに、主にPNG形式で保存するように求められます。

この場合、PILライブラリは必要ありません。


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  

0

numpy配列を画像として保存するには、いくつかの選択肢があります:

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.