'normal'(Enthought)pythonを使用してnumpy配列を16ビットイメージとして保存できますか?



Can I Save Numpy Array



解決:

1つの代替方法は、pypngを使用することです。それでも別のパッケージをインストールする必要がありますが、それは純粋なPythonなので、簡単なはずです。 (実際にはpypngソースにCythonファイルがありますが、その使用はオプションです。)

pypngを使用してnumpy配列をPNGに書き込む例を次に示します。



import png import numpy as np#次のインポートは、興味深い配列のデータを作成するためのものです。 PyPNGでPNGファイルを書き込む必要はありません。 from scipy.ndimage import gaussian_filter#このデモンストレーション用にnumpy配列で画像を作成します。 nrows = 240 ncols = 320 np.random.seed(12345)x = np.random.randn(nrows、ncols、3)#yは浮動小数点のデモンストレーションデータです。 y = gaussian_filter(x、(16、16、0))#yを16ビットの符号なし整数に変換します。 z =(65535 *((y --y.min())/ y.ptp()))。astype(np.uint16)#pypngを使用してzをカラーPNGとして書き込みます。 with open( 'foo_color.png'、 'wb')as f:writer = png.Writer(width = z.shape [1]、height = z.shape [0]、bitdepth = 16)#zをPythonに変換#pngライターが期待するリストのリスト。 z2list = z.reshape(-1、z.shape [1] * z.shape [2])。tolist()writer.write(f、z2list)#これはグレースケールの例です。 zgray = z [:、:、0] #pypngを使用して、zgrayをグレースケールPNGとして記述します。 open( 'foo_gray.png'、 'wb')をfとして使用:writer = png.Writer(width = z.shape [1]、height = z.shape [0]、bitdepth = 16、greyscale = True)zgray2list = zgray.tolist()writer.write(f、zgray2list)

カラー出力は次のとおりです。

foo_color.png



グレースケール出力は次のとおりです。

foo_gray.png


アップデート :最近、というモジュールのgithubリポジトリを作成しましたnumpy配列をPNGファイルに書き込むための関数を提供するnumpngw。リポジトリにはパッケージとしてインストールするためのsetup.pyファイルですが、重要なコードは1つのファイルに含まれています。numpngw.py、これは任意の便利な場所にコピーできます。の唯一の依存関係numpngwはnumpyです。



上記と同じ16ビット画像を生成するスクリプトは次のとおりです。

import numpy as np import numpngw#次のインポートは、興味深い配列のデータを作成するためのものです。 PyPNGでPNGファイルを書き込む必要はありません。 from scipy.ndimage import gaussian_filter#このデモンストレーション用にnumpy配列で画像を作成します。 nrows = 240 ncols = 320 np.random.seed(12345)x = np.random.randn(nrows、ncols、3)#yは浮動小数点のデモンストレーションデータです。 y = gaussian_filter(x、(16、16、0))#yを16ビットの符号なし整数に変換します。 z =(65535 *((y --y.min())/ y.ptp()))。astype(np.uint16)#numpngwを使用して、zをカラーPNGとして書き込みます。 numpngw.write_png( 'foo_color.png'、z)#これはグレースケールの例です。 zgray = z [:、:、0] #numpngwを使用して、zgrayをグレースケールPNGとして記述します。 numpngw.write_png( 'foo_gray.png'、zgray) 

このpngとnumpngwの説明はとても役に立ちます!しかし、私が言及すべきだと思った小さな「間違い」が1つあります。 16ビットの符号なし整数への変換では、y.max()はy.min()である必要があります。ランダムな色の画像の場合、それは実際には問題ではありませんでしたが、実際の画像の場合、正しく行う必要があります。これが修正されたコード行です...

z =(65535 *((y --y.min())/ y.ptp()))。astype(np.uint16)