前回は、画像のマウスドラッグ部分にモザイクを入れるプログラムを作成しました。
今回は、写真を油絵のように加工する方法について解説します。
Pythonで利用できる画像処理モジュール「Pillow」には、デフォルトでいくつかの画像処理関数が用意されており、それらを組み合わせて写真を油絵のように加工してみます。
では、プログラムの全体を見てみましょう。
# -*- coding: utf-8 -*- | |
import tkinter | |
from PIL import Image, ImageTk, ImageFilter | |
# パラメータ(絵の細かさ: 整数4(細かい)〜7(粗い)ぐらいで調整) | |
prm = 5 | |
read_image = None | |
img = None | |
cvs = None | |
# 絵画変換処理 | |
def make_painting(): | |
global cvs,img,read_image,prm | |
ret_img = read_image.filter(ImageFilter.SMOOTH) | |
ret_img = ret_img.filter(ImageFilter.DETAIL) | |
ret_img = ret_img.filter(ImageFilter.ModeFilter(size=prm)) | |
# 編集した画像を画面に反映 | |
img = ImageTk.PhotoImage(image=ret_img) | |
cvs.create_image(0, 0, image=img, anchor='nw') | |
if __name__ == "__main__": | |
# ファイル名指定 | |
fname = "neko.jpg" | |
# ファイルを開く | |
read_image = Image.open(fname) | |
# 画像サイズを取得 | |
w, h = read_image.size | |
# GUI作成 | |
root = tkinter.Tk() | |
root.title("Image Test 4") | |
root.resizable(False, False) | |
# tkinterで表示できるように画像変換 | |
img = ImageTk.PhotoImage(image=read_image) | |
# Canvasの準備 | |
cvs = tkinter.Canvas(root, bg="black", width=w, height=h) | |
# Canvasに画像を描画 | |
cvs.create_image(0, 0, image=img, anchor='nw') | |
cvs.pack() | |
# 変換ボタンを用意 | |
button = tkinter.Button(root, text="変換", command=make_painting) | |
button.pack() | |
root.mainloop() |
今回は、Pillowの標準関数の組み合わせで実装したため、50行程度で書けました。
ベースは「Pythonで画像処理(2)白黒画像に変換する」で作成したプログラムを使用しています。
ベースプログラムから変えた部分のみ解説します。
3行目のインポートモジュールに、「ImageFilter」を追加しました。Pillowの画像フィルタ機能を利用するためです。
6行目は、出来上がり画像の細かさを調整するパラメータです。
詳細は後述しますが、整数4(細かい)〜7(粗い)までの値を代入します。
13行目から20行目が、変換処理部分です。
15行目から17行目で、写真に対して、下記フィルタを順に適用します。
1.ImageFilter.SMOOTH
2.ImageFilter.DETAIL
3.ImageFilter.ModeFilter
まず「ImageFilter.SMOOTH」フィルタを利用して、写真をぼやかします。これにより写真の鮮明さを消します。
次に「ImageFilter.DETAIL」フィルタを利用して、写真を鮮明に戻します。一度鮮明さを消してから戻すので、元の写真のようにはならず、代わりに人が描いたような鮮明な画像になります。
最後に「ImageFilter.ModeFilter」フィルタを掛けます。これはピクセル周囲で頻度の高いピクセルを採用するフィルタで、ピクセル周囲の特徴を強調する作用があります。
前述したパラメータは「ImageFilter.ModeFilter」フィルタに与えるもので、パラメータ値が大きくなれば、上記のピクセル範囲が大きくなります。
それでは、作成したプログラムを実行していきます。
今回は、下記2枚の写真を油絵っぽく変換してみます。


まず、yama.jpgをパラメータ4から順に適用してみます。

遠目に見るとほぼ写真ですが、近くで見ると絵っぽくなっているのがわかります。

少し絵っぽさが増しましたが、まだ写真ですね。

だいぶ絵っぽくなりました。解像度がもともと高い写真の場合は、パラメータを上げてやると良いと思います。

ここまで来ると、手前の木の葉っぱが筆で描いたようになっているのが分かると思います。それでも遠目に見ると写真に見えます。そのぐらい上手い油絵ということですね。まあ元々が写真なので当たり前ですが。
次に、neko.jpgを変換してみます。

すでに近くで見ると絵っぽくなっています。

パラメータ4とあまり変化ないですね。

猫の顔がわからなくなりました。遠目に見るといい感じですが、近くで見た場合に絵としてもギリギリ猫と分かる範囲ですね。パラメータとしては5か6が良いかなと思います。

地面と同化してしまってますね。元の写真を知っているので猫に見えなくもないですが、初めて見ると何だコレはになりそうです。
全4回に渡って掲載したPythonで画像処理プログラミングですが、一旦以上とします。
今後は、AIで画像分類とかもやりたいですね。面白いネタを思いついたらやってみようと思います。
コメント