よちよちpython

独習 python/Qpython/Pydroid3/termux

Python/OpenCVで顔にモザイク

f:id:chayarokurokuro:20190703184627p:plain

はじめに

またまたOpenCVを使っての顔検出。今回はそれに モザイク をかけます。


スマホで写した画像に人の顔が写っているからモザイクをかけたい!」

「あら、ほら、あそこ… あそこに人の顔が見えるわ…あらいやだ…」等。

冝保愛子さん安らかに…(昭和人しかわからないか…)


前前回の顔検知の四角い枠の部分をモザイク処理に書き換えれば済むんですが、それだけではちと芸がない。

改良して、カスケードファイルの検索 と検出後の新規画像ファイルを 新規フォルダに保存 する部分を追加します。


実行方法

  1. 適当なフォルダを作って、下記のPythonスクリプトとモザイクをかけたい「.jpg 」 画像をそのフォルダに保存してください。
  2. 実行すると、Mosic_face という保存用フォルダが作成され、元の画像の顔を一括でモザイク処理してそこに自動保存します。


参考
- >クジラ飛行机Pythonによるスクレイピング&機械学習 開発テクニック』ソシム P.363


目次


環境

Windows10
Anaconda
Python3.6
JupyterNotebook


準備もの・作るもの

  1. 注意点

    OpenCVを使う際、フォルダ名やファイル名が日本語だと実行時にエラーが出るようです。

  2. 作るもの

    顔を検知しモザイクを掛けるPythonスクリプトを一つ。(適当な場所にフォルダを作って保存。)

  3. 画像の準備

    顔の写ってる物、写っていない物、顔の向きもいくつか違うものなど。(上と同じフォルダに「.jpg」 で保存。)

  4. モジュールの準備

    モジュールで「cv2」を使いますが、OpenCV をインストールすれば使えるようになります。
    カスケードファイル(検知用分類器)は OpenCVをインストール すればどこかに保存されます。


Pythonスクリプト作成

では作っていきます。

# フォルダのパス表示確認用。日本語だとエラーが出る
import os
dir_path = os.path.dirname(os.path.abspath('__file__'))
print("このファイルのフォルダパス\n",dir_path)

# 顔検知用とファイル検索用モジュールインポート
import cv2
import sys,os
from glob import glob

# カレントディレクトリ移動
os.chdir(os.path.dirname(os.path.abspath('__file__')))

# モザイク処理した画像保存用フォルダ作成
new_dir_path = os.path.join(dir_path ,"Mosaic_face")
try:
    # 保存用フォルダがなければ作成
    if glob(new_dir_path) is not None:
        os.mkdir(new_dir_path)
    # すでに保存フォルダがあれば
except:
    pass


# ディレクトリ内のjpgファイルを全て取得しリスト化
image_files = glob('*.jpg')


# 元画像ファイル名を拡張子と切り離し、一つずつ目の検出処理
for image_file in image_files:
    # 切り離す
    image_file_name_split = image_file.split(".")
    # 拡張子より前の部分
    image_file_name = image_file_name_split[0]
    # 拡張子
    image_file_extension = image_file_name_split[1]
    
    print(image_file_name)

    # カスケードファイルの検索 (デフォルトの「cv2」フォルダから検索します。)
    cascade_file_name = "haarcascade_frontalface_alt.xml"                       # 使用するカスケードファイル
    cv2_path = os.path.dirname(str(cv2).split()[-1].strip(">").strip("'"))      # 「cv2」フォルダの検索
    cascade_dir_path = os.path.join(cv2_path,"data")                            # 「cv2のパス」と直下の「data」フォルダを連結
    cascade_file = cascade_dir_path + "\\" + cascade_file_name                  # 使用するカスケードファイルのフルパス
    

    # 画像の読込
    image = cv2.imread(image_file)

    # グレースケールに変換
    image_gs = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)

    # カスケードファイルの読込
    cascade = cv2.CascadeClassifier(cascade_file)

    # 顔検出の実行(リスト型)
    face_list = cascade.detectMultiScale(
        image_gs,
        scaleFactor=1.1,
        minNeighbors=1,
        minSize=(100,100)
    )

    # 顔が検出されたら(リスト要素があれば)
    if len(face_list) > 0:
        
        # モザイク処理
        color = (0,0,255)
        for face in face_list:
            x,y,w,h = face
            
            # 顔の切り抜き
            face_image = image[y:y+h , x:x+w]
            # 切り抜いた画像を指定倍率で縮小
            mosaic_rate = 20
            face_image = cv2.resize(face_image,(w//mosaic_rate, h//mosaic_rate))
            # 縮小した画像を元のサイズに戻す
            face_image = cv2.resize(face_image, (w, h), interpolation = cv2.INTER_AREA)
            # 元の画像に貼り付ける
            image[y:y+h , x:x+w] = face_image
            
    
            #新規ファイル名作成
            New_file_name = new_dir_path + "\\" + image_file_name + "MoosaicFace.PNG"
        
            # 描写結果をファイルに書き込む
            cv2.imwrite(New_file_name,image)
    
    # 顔が検出されなければ
    else:
        print(image_file_name + "は顔が検出できませんでした")
        
print("\n終了しました。\nMosaic_faceフォルダを確認してください。")




実行結果

    このファイルのフォルダパス
     C:\Users\ユーザー名\何とかかんとか\MosaicFace
    ahoSakata
    ahoSakataは顔が検出できませんでした
    Aska
    django
    Kiyohara
    Taki
    Makihara
    Shimizu
    Tashiro
    Uchida
    Ushiku_Daibutsu
    Ushiku_Daibutsuは顔が検出できませんでした
    
    終了しました。
    Mosaic_faceフォルダを確認してください。

処理後の画像

f:id:chayarokurokuro:20190703184809p:plain

f:id:chayarokurokuro:20190703184853p:plainf:id:chayarokurokuro:20190703184940p:plainf:id:chayarokurokuro:20190703185019p:plainf:id:chayarokurokuro:20190703185050p:plainf:id:chayarokurokuro:20190703185120p:plainf:id:chayarokurokuro:20190703185155p:plain

以下は検出されなかった。
OpenCVは高度な分類機能付きか。

f:id:chayarokurokuro:20190703185250j:plainf:id:chayarokurokuro:20190703185345j:plain