Maresfield イギリスの飯、別にマズくないよ

Pythonで画像を読み込む

パッケージ

Pythonで画像を扱うときによく使うパッケージ

画像を読み込んで配列に変換する

一般的な8-Bit画像

colorgrid

拡大表示しているだけで実際はそれぞれの色が1pxの画像。これを読み込んだ場合。

matplotlib.image.imread()

インストール

pip install matplotlib

読み込み

from matplotlib import image
img = image.imread(path_to_image)
print img

結果

[[[ 1.          0.          0.        ]
  [ 0.          1.          0.        ]
  [ 0.          0.          1.        ]]

 [[ 0.          0.68235296  0.93725491]
  [ 0.9254902   0.          0.54901963]
  [ 1.          0.94901961  0.        ]]

 [[ 1.          1.          1.        ]
  [ 0.50588238  0.50588238  0.50588238]
  [ 0.          0.          0.        ]]]

matplotlibは単体ではPNG画像しかサポートしていないが、それ以外の画像はPILを通して扱えるらしい。 与えられた8-Bit画像は自動的に0-1の浮動小数点数に変換される。

参考: http://matplotlib.org/users/image_tutorial.html#importing-image-data-into-numpy-arrays

scipy.misc.imread()

インストール

pip install scipy

読み込み

from scipy import misc
img = misc.imread(path_to_image)
print img

結果

[[[255   0   0]
  [  0 255   0]
  [  0   0 255]]

 [[  0 174 239]
  [236   0 140]
  [255 242   0]]

 [[255 255 255]
  [129 129 129]
  [  0   0   0]]]

これは0-255の8bitで返される。

scikit-image

sciという名前が入っているがscipyと関係があるのかはわからない。

インストール

pip install scikit-image

読み込み

from skimage import io
img = io.imread(path_to_image)
print img

結果

[[[255   0   0]
  [  0 255   0]
  [  0   0 255]]

 [[  0 174 239]
  [236   0 140]
  [255 242   0]]

 [[255 255 255]
  [129 129 129]
  [  0   0   0]]]

scipyと同じ。

PIL.Image.load()

インストール

pip install Pillow

読み込み

from PIL import Image
import numpy as np
img = Image.open(path_to_image)
img_array = np.asarray(img)
print img_array

PILの場合はPILのデータを読み込んだ後、更にndarrayに変換する

結果

[[[255   0   0]
  [  0 255   0]
  [  0   0 255]]

 [[  0 174 239]
  [236   0 140]
  [255 242   0]]

 [[255 255 255]
  [129 129 129]
  [  0   0   0]]]

HDRI画像

HDR画像は上記のモジュールでは読み込むことができないようなので、 openexrはOpenEXRモジュールもしくはimageioで、HDRはimageioで読み込む。

Rec709.exr Rec709 Copyright (c) 2004, Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd.

画像はOpenEXRのGithubリポジトリより。

imageio

インストール

pip install imageio

読み込み

from imageio import imread
img = imread("Rec709.hdr")
print img

結果

[[[0.28320312 0.38476562 0.109375  ]
  [0.25976562 0.359375   0.09570312]
  [0.2421875  0.33203125 0.08398438]
  ...
  [0.16015625 0.22070312 0.05859375]
  [0.17480469 0.22558594 0.07226562]
  [0.19824219 0.24609375 0.08398438]]

 [[0.31445312 0.4296875  0.1328125 ]
  [0.29492188 0.41992188 0.1171875 ]
  [0.27734375 0.39257812 0.109375  ]
  ...
  [0.15625    0.21679688 0.06445312]
  [0.16796875 0.22167969 0.06640625]
  [0.20507812 0.25390625 0.08398438]]

 [[0.3359375  0.45117188 0.15625   ]
  [0.31640625 0.44335938 0.14453125]
  [0.31835938 0.43359375 0.14453125]
  ...
  [0.16992188 0.21484375 0.06933594]
  [0.18066406 0.22851562 0.06835938]
  [0.22070312 0.265625   0.08789062]]

 ...

 [[0.15917969 0.22949219 0.07714844]
  [0.20898438 0.27929688 0.11328125]
  [0.26171875 0.34570312 0.1640625 ]
  ...
  [0.04443359 0.05371094 0.02197266]
  [0.02954102 0.04467773 0.01489258]
  [0.03686523 0.05541992 0.02001953]]

 [[0.26953125 0.328125   0.11328125]
  [0.25390625 0.32421875 0.13085938]
  [0.26367188 0.35546875 0.171875  ]
  ...
  [0.04614258 0.05932617 0.02514648]
  [0.04272461 0.05371094 0.02514648]
  [0.04101562 0.05615234 0.02539062]]

 [[0.48046875 0.47265625 0.15429688]
  [0.375      0.43359375 0.16210938]
  [0.31835938 0.40429688 0.1875    ]
  ...
  [0.05566406 0.06298828 0.03564453]
  [0.05126953 0.06347656 0.02978516]
  [0.046875   0.06445312 0.02539062]]]

