よちよちpython

独習 python/Qpython/Pydroid3/termux/Linux

Python/openCVで画像の顔検知

はじめに

イギリスの神経学者で2015年に亡くなったコロンビア大学医学大学院教授 オリバー・サックス がおります。
彼は人間の知性や精神、認識といったテーマを医者の視点から扱った有名な本をいくつか出しております。

実際の医療現場からみる様々な症例を描いたノンフィクションでどれも大変興味深く、驚くようなことが書かれてあります。

その中に、人の顔を認識できなくなった人の話が載っていたかと思います。
何らかの原因で脳神経機能が上手く働かなくなったりするとそのようなことが起こることが稀にあるようです。

日本の妖怪の のっぺらぼう も、恐らくはそうした症例の話をキャラクター化させたものだろうと思います。
他人の首が伸びているように見える症状もあるとか。まるで ろくろっ首 です。

今回は妖怪の話ではなく、下手の横好き、画像認識に挑戦。
画像から人物の顔を検出し、顔を四角い枠で囲んだ新規画像を作成するPythonスクリプトを作ります。

参考にしたのは

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

上記の本でOpenCVによる顔認識は、Doccker上のUbuntuと、Macを使ってのやり方が載っています。

【画像あれこれ】

師匠は顔以外が検知されています。
さすがプロです。

f:id:chayarokurokuro:20190701180005j:plain

大仏

f:id:chayarokurokuro:20190701180111j:plain

ジャズギタリストのジャンゴラインハルト

f:id:chayarokurokuro:20190701180355j:plain

ディープパープルのジャケット写真

f:id:chayarokurokuro:20190701180444j:plain

ジェフベック。検知されず。

f:id:chayarokurokuro:20190701180627j:plain

ジミヘンドリックス。横向いているので未検知。
後ろのパーカッションは検知されている。

f:id:chayarokurokuro:20190701180656j:plain


目次


作成・実行環境

Windows10
Anaconda
Python3.6
JupyterNotebook


前準備

画像の準備

顔の写ってる物、写っていない物、顔の向きもいくつか違うものなど。


モジュールの準備

モジュールで「cv2」を使いますが、OpenCVをインストールすれば使えるようになります。
インストール方法をWindows上のAnacondaからのみ書いておきます。


openCVインストール方法 Anaconda Navigatorから

  1. 「Anaconda Navigator」を開く → 左端「Environments」を押す → モジュールの一覧が表示される
    (一覧の上に「Installed」と表示されていると思いますが、そのときインストール済の一覧が表示されています。)

  2. opencv」にチェックが入っているか確認 :「Search Packages」の検索窓に「opencv」と入力
    (一文字入力する毎に検索結果が一覧で表示されます。)

  3. opencv」が含まれていなければ、「Installed」を「Not installed」に変更 → 再び検索して確認

  4. 未インストール一覧が表示される → 「opencv」にチェックを入れる

  5. 画面右下に「Apply」「Clear」と出る → 「Apply」をクリック → チェックしたモジュールのダウンロードとインストールが始まる


openCVインストール方法 Anaconda コマンドから

※たぶんこれでできると思うが未確認。個人用メモ。

  1. コマンドプロンプトかAnaconda Promptを起動
  2. 仮想環境確認
    >conda info -eとコマンドを入力する → 仮想環境が表示される# conda enviroments 作成済みの仮想環境一覧

  3. 仮想環境を作動
    >conda activate 仮想環境名 → プロンプトのカレントディレクトリ表示の前に(仮想環境名) カレントディレクトリ >が表示されたらOK

  4. モジュールをインストール
    >conda install -c conda-forge opencv

  5. インストールされたか確認
    >conda list


ファイルとディレクト

作るのはPythonスクリプト1つ。画像を準備。ファイル名はなんでもOK。
任意の場所にディレクトリを作成し、pyスクリプトと顔認識させるjpg画像を保存。
.
|-- photo1.jpg
|-- 顔検知用のファイル.py


(要注意)カスケードファイルの保存場所を確認

ここが最大につまづいたポイントでした。
OpenCVカスケードファイル(CASCADE) というものを使います。拡張子はxml
カスケードファイル は、OpenCVをインストールすれば自動的にディレクトリにコピーされるとのこと。
人や猫の顔、目や鼻など、検出できるものが種類によっていくつか用意されています。(独自に作成も可能)

だが、それは一体どこに保存されている?

環境によって保存場所が異なるようです。

カスケードファイルの保存場所確認

参考
なぽろぐ opencvで顔認識しようとしたらカスケードファイルが見つからなかった

上のサイトにカスケードファイルの検索用Pythonスクリプトが載せてあります。参考にさせて頂きました。


Pythonスクリプト作成

ここからPythonスクリプトを作っていきます。

モジュールのインポート

#!/usr/bin/env python  
# coding: utf-8  
  
import cv2  #opencvをインストールすれば使用可能になる

入力ファイルを指定する

ファイル名は任意でOKですが、日本語だと画像の読込のとき実行エラーになりました。

image_file = "photo1.jpg"

カスケードファイルのパスを指定する

※ ↓ のカスケードファイルの保存場所「dir_name」はお使いの環境に合わせて変えてください。

dir_name = "C:\\Users\\ユーザー名\\Anaconda3\\pkgs\\libopencv-3.4.2-h20b85fd_0\\Library\\etc\\haarcascades\\"
cascade_file = dir_name + "haarcascade_frontalface_alt.xml"

画像の読込

image = cv2.imread(image_file)
print(image.shape)
(268, 188, 3)

グレースケールに変換

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=(20,20)
)

顔が認識されたかどうかで条件分岐処理

顔が検出できれば画像を新規作成、できなければ「no face」と出力。

if len(face_list) > 0:
    #認識した部分を囲む
    print(face_list)
    color = (0,0,255)
    for face in face_list:
        x,y,w,h = face
        cv2.rectangle(image,(x,y),(x+w,y+h),color,thickness=8)
        #描画結果をファイルに書き込む
    cv2.imwrite("output1.PNG",image)
else:
    print("no face")
[[157 171  23  23]]

最後に

正面を向いた写真でも検出されない場合は、顔検出の実行にあるminSize=(20,20)の数字をいろいろ変えてみてください。