【Python】画像にモザイクをかける

 

こんにちは。のっくんです。

 

今日の記事では、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

ABOUTこの記事をかいた人

個人アプリ開発者。Python、Swift、Unityのことを発信します。月間2.5万PVブログ運営。 Twitter:@yamagablog