Pythonで画像を扱う上で便利なライブラリがいくつかありますが、
大体はnumpy配列にしてくれると思います。
基本的に色の形式さえあっていれば相互に変換・比較可能なのでどれを使ってもいいかなと思っています。
今回は読み込み方法やパフォーマンス?を調べたのでメモしておきます。
(画像形式とかのサポート範囲はちゃんと調べられてないです。)
今回調べたのは以下のライブラリです。
PIL
一番お手軽です。
インストールはpip install Pillow
で終わりです。
使い方
Python image libraryと言うだけあって、使いやすいです。
from PIL import Image
from io import BytesIO
filename = 'image.png'
# 画像ファイルパスから読み込み
img = Image.open(filename)
# バイナリから読み込み(python3なのでbinaryモードで読み込み)
with open(filename, 'rb') as f:
binary = f.read()
img = Image.open(BytesIO(data))
# numpy配列の取得
img_array = np.asarray(img)
# 色の変換も簡単ですが、できる色が制限されます。
print(img.mode) # RGBA
rgb = img.convert('RGB')
OpenCV
インストールが一番面倒です。環境によって異なります。
pipでインストール
wheel対応のパッケージがpypiにunofficialに上がっているのでそれをインストールして見ます。
追加でlibXext, libSM, libXrenderなどが必要みたいです。
参考:Jupyterでmatplotlibのインポートした時にImportErrorが出た時の対処法
$ pip install opencv-python
// ない場合は追加でインストールが必要です。以下はubuntu/debian等の場合
$ apt install libsm6 libxrender1 libxext6
condaでインストール
anaconda等で環境構築している場合には
インストールは conda install -c menpo opencv3
等でインストールできる場合があります。
ただし、pythonバージョンとビット環境等によってはバイナリが上がっていないケースもあるのでその場合は他の方法で。。
対応してそうなプラットフォームはここでわかりそうです。
apt等でinstall or 自分でビルド
自分で好きなバージョンを入れたい場合はこの方法しかないです。
今回は特に触れません。
使い方
基本的にcの関数をバインドして呼んでいる?ので呼び方があまりpythonぽくないことも多いです。
慣れると使いやすいかなと思います。
import cv2
filename = 'image.png'
# 画像ファイルパスから読み込み
img = cv2.imread(filename)
# バイナリから読み込み(python3なのでbinaryモードで読み込み)
with open(filename, 'rb') as f:
binary = f.read()
# 一度ndarrayに変換してからdecodeします。reshapeだけしてると思われます.
arr = np.asarray(bytearray(binary), dtype=np.uint8)
img = cv2.imdecode(arr, -1) # 'load it as it is'
# numpy配列の取得、インスタンス自体がndarrayです
type(img) # numpy.ndarray
# デフォルトの色がBGR。
# 色の変換は充実。ただし指定のチェックは甘い(間違えて指定しても普通に変換される)
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
Scikit-image
これもインストールはPILと同じに簡単です。
インストールはpip install scikit-image
で終わりです。
使い方
PILと同じくらいには使いやすいかなと思います。
from skimage import io, color
from io import BytesIO
filename = 'image.png'
# 画像ファイルパスから読み込み
img = io.imread(filename)
# バイナリから読み込み(python3なのでbinaryモードで読み込み)
with open(filename, 'rb') as f:
binary = f.read()
img = io.imread(BytesIO(data))
# numpy配列の取得、インスタンス自体がndarrayです
type(img) # numpy.ndarray
# デフォルトの色はRGB/RGBAです
# 色の変換も充実しています。割とチェックもされる印象
rgb = color.rgba2rgb(img)
lab = color.rgb2lab(rgb)
まとめ
速度
気になる速度は
opencv > pillow == skimage
でした。
pillowはndarrayに変換時に時間がかかっていそうですが、きちんとタイプを指定すればskimageと同程度か少し早いくらいでした。
opencvが一番早かったですが、これは単にnumpyの速度かもしれません。
画像サイズを2MBくらいのものにしても結果の傾向は変わりませんでした。
加工も含めたopencvとpillowの比較は誰かがしてくれていました。
PIL vs Opencv
読み込みレベルだとほとんど差がないので、
それ以降の加工内容や使い勝手でライブラリを選定する、のがいいと思います。
個人的にはPyData公認のscikit-imageが好きですね。