Python OpenCVによる顔認証とモザイク処理

'21/07/17更新:モザイクをかける関数を追記しました。

 簡単に出来ます。その理由は、「haarcascade_frontalface_default.xml」のようなカスケード分類器を活用するためです。これは、機械学習でいう特徴量をすでに学習済みである学習分類器(オブジェクトファイル)のことです。それは、本記事の一番下のリンク先でダウンロードと導入方法を記載しています。

 本記事では、顔検出のテスト用画像にスタートレック ヴォイジャーの乗組員8名が正面を向いて写っている写真を借用しました(下記リンク参照)。http://buzz-plus.com/article/2016/12/29/star-trek-voyager/

f:id:HK29:20191013015039j:plain

下図は、本プログラムを実行して顔検出した結果です。本プログラムは別の画像ファイルであっても人の画像が正面から写っていれば反応します(そのようなカスケードファイルを使用しているため)。もし、人でない猫や犬、もしくは顔が横向いてたりしたら、顔とは認識されないだけです。

f:id:HK29:20191013015113j:plain

下図は、本プログラムを実行してモザイクをかけた結果です。その仕組みは、検出した顔の範囲を一旦切り出します。それを縮小して解像度を落とした後に、元のサイズへ戻すことでモザイクとなります。

f:id:HK29:20210717172539j:plain

▼本プログラム

※注意点:[ユーザー名]と記載の箇所は、自分のPCのユーザー名を入力する。あるいは、カスケードファイルを保存した場所のパスを入力します。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os, glob
import cv2
import pandas as pd
import numpy as np

# 顔検出して赤枠で囲む関数
def image_recognition_func(input_fig, cascade_file, scale_list):
    # カスケードファイルをOpenCVで読み込む(学習分類器)
    cascade = cv2.CascadeClassifier(cascade_file)

    coordinate_data_list = []
    for i, e in enumerate(scale_list):
        img = cv2.imread(input_fig)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        face_list = cascade.detectMultiScale(gray, scaleFactor=e) # scaleFactor(>1)
        buf = []

        # 認識した顔の輪郭を赤枠で囲む
        for (x, y, w, h) in face_list:
            cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 3)
            cv2.imwrite("recognition_face" + input_fig[:-4] + str(i) + '.jpg', img)
            # 顔の位置座標をリストへ格納
            buf.append((x, y, w, h))
            
        buf.sort()
        coordinate_data_list.append(buf)
        # メモリ上のイメージオブジェクトを削除
        del img
    
    # 認識した顔の位置座標をcsvファイルへ保存するための処理
    df = pd.DataFrame(coordinate_data_list)
    df = df.T
    print(df)
    df.to_csv('recognition_face_data_list.csv')


# 顔検出してモザイクをかける関数
def image_recognition_and_mosaic_func(input_fig, cascade_file, scale_list):
    # カスケードファイルをOpenCVで読み込む(学習分類器)
    cascade = cv2.CascadeClassifier(cascade_file)

    coordinate_data_list = []
    for i, e in enumerate(scale_list):
        img = cv2.imread(input_fig)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        face_list = cascade.detectMultiScale(gray, scaleFactor=e) # scaleFactor(>1)

        # モザイク処理
        for (x, y, w, h) in face_list:
            face= img[y:y+h, x:x+w] # 顔部分をイメージ抽出
            reduc = cv2.resize(face, (int(w * 0.05), int(h * 0.05))) # 小さいサイズへ変換(ここでは5%)
            mosaic = cv2.resize(reduc,(w, h)) # 元サイズへ戻す
            img[y:y+h, x:x+w] = mosaic # 元へはめ込む(モザイクになる)
            cv2.imwrite("mosaic_face" + input_fig[:-4] + str(i) + '_face.jpg', img)
        # メモリ上のイメージオブジェクトを削除
        del img


def main():
    # ファイル名「*face*」を全削除する
    for f in glob.glob('*face*'):
        os.remove(f)

    # 検出範囲を複数設定する
    scale_list = np.arange(1.1, 1.5, 0.1).tolist()
    print(scale_list)
    
    # 顔認証関数の呼び出し
    image_recognition_func(fig_path, cascade_path, scale_list)

    # 顔認証してモザイクをかける関数の呼び出し
    image_recognition_and_mosaic_func(fig_path, cascade_path, scale_list)


if __name__ == '__main__':
    # 顔認証のカスケードファイルがある保存先パスを指定
    cascade_path = r'C:/Users/[ユーザー名]/Anaconda3/Lib/site-packages/cv2/data/haarcascade_frontalface_alt.xml'

    # 顔認証するファイルパスを指定
    fig_path = 'star-trek-voyager.jpg'
    
    # メイン関数の実行
    main()

OpenCVのインストールとカスケードファイルのダウンロード方法

hk29.hatenablog.jp

以上

<広告>