LoginSignup
70
71

More than 5 years have passed since last update.

Pythonの画像読み込み: PIL, OpenCV, scikit-image

Last updated at Posted at 2017-09-20

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
でした。

38KBの画像の場合の比較です。
スクリーンショット 2017-09-21 14.03.39.png

pillowはndarrayに変換時に時間がかかっていそうですが、きちんとタイプを指定すればskimageと同程度か少し早いくらいでした。
opencvが一番早かったですが、これは単にnumpyの速度かもしれません。
画像サイズを2MBくらいのものにしても結果の傾向は変わりませんでした。

加工も含めたopencvとpillowの比較は誰かがしてくれていました。
PIL vs Opencv

読み込みレベルだとほとんど差がないので、
それ以降の加工内容や使い勝手でライブラリを選定する、のがいいと思います。

個人的にはPyData公認のscikit-imageが好きですね。

70
71
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
70
71