webdevqa.jp.net

PILを使用して生画像を読み取る方法

各ピクセルが16ビット符号なし整数に対応する生の画像があります。次のコードのように、PIL Image.fromstring()関数を使用して読み取ろうとしています。

if __name__ == "__main__":
    if (len(sys.argv) != 4):
        print 'Error: missing input argument'
        sys.exit()

    file = open(sys.argv[1], 'rb')
    rawData = file.read()
    file.close()

    imgSize = (int(sys.argv[2]), int(sys.argv[3]))

    # Use the PIL raw decoder to read the data.
    #   - the 'F;16' informs the raw decoder that we are reading a little endian, unsigned integer 16 bit data.
    img = Image.fromstring('L', imgSize, rawData, 'raw', 'F;16')

    im.save('out.png')

PILのドキュメントには、fromstring()関数の最初の引数が 'mode'であることが記載されています。しかし、ドキュメントを見てグーグルで調べてみると、その議論が本当に意味するものについての詳細を見つけることができませんでした(色空間などに関連していると思います)。 fromstring()関数とmode引数の意味についてのより詳細なリファレンスがどこにあるか誰にもわかりますか?

30
Alceu Costa

特定のドキュメントは http://effbot.org/imagingbook/concepts.htm にあります。

モード

画像のモードは、画像内のピクセルのタイプと深度を定義します。現在のリリースでは、次の標準モードがサポートされています。

  • 1 (1-bit pixels, black and white, stored with one pixel per byte)
  • L (8-bit pixels, black and white)
  • P (8-bit pixels, mapped to any other mode using a colour palette)
  • RGB(3x8ビットピクセル、トゥルーカラー)
  • RGBA(4x8ビットピクセル、透明マスク付きトゥルーカラー)
  • CMYK(4x8ビットピクセル、色分解)
  • YCbCr(3x8ビットピクセル、カラービデオ形式)
  • I (32-bit signed integer pixels)
  • F (32-bit floating point pixels)

PILは、LA(アルファ付きのL)、RGBX(パディング付きのトゥルーカラー)、RGBa(アルファが事前乗算されたトゥルーカラー)など、いくつかの特殊モードの限定サポートも提供します。

20
Katriel

Image.frombuffer(mode、size、data)=> image

(PIL 1.1.4の新機能)。標準の「raw」デコーダーを使用して、文字列またはバッファーオブジェクトのピクセルデータから画像メモリを作成します。一部のモードでは、画像メモリは元のバッファとメモリを共有します(つまり、元のバッファオブジェクトへの変更が画像に反映されます)。すべてのモードがメモリを共有できるわけではありません。サポートされるモードには、「L」、「RGBX」、「RGBA」、および「CMYK」が含まれます。他のモードでは、この関数はfromstring関数への対応する呼び出しのように動作します。

「L」が何を表すのかわかりませんが、「RGBA」はRed-Green-Blue-Alphaを表します。そのため、RGBXはRGBと同等であると考えられます(編集:テストではそうではありません)? CMYKはシアン-マゼンタ-イエロー-ケルビンで、別のタイプの色空間です。もちろん、PILについて知っているなら、色空間についても知っていると思います。そうでない場合、 Wikipedia には素晴らしい記事があります。

それが本当に何を意味するのか(それで十分でない場合):ピクセル値は、色空間ごとに異なってエンコードされます。通常のRGBでは、ピクセルあたり3バイト-0-254、0-254、0-254があります。アルファの場合、各ピクセルに別のバイトを追加します。 RGB画像をRGBAとしてデコードすると、最初のピクセルの右側のRピクセルをアルファとして読み取ることになります。つまり、Rの値としてGピクセルを取得します。これは画像の大きさに応じて拡大されますが、実際には色が不安定になります。同様に、CMYKでエンコードされた画像をRGB(またはRGBA)として読み取ろうとすると、画像が本来のように見えなくなります。たとえば、画像でこれを試してください:

i = Image.open('image.png')
imgSize = i.size
rawData = i.tostring()
img = Image.fromstring('L', imgSize, rawData)
img.save('lmode.png')
img = Image.fromstring('RGB', imgSize, rawData)
img.save('rgbmode.png')
img = Image.fromstring('RGBX', imgSize, rawData)
img.save('rgbxmode.jfif')
img = Image.fromstring('RGBA', imgSize, rawData)
img.save('rgbamode.png')
img = Image.fromstring('CMYK', imgSize, rawData)
img.save('rgbamode.tiff')

さまざまなモードが何をするのかがわかります。アルファ付きのpng、アルファなしのpng、bmp、gif、jpegなど、さまざまな入力画像で試してください。実際、それはちょっと楽しい実験です。

10
Wayne Werner

他のすべてが失敗した場合、いつでもソースコードを読むことができます。 PILの場合、ダウンロードは here です。

16ビットの符号なし整数のピクセルデータの形式を正確に言ったことはありませんが、RRRRRGGGGGGBBBBBB、(5ビット赤、6ビット緑、5ビット青)、またはRRRRRGGGGGBBBBBA(5-ビット赤、5ビット緑、5ビット青、1ビットアルファまたは透明度)。ソースのいくつかを自分で非常に簡単に覗いてみても、これらの形式のサポートは見当たりませんでしたが、確かにどちらかと言えません。

PILのダウンロードと同じWebページで、彼らはPython Image SIGメーリングリストに質問を送信し、そのリンクを提供できることを言及しています。 。

お役に立てれば。

5
martineau

これは古い質問ですが、これは将来誰かを助けるかもしれません。元のコードスニペットの問題の1つは、Image.fromstring('L', imgSize, rawData, 'raw', 'F;16')F;16一部は'F'モード。

これは私のために働く:

image = Image.fromstring('F', imgSize, rawData, 'raw', 'F;16')
image.convert('L').save('out.png')
4
matiasg