Pythonによる各種画像処理ライブラリを用いた画像データの入出力方法とライブラリ間の連携方法（OpenCV, Scikit-image, Pillow）

# 概要
Python を用いて画像処理を行う第一歩として，画像処理用の各種ライブラリによるデータの入出力方法と，ライブラリ間の連携方法について記載する．
Python ではいくつかの画像処理ライブラリが活用できる．そのため，ひとつのコードの中で複数のライブラリを用いた処理を行う際には，互換性の確認が必要である．
ここでは，各ライブラリを用いて実装する際の画像データ構造の扱い方の違いと複数ライブラリをまたいで使用する際の方法について記述する．

# Python で活用できる画像処理ライブラリの種類と事前準備
ここでは画像処理ライブラリとして，OpenCV, Scikit-image, Pillow について扱う．
## OpenCV：Open Source Computer Vision Library
Intel が開発した画像処理のためのオープンソースライブラリ．C/C++, Java, MATLAB でも公開されており，インターネット上にも OpenCV を用いたサンプルコードが多く見受けられる．
【インストール方法】
コマンドプロンプト上で，OpenCV を pip3 コマンドによりインストールする．

```
pip3 install opencv-python
pip3 install opencv-contrib-python
```

※OpenCV では，画像データを numpy 配列 ndarray で扱うため，numpy モジュールがインストールされていない場合には numpy インストールしておく．

```
pip3 install numpy
```

【インポート方法】
Python プログラム上で cv2 を import する．

```
import cv2
```

## Scikit-image
Python向けの画像処理ライブラリ．
【インストール方法】
コマンドプロンプト上で，Scikit-image を pip3 コマンドによりインストールする．

```
pip3 install scikit-image
```

※Scikit-image も OpenCV 同様，画像データを numpy 配列 ndarray で扱うため，numpy モジュールがインストールされていない場合には numpy インストールしておく．

```
pip3 install numpy
```

【インポート方法】
Python プログラム上で skimage の io メソッドを import する．

```
from skimage import io
```

## Pillow
2011 年で開発を停止した PIL (Python Image Library) のリポジトリをフォークし，Python3 のサポートを追加した画像処理ライブラリ．
【インストール方法】
コマンドプロンプト上で，Scikit-image を pip3 コマンドによりインストールする．

```
pip3 install Pillow
```

【インポート方法】
Python プログラム上で PIL を import する．

```
from PIL import Image
```



# 各画像処理ライブラリの入出力
## OpenCV
・入力

```
img = cv2.imread(Inputfilename)
```

※ Inputfilename には画像のあるディレクトリからファイル名を記載するが，日本語を含む path は読み込まないため注意．

・画像の可視化

```
cv2.imshow('imgCV', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```

・出力

```
cv2.imwrite(Outputfilename, img)
```

【データの構造】
画像データを読み込むと，( 画像の縦のサイズ, 画像の横のサイズ, 色の次元数（白黒だと 1 カラーだと 3） ) の構造になっている．色の順番は，BGR（青、緑、赤）の順で保存されている．

```
print(type(img))
<class 'numpy.ndarray'>
print(img.shape)
(縦, 横, 色)
print(im.dtype)
uint8
```

## Scikit-image
・入力

```
img = io.imread(Inputfilename)
```

・画像の可視化

```
io.imshow(img)
```

・出力

```
io.imsave(Outputfilename, img)
```

【データの構造】
画像データを読み込むと，( 画像の縦のサイズ, 画像の横のサイズ, 色の次元数（白黒だと 1 カラーだと 3） ) の構造になっている．色の順番は，RGB（赤、緑、青）の順で保存されている．

```
print(type(img))
<class 'numpy.ndarray'>
print(img.shape)
(縦, 横, 色)
print(im.dtype)
uint8
```

## Pillow
・入力

```
img = Image.open(Inputfilename)
```

・画像の可視化

```
img.show()
```


・出力

```
img.save(Outputfilename)
```

【データの構造】
画像データを読み込むと，画像オブジェクトとして読み込まれている．

```
print(img)
<PIL."ファイル形式"ImagePlugin."ファイル形式"ImageFile image mode="色情報" size="横"x"縦" at 0xXXXXXXXXXXX>
```

# 各ライブラリで読み込んだデータの扱い方
## 1. Pillow で読み込んだデータを numpy により画像処理を行う
Pillow で読み込んだデータはオブジェクト型になっているため，numpy による画像処理を行う場合には，ndarray 型に変更する．

```
imgRGB = np.asarray(img)
```
※img：Pillow で読み込んだデータ，img2：ndarray 型に変更したデータ（RGB）

ここで img2 のデータは，色の順番が RGB の順になっている．そのため，Scikit-image で扱う場合と OpenCV で扱う場合には，この後の処理が少し異なることに注意が必要．

### 1.1. Scikit-image で扱う場合
Scikit-image で扱う場合には，色の順番が同じであるため，処理は不要．

### 1.2. OpenCV で扱う場合
OpenCV で扱う場合には，色の順番を変える次の処理が必要になる．

```
imgCV = cv2.cvtColor(imgPIL, cv2.COLOR_RGB2BGR)
```

## 2. OpenCV と Sckit-image の連携
OpenCV と Sckit-image では色の保存されている順番が異なるため，お互いのライブラリを扱う際には，色の順番の変換が必要になる．
## 2.1. OpenCV で読み込んだデータを Sckit-image により画像処理を行う
OpenCV で読み込んだデータを Sckit-image で扱う際には，BGR から RGB への変換が必要．

```
imgSK = cv2.cvtColor(imgCV, cv2.COLOR_BGR2RGB)
```
※imgCV：OpenCV で読み込んだデータ（BGR），imgSK：Sckit-image で読み込んだデータ（RGB）

## 2.2. Sckit-image で読み込んだデータを OpenCV により画像処理を行う
Sckit-image で読み込んだデータを OpenCV で扱う際には，RGB から BGR への変換が必要．

```
imgCV = cv2.cvtColor(imgSK, cv2.COLOR_BGR2RGB)
```
※imgCV：OpenCV で読み込んだデータ（BGR），imgSK：Sckit-image で読み込んだデータ（RGB）