scikit-image とは
scikit-image は Pytyon 用の画像処理パッケージで、画像の入出力、変換、表示まで 1 パッケージで容易に行うことができます。 読み込んだ画像データは NumPy 配列として保持されるため、NumPy 配列の各種メソッドを使用して画素値を直接処理することができます。
高速な画像処理が可能なライブラリとして OpenCV などもありますが、scikit-image は OpenCV よりも学習が容易です。 科学的な画像処理には scikit-image、リアルタイムでのコンピュータービジョンタスクには OpenCV、と使い分けるとよさそうです。
scikit-image のインストール
scikit-image
パッケージは pip install
コマンドで簡単にインストールできます(最新バージョンへの更新を兼ねるには -U
オプションを付けます)。
依存する numpy
、scipy
、pillow
などのパッケージもまとめてインストールされます。
できれば、venv 環境 にインストールすることをお勧めします。
画面上に画像を表示する関数 (io.imshow()
) を使用する場合は、matplotlib
パッケージもインストールしておく必要があります。
Python コードからインポートするパッケージの名前は scikit-image
ではなく、skimage
なので注意してください。
skimage
の機能は、次のようにサブパッケージとして分けられています。
io
… 画像の読み書きや、画面への表示transform
… 回転などの画像変換処理color
… 色空間の変換data
… テスト用の画像データimg = data.astronaut()
のようにテスト画像データで簡単にお試しできます。
画像ファイルを読み込む
scikit-image で画像ファイルを読み込むには、io.imread()
関数を使用します。
読み込んだ画像データは、NumPy 配列 (numpy.ndarray
) として保持されます。
次の例では、64x64 サイズのカラー画像を読み込んでいます。
from skimage import io
img = io.imread("cat-64x64.jpg")
print(type(img)) # => <class 'numpy.ndarray'>
print(img.shape) # => (64, 64, 3)
NumPy 配列の値を出力してみると、各画素値 (R, G, B) の値が格納されていることを確認できます。
print(img)
NumPy 配列は 3 次元ベクトルの形で、[行, 列, チャネル]
という構成になっているので、例えば次のようにして画素値を取り出すことができます。
print(img[0, 0]) # => [215 238 232] (左上の 1 ピクセルの RGB 値)
print(img[0, 0, :]) # => 同上
print(img[0, 0, 0]) # => 215 (左上 の 1 ピクセルの R 値)
print(img[0, 0, 1]) # => 238 (左上 の 1 ピクセルの G 値)
print(img[0, 0, 2]) # => 232 (左上 の 1 ピクセルの B 値)
print(img[0, :, 0]) # => [215 216 219 ... 133] (1 行目のすべての列のピクセルの R 値)
print(img[:, 0, 0]) # => [215 219 227 ... 146] (1 列目のすべての行のピクセルの R 値)
io.imread()
で画像を読み込むときに、as_gray=True
オプションを指定すると、グレースケール化された NumPy 配列データを取得することができます。
この場合、RGB の 3 チャネルではなく、1 チャネルのデータになるので、NumPy 配列は 2 次元データになります。
img = io.imread("cat-64x64.jpg", as_gray=True)
print(type(img)) # => <class 'numpy.ndarray'>
print(img.shape) # => (64, 64)
print(img[0, 0]) # => 0.9124701960784314(左上の画素値)
画像を表示する
NumPy 配列として保持している画像データを、画面上に表示するには im.imshow()
関数を使用します。
Jupyter Notebook などの GUI 環境を使用していない場合は、続けて im.show()
を実行して、各種 OS (Windows/macOS/Linux) のウィンドウを表示する必要があります。
from skimage import io
img = io.imread("cat-64x64.jpg")
io.imshow(img)
io.show()
画像を表示するだけであれば、実は次のように直接ファイル名を指定するだけで表示できます。
io.imshow("cat-64x64.jpg")
io.show()
次のように明示的に matplotlib.pyplot
モジュールをインポートして使う方法もあります。
matplotlib
で細かい出力制御をしたいときは、こちらの方法を使うとよいです。
from matplotlib import pyplot as plt
from skimage import io
img = io.imread("cat-64x64.jpg")
plt.imshow(img)
plt.show()
RGB の各成分を取り出す
画像データ(NumPy 配列)の 3 次元目には、各画素の RGB 成分が含まれています。 次のように配列スライスを使って、各チャネルの成分を抽出することができます。
上の例では、imshow()
関数の cmap
でカラーマップを gray
に指定したので、画素値 0 が黒、画素値 255 が白になるように表示されています。
カラーマップを変更することで、各成分の強度を異なる色表現で表示することができます(参考: Choosing Colormaps in Matplotlib)。
例えば、Grays
(あるいは Greys
)を使うと、画素値 0 が白、画素値 255 が黒となるようなグレースケールで表示されます。
ax[1].imshow(img_r, cmap="Grays")
ax[2].imshow(img_g, cmap="Grays")
ax[3].imshow(img_b, cmap="Grays")
カラーマップとして Reds
、Greens
、Blues
を指定すると、各チャネルの強度を直感的な色で表示できます。
ax[1].imshow(img_r, cmap="Reds")
ax[2].imshow(img_g, cmap="Greens")
ax[3].imshow(img_b, cmap="Blues")