Pynote

Python、機械学習、画像処理について

OpenCV - 画像にモザイクをかける方法について

モザイク処理をする方法

モザイク処理したい領域を最近傍補間で一度小さいサイズにリサイズしたあと、元のサイズに戻すことでモザイクをかけることができる。
コードとしては次のようになる。

元の画像

# Jupyter Notebook で画像を表示する。
from IPython.display import Image, display

def imshow(image):
    png = cv2.imencode('.png', image)[1]
    display(Image(png))
import cv2


def mosaic(img, scale=0.1):
    # 画像を scale (0 < scale <= 1) 倍にリサイズする。
    mosaiced = cv2.resize(img, dsize=None, fx=scale, fy=scale,
                          interpolation=cv2.INTER_NEAREST)
    # 元の大きさにリサイズする。
    h, w = img.shape[:2]
    mosaiced = cv2.resize(mosaiced, dsize=(w, h),
                          interpolation=cv2.INTER_NEAREST)
    return mosaiced

# 画像を読み込む。
img = cv2.imread('sample.jpg')
mosaiced = mosaic(img)

# 可視化する。
imshow(mosaiced)

モザイク後の画像

cv2.reisze() でリサイズするの際の補完方法で最近傍補完 (interpolation=cv2.INTER_NEAREST) を指定しないと、以下のようなぼやけた画像になってしまうので注意する。


画像の一部にモザイクをかける。

画像は numpy 配列なので、モザイクをかけたい領域をスライスで取り出して処理し、それを元の領域に代入すればよい。

import cv2


def mosaic(img, scale=0.1):
    # 画像を scale (0 < scale <= 1) 倍にリサイズする。
    mosaiced = cv2.resize(img, dsize=None, fx=scale, fy=scale,
                          interpolation=cv2.INTER_NEAREST)
    # 元の大きさにリサイズする。
    h, w = img.shape[:2]
    mosaiced = cv2.resize(mosaiced, dsize=(w, h),
                          interpolation=cv2.INTER_NEAREST)
    return mosaiced

# 画像を読み込む。
img = cv2.imread('sample.jpg')

# 画像の一部にモザイクをかける。
img[50:200, 50:200] = mosaic(img[50:200, 50:200])

# 可視化する。
imshow(img)


顔検出して、モザイク処理を行う。

これまでの応用で、顔検出した領域にモザイク処理を行う方法を紹介する。
顔検出処理には face_recognition ライブラリを使うので、使い方は以下を参照されたい。

pynote.hatenablog.com

import cv2
import face_recognition


def mosaic(img, scale=0.1):
    # 画像を scale (0 < scale <= 1) 倍にリサイズする。
    mosaiced = cv2.resize(img, dsize=None, fx=scale, fy=scale,
                          interpolation=cv2.INTER_NEAREST)
    # 元の大きさにリサイズする。
    h, w = img.shape[:2]
    mosaiced = cv2.resize(mosaiced, dsize=(w, h),
                          interpolation=cv2.INTER_NEAREST)
    return mosaiced


# 画像を読み込む。
img = cv2.imread('sample.jpg')

# 顔検出する。
locations = face_recognition.face_locations(img)

# 検出された顔領域に対して、モザイク処理を行う。
for top, right, bottom, left in locations:
    img[top:bottom, left:right] = mosaic(img[top:bottom, left:right])

# 可視化する。
imshow(img)