OpenEXR

インストール

pip install OpenEXR

が、いきなりインストールしようとするとエラーが出て失敗する。

OpenEXR.cpp:36:10: fatal error: 'ImathBox.h' file not found
    #include <ImathBox.h>
             ^
    1 error generated.
    error: command 'cc' failed with exit status 1

Macの場合、Homebrewでopenexrをインストールすると必要なファイル等がインストールされる。 その後再びpipを実行すれば無事OpenEXRモジュールがインストールされる。

読み込み OpenEXRの場合は読み込んだデータがnumpy配列ではない。 numpy配列として扱うにはimageioを使って読み込むのが手っ取り早いが、imageioを使わずnumpy配列として他のモジュールで編集する為には手動で変換する必要がある。

http://excamera.com/articles/26/doc/intro.html#openexr-to-jpg

を参考に

import OpenEXR
import Imath
import numpy

file = OpenEXR.InputFile("Rec709.exr")
pixelType = Imath.PixelType(Imath.PixelType.FLOAT)
dw = file.header()['dataWindow']
width = dw.max.x - dw.min.x + 1
height = dw.max.y - dw.min.y + 1
rgbStr = file.channels('RGB', pixelType)
rgb = [numpy.fromstring(c, dtype=numpy.float32) for c in rgbStr]
img = numpy.vstack(rgb).T.reshape(height, width, 3)
print img

結果

[[[0.28344727 0.38598633 0.11120605]
  [0.2602539  0.359375   0.09747314]
  [0.24353027 0.33251953 0.08496094]
  ...
  [0.16027832 0.22106934 0.059021  ]
  [0.17565918 0.22558594 0.07250977]
  [0.1986084  0.24645996 0.0847168 ]]

 [[0.3149414  0.4296875  0.13366699]
  [0.2956543  0.4206543  0.11816406]
  [0.2783203  0.39404297 0.10986328]
  ...
  [0.15649414 0.21679688 0.06524658]
  [0.16809082 0.22229004 0.06713867]
  [0.2064209  0.2541504  0.0847168 ]]

 [[0.33691406 0.45239258 0.15734863]
  [0.3178711  0.44458008 0.14526367]
  [0.31860352 0.43359375 0.14550781]
  ...
  [0.17016602 0.2154541  0.07006836]
  [0.18115234 0.22912598 0.0692749 ]
  [0.22143555 0.2668457  0.08813477]]

 ...

 [[0.15942383 0.23022461 0.07733154]
  [0.20935059 0.27978516 0.11413574]
  [0.26342773 0.34594727 0.16479492]
  ...
  [0.04443359 0.05380249 0.02217102]
  [0.02973938 0.04476929 0.01499176]
  [0.03686523 0.05551147 0.02009583]]

 [[0.2709961  0.32836914 0.11437988]
  [0.2553711  0.32470703 0.13183594]
  [0.26513672 0.3569336  0.17358398]
  ...
  [0.04620361 0.05938721 0.02523804]
  [0.04293823 0.05389404 0.02523804]
  [0.0411377  0.05621338 0.02548218]]

 [[0.48046875 0.47338867 0.15551758]
  [0.37573242 0.4350586  0.16320801]
  [0.31982422 0.40478516 0.18896484]
  ...
  [0.05566406 0.06341553 0.03607178]
  [0.05142212 0.06378174 0.02987671]
  [0.04718018 0.0645752  0.02583313]]]

数値で見ると大分誤差が大きいような気がするが、画像でみればほぼ同じように見えるので気にしないことにする。

配列

これらの結果はピクセルのRGB値からなる配列を要素とした画像の一行分のピクセルの配列、さらにそれを要素とした多次元配列。

コンソールでのアウトプットはインデントされているけど、元の画像と照らし合わせてあえて崩すとこんな感じだろうか。

[
    [[255   0   0] [  0 255   0] [  0   0 255]]

    [[255 251 250] [ 47  47  48] [  0   0   0]]

    [[  0 108 220] [214   0  67] [255 226   0]]
]

つまり

pixel = [縦][横][色]

終わり

あとは配列を編集して書き出せばHDR画像のサムネイルなんかもさくっと生成できる。



参考

http://matplotlib.org/users/image_tutorial.html

http://www.scipy-lectures.org/advanced/image_processing/