web-dev-qa-db-ja.com

Pythonで離散ピクセル値から画像を描画する最も速い方法は何ですか?

一部のデータを視覚化する手段として、計算されたピクセル値に基づいて画像を描画したいと思います。本質的に、私はカラートリプレットの2次元マトリックスを取り、それをレンダリングしたいと思います。

これは画像処理ではないことに注意してください。これは、既存の画像を変換したり、画像全体の変換を行ったりするものではありません。また、レンダリングしている画像に所定の構造がないため、ベクターグラフィックでもありません。おそらく、一度に1ピクセルずつ色のアモルファスブロブを作成する予定です。

とりあえず、1kx1kピクセル程度の画像をレンダリングする必要がありますが、スケーラブルなものが役に立つでしょう。最終的なターゲット形式はPNGまたはその他のロスレス形式です。

現在ImageDrawのdraw.pointを介してPILを使用していますが、必要な非常に具体的で比較的基本的な機能を考えると、より高速なライブラリはありますか?

38
saffsd

numpyscipyが利用可能な場合(そして、Pythonで大きな配列を操作している場合は、それらをお勧めします)、 scipy.misc.pilutil.toimage 関数は非常に便利です。簡単な例:

import numpy as np
import scipy.misc as smp

# Create a 1024x1024x3 array of 8 bit unsigned integers
data = np.zeros( (1024,1024,3), dtype=np.uint8 )

data[512,512] = [254,0,0]       # Makes the middle pixel red
data[512,513] = [0,0,255]       # Makes the next pixel blue

img = smp.toimage( data )       # Create a PIL image
img.show()                      # View in default viewer

良い点は、toimageがさまざまなデータ型に非常によく対応することです。そのため、浮動小数点数の2D配列は、適切にグレースケールなどに変換されます。

numpyscipyhere からダウンロードできます。またはpipを使用:

pip install numpy scipy
35
BADC0DE
_import Image
im= Image.new('RGB', (1024, 1024))
im.putdata([(255,0,0), (0,255,0), (0,0,255)])
im.save('test.png')
_

画像の左上に赤、緑、青のピクセルを配置します。

im.fromstring()は、バイト値を処理したい場合でも高速です。

18
bobince

必要条件

この例では、 NumpyPillow をインストールします。

目標は、最初に、作成する画像を3(RGB)数値のセットの配列配列として表すことです。パフォーマンスとシンプルさのために、Numpyの array() を使用します。

_import numpy

data = numpy.zeros((1024, 1024, 3), dtype=numpy.uint8)
_

次に、真ん中の3ピクセルのRGB値を赤、緑、青に設定します。

_data[512, 511] = [255, 0, 0]
data[512, 512] = [0, 255, 0]
data[512, 513] = [0, 0, 255]
_

次に、Pillowの Image.fromarray() を使用して、配列から画像を生成します。

_from PIL import Image

image = Image.fromarray(data)
_

次に、画像を「表示」します(OS Xでは、プレビューで一時ファイルとして開きます)。

_image.show()
_

注意

この回答はBADCODEの回答に触発されました。これは古すぎて使用できず、完全に書き換えずに単純に更新するにはあまりにも異なっていました。

6
orokusaki

別のアプローチは、Python 3での TIC-80 API のオープンソース実装である Pyxel を使用することです(TIC-80はオープ​​ンソースのPICO-8です)。

以下は、黒い背景に黄色のピクセルを1つだけ描画する完全なアプリです。

import pyxel

def update():

    """This function just maps the Q key to `pyxel.quit`,
    which works just like `sys.exit`."""

    if pyxel.btnp(pyxel.KEY_Q): pyxel.quit()

def draw():

    """This function clears the screen and draws a single
    pixel, whenever the buffer needs updating. Note that
    colors are specified as palette indexes (0-15)."""

    pyxel.cls(0)            # clear screen (color)
    pyxel.pix(10, 10, 10)   # blit a pixel (x, y, color)

pyxel.init(160, 120)        # initilize gui (width, height)
pyxel.run(update, draw)     # run the game  (*callbacks)

:ライブラリでは最大16色しか許可されていませんが、どの色を変更することもでき、多くの作業をせずにさらに多くの色をサポートすることができます。 。

2
Carl Smith

PILを使用してディスク上にイメージファイルを生成し、後でイメージリーダーソフトウェアでロードすると思います。

メモリ内の画像を直接レンダリングすることで、速度が少し向上するはずです(ディスクにイメージを書き込んでから再ロードするコストを節約できます)。さまざまなpythonモジュールで画像をレンダリングする方法については、このスレッドをご覧ください https://stackoverflow.com/questions/326300/python-best-library-for-drawing

私は個人的にwxpythonとdc.DrawBitmap関数を試してみます。外部イメージリーダーではなくこのようなモジュールを使用すると、多くの利点があります。

  • 速度
  • パラメータのボタンを備えたインタラクティブなユーザーインターフェースを作成できます。
  • ズームインおよびズームアウト機能を簡単にプログラムできるようになります
  • 計算しながら画像をプロットできるため、計算に時間がかかる場合に非常に便利です。
1
Mapad