Python 機械学習

【Python】Face RecognitionとOpenCVで人物の顔にモザイク処理を行う

この記事は約7分で読めます。

 

 

前準備と実行環境

 

Face Recognitionはディープラーニングが使われているのでGPUが必要になります。

自分のPCにはGPUが無かったのでColabで動作することを想定しています。

 

ColabでGPUを使用する

 

Face Recognition はインストール時でdlibをビルドが必要になるためGPUを使わないと以下のようなエラーになります。

 

Error while calling cudaGetDevice(&the_device_id) in file /tmp/pip-install-8rhciq4o/dlib_838b2895161a4c358d1084826c17d7fd/dlib/cuda/gpu_data.cpp:204. code: 100, reason: no CUDA-capable device is detected

 

これを回避するためにまずGooglecolabratoryでコード実行に際に「GPU」で実行するように設定を変更します。具体的にはNotebookの「編集」→「ノートブックの設定」→「ハードウェア アクセラレータ」を「GPU」に変更して「保存」で設定完了です。

 

参照:https://pyming.info/2021/06/04/colab_gpu/

 

ライブラリのインストール

 

次にライブラリをインストールします。

 

$ pip install face_recognition

 

インストールが完了したらライブラリを読み込みます。

 

import face_recognition

 

画像を読み込む

 

OpenCVではまず対象の画像を読み込む必要があります。

今回使用するのは以下の画像です

この画像の顔の部分を判定してそこにモザイク処理を行います

 

 

まず、OpenCVで画像を読み込むときはcv2.imread関数を使います。

 

import os
import cv2
import face_recognition
import matplotlib.pyplot as plt
import requests

img_url = 'https://tkstock.site/wp-content/uploads/2022/12/370392d75ef83e55608e451f6e8c4da6864a4.jpg'
r = requests.get(img_url)
img_path = 'sample.jpg'
with open(img_path, 'wb') as saveFile: 
    saveFile.write(r.content)

img = cv2.imread(img_path)
# 画像の表示
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # OpenCV は色がGBR順なのでRGB順に並べ替える
plt.show()

 

<実行結果>

 

 

Face Recognitionで顔枠を判定して座標を取得する

 

# 画像の顔の座標を取得する
loc = face_recognition.face_locations(img, model="hog")
loc

 

<実行結果>

[(110, 397, 239, 268)]

 

FaceRecognitionが顔と判定した部分を確認する

 

次はこの座標と画像データを使ってfacerecognitionが顔と判定した部分を赤枠で囲ってプロットしてみます。

 

# 顔の枠を判定してプロットする関数
def draw_face_locations(img, locations):
    fig, ax = plt.subplots()
    ax.imshow(img)
    ax.set_axis_off()
    for i, (top, right, bottom, left) in enumerate(locations):
        # 長方形を描画する。
        w, h = right - left, bottom - top
        ax.add_patch(plt.Rectangle((left, top), w, h, ec="r", lw=2, fill=None))
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # OpenCV は色がGBR順なのでRGB順に並べ替える
    plt.show()
    return

# 関数実行
draw_face_locations(img, loc)

 

<実行結果>

イイ感じに判定できているのが分かります。

 

赤枠部分にモザイクを掛ける

 

次はこの赤枠部分にモザイクを掛けます。

 

# モザイク処理
def pixelate(src, ratio=1):
    small = cv2.resize(src, None, fx=ratio, fy=ratio, interpolation=cv2.INTER_NEAREST)
    return cv2.resize(small, src.shape[:2][::-1], interpolation=cv2.INTER_NEAREST)


def pixelate_area(src,loc,ratio=0.1):
  dst = src.copy()
  for i, (top, right, bottom, left) in enumerate(loc):
        w, h = right - left, bottom - top
        dst[top:top + h, left:left + w] = pixelate(dst[top:top + h, left:left + w], ratio)
  return dst

# 画像の表示
dst = pixelate_area(img,loc,ratio=0.1)
plt.imshow(cv2.cvtColor(dst, cv2.COLOR_BGR2RGB)) # OpenCV は色がGBR順なのでRGB順に並べ替える
plt.show()

 

<実行結果>

 

こんな感じで先ほど赤枠で囲まれた部分にモザイクが掛かります。

 

モザイク処理した画像を保存・出力する

 

最後にモザイクを掛けた画像を出力して確認してみます

 

#ファイル出力
cv2.imwrite('output.jpg', dst)

 

ここでファイル名に拡張子をつけていないと以下のようなエラーが起こるので注意してください。

 

cv2.error: OpenCV(4.1.1) C:\projects\opencv-python\opencv\modules\imgcodecs\src\
loadsave.cpp:662: error: (-2:Unspecified error) could not find a writer for the
specified extension in function ‘cv::imwrite_’

 

ちなみに、出力は以下の形式に対応しているようです。

 

jpg, jpeg, jpe, jp2, png, webp, bmp, pbm, pgm, ppm,
pxm, pnm,  sr, ras, tiff, tif, exr, hdr, pic, dib

 

 

コメント

  1. […] 参考:【Python】Face RecognitionとOpenCVで人物の顔にモザイク処理を行う […]

  2. […] 関連記事:【Python】Face RecognitionとOpenCVで人物の顔にモザイク処理を行う […]

タイトルとURLをコピーしました