こんにちは。のっくんです。
今日の記事では、Pythonを使って画像にモザイクをかける方法をご紹介します。
[speech_bubble type=”ln” subtype=”L1″ icon=”ilust/cat2_1_idea.png” name=”ネコ”]モザイクってあのグニャグニャしたやつ?顔を隠したり、、[/speech_bubble] [speech_bubble type=”ln” subtype=”L1″ icon=”profile_face.png” name=”のっくん”]そうだよ。でも残念ながらOpenCVにはモザイク処理のライブラリが無いんだ。だから、原理から理解して自分で作るよ。大丈夫、10行ぐらいで作れちゃうんだ。[/speech_bubble]
[toc]
この記事で使用するツール
・Python 3.6
・Jupyter Notebook
・opencv-python
モザイクの原理
モザイクは特殊な処理ではなく、一度縮小してから拡大すればできます。

左が5×5の元画像で、それを1×1の画像に縮小します。縮小する方法はいくつかありますが、上の例では画素の平均値を計算するイメージです。それを再度5×5に戻すと1つの画素が全体に引き伸ばしたような形になり、モザイクができるんです。
ちなみに、縮小する方法(アルゴリズム)の種類は以下の通り。
・Lanczos法
・平均画素法
・バイキュービック法
それぞれの仕組みはよく分かりませんが、ぶっちゃけ見た目に大差ないのであまり気にしなくて良いです。
縮小してから拡大することだけ覚えておきましょう。
プログラム
私のプロフィールである以下の画像にモザイクをかけるプログラムを作成します。

Jupyter Notebookを開いてください。
matplotlibを使ってインラインで画像を表示しますのでセルで以下のコードを実行しておきます。
%matplotlib inline
次にモザイク処理を行うコードを書いていきます。モザイクをかける処理は他でも使えるので以下のようにモジュール化しておきます。
mosaic.py
import cv2 # imgは元画像、rectはモザイクをかける座標 def put_mosaic(img, rect): # 縮小するサイズ size = (10, 10) # モザイクをかける座標を取得、左上(x1,y1),右下(x2,y2) (x1, y1, x2, y2) = rect # モザイクをかける幅と高さ w = x2 - x1 h = y2 - y1 # モザイクをかける部分を元画像から切り取り area = img[y1:y2, x1:x2] # 縮小 small = cv2.resize(area, size) # 縮小した画像を拡大,zoomにはモザイク画像が入る zoom = cv2.resize(small, (w, h), interpolation=cv2.INTER_AREA) # 元の画像へモザイク画像をコピー img2 = img.copy() img2[y1:y2, x1:x2] = zoom return img2
mosaic.pyとmosaic-test.ipynbを同じディレクトリに配置してください。ジュピターノットブックで以下のようにインポートして使います。
mosaic-test.ipynb
import matplotlib.pyplot as plt import cv2 import mosaic img = cv2.imread("profile.jpg") mos = mosaic.put_mosaic(img, (200,200,800,800)) plt.imshow(cv2.cvtColor(mos, cv2.COLOR_BGR2RGB)) plt.show()
put_mosaicの引数には、モザイクをかける画像と座標を指定してください。

実行すると、縦、横それぞれ200から800のエリアにモザイクがかかっています。うまくいきましたね。
参考
PythonによるAI・機械学習・深層学習アプリのつくり方、ソシム、2018.6