今日は、OpenCVを使って画像を鉛筆画に変換する方法と、matplotlibを使って様々な段階の画像をプロットする方法を学びたいと思います。
おすすめの記事 Pythonでエッジ検出
1. モジュールのインポート
まず、このプログラムにモジュールをインポートすることから始めましょう。ここでは、OpenCV の関数と matplotlib モジュールを利用して、画像をプロットする予定です。
また、プロットのスタイルは私の好みに合わせて設定します。
|
1
2
3
|
import cv2
import matplotlib.pyplot as plt
plt.style.use('seaborn')
|
2. オリジナル画像の読み込みとプロット
では、ファイルのパスを受け取る imread 関数を使用して、プログラムにイメージファイルをロードします。ファイルへのパスが正しいことを確認してください。
また、画像のカラーコードをRGB形式に変更して元の色を取得し、imshow関数を使用して画像をプロットします。
そのためのコードを以下に示します。
|
1
2
3
4
5
6
7
|
img = cv2.imread("image1.png")
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.figure(figsize=(8,8))
plt.imshow(img)plt.axis("off")
plt.title("Original Image")
plt.show() |
上記のコードを用いて、使用する画像をプロットすると、以下のように表示されます。
|
1
2
3
4
5
6
|
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
plt.figure(figsize=(8,8))
plt.imshow(img_gray,cmap="gray")
plt.axis("off")
plt.title("GrayScale Image")
plt.show() |
3. 画像をグレースケールに変換する
画像の複雑さを軽減し,処理を簡単にするために,関数 cvtColor を用いて画像をグレースケール画像に変換します.以下に示すコードを用いて,同じ画像をプロットします.
|
1
2
3
4
5
6
|
img_invert = cv2.bitwise_not(img_gray)
plt.figure(figsize=(8,8))
plt.imshow(img_invert,cmap="gray")
plt.axis("off")
plt.title("Inverted Image")
plt.show() |
出力画像は以下のように表示されます。
|
1
2
3
4
5
6
|
img_smoothing = cv2.GaussianBlur(img_invert, (21, 21),sigmaX=0, sigmaY=0)
plt.figure(figsize=(8,8))
plt.imshow(img_smoothing,cmap="gray")
plt.axis("off")
plt.title("Smoothen Image")
plt.show() |
この記事もチェック:PythonとOpenCVを使って画像分割|二値化やグレースケールの変換等を解説
4. 画像を反転させる
さて、次のステップは画像の反転です。さて、なぜ反転させるのか?その答えは、画像を反転させると、より正確に、より詳細に画像を研究するのに役立つからです。
スケッチは正確で良いものでなければならないので、より詳細な研究はスケッチ生成に重要です。画像を反転させるコードを以下に示す。
|
1
2
3
4
5
6
|
final = cv2.divide(img_gray, 255 - img_smoothing, scale=255)
plt.figure(figsize=(8,8))
plt.imshow(final,cmap="gray")
plt.axis("off")
plt.title("Final Sketch Image")
plt.show() |
反転された画像の出力は以下のように表示されます。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
plt.figure(figsize=(20,20))
plt.subplot(1,5,1)
plt.imshow(img)plt.axis("off")
plt.title("Original Image")
plt.subplot(1,5,2)
plt.imshow(img_gray,cmap="gray")
plt.axis("off")
plt.title("GrayScale Image")
plt.subplot(1,5,3)
plt.imshow(img_invert,cmap="gray")
plt.axis("off")
plt.title("Inverted Image")
plt.subplot(1,5,4)
plt.imshow(img_smoothing,cmap="gray")
plt.axis("off")
plt.title("Smoothen Image")
plt.subplot(1,5,5)
plt.imshow(final,cmap="gray")
plt.axis("off")
plt.title("Final Sketch Image")
plt.show() |
これに加えて、得られるスケッチがエッジの少ない滑らかなものになるように、画像のスムージングも行う。そのためのコードを以下に示す。

出力画像は以下のようになります。

5. 画像を鉛筆のスケッチに変換する
さて、画像処理全体が終わったところで、これまでの出力を関数に渡し、画像に適切な変更を加えるために適切で正確なパラメータを渡すことになります。以下のコードにも同じことが書かれています。

最終的な出力は以下のように表示されます。

6. 最終的な出力
以下のコードでは、サブプロットを使ってすべての画像を1つのフレームに表示します。

出力は以下のように表示されます。

かなり正確な結果であることがわかりますね。すごい! 同じコードを別の画像で試したところ、とても素晴らしい結果が得られました。同じものを見てみましょう。

まとめ
今日は、画像を鉛筆画にする方法について学びました。お疲れ様でした。自分でも画像を試してみてください。
このようなチュートリアルを今後も続けていきます。