賢くなりたい~賢くなりたくない~♪

見たもの聞いたもの何でも発信!!

OpenCV + Python で画像内の顔を自動検出して匿名化【ソースコード付き・機械学習】

f:id:ooenoohji:20181110235953j:plain
本記事ではpythonでの画像処理を紹介します。特にOpenCVライブラリを使った画像内の顔検出処理について、ソースコード付きで解説します。出力としては上のような画像が得られます。
画像処理における顔検出は王道ですので、OpenCVの勉強を始めた方は是非本記事を参考にして、次へのステップアップに活かしてください。
以下、実験環境の準備、顔検出のソースコード、簡単な解説を示します。

OpenCVとは

f:id:ooenoohji:20181024055217j:plain
以前の記事にも書いたのですが、画像処理のライブラリです。おそらく世界で一番有名なのではないでしょうか。私はいろいろな国で画像処理関係の仕事をしたり、国際会議に出てきましたが、利用率はかなり高いです。
というのも、かなり多くの、そして高度な画像処理がライブラリ内に揃っているからです。ノイズ除去、特徴抽出から、機械学習ベースの認識処理、そしてディープラーニングまで、コンピュータヴィジョン全般を網羅しています。
さらに近年、pythonでも使えるようになり、簡単にライブラリを利用することができるようになりました(以前は設定が結構面倒だった)。

実験環境の準備(OpenCVのインストール)

これは本ブログの前回の記事を参考にしていただけたらと思います。以下のリンクからOpenCVのインストール手順を見ることができます。
kashikoku.instafr.com

識別器を用いた顔検出処理

以下、OpenCVを用いた顔検出処理のソースコードを示します。アルゴリズムとしては

Haar-like特徴量をカスケード型分類器に入力して画像内の各領域を「顔/顔以外」で分類する

というようなことをしています。本記事では詳しくは説明しませんが、興味のある方はググればたくさん論文や解説ページが出てきます。



【スポンサーサイト】

ソースコード

import cv2

# 識別器の指定 : Haar-based-classifier
cascade_path = "C:\\Users\\hogehoge\\Anaconda3\\envs\\OpenCV\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascade_path)

# 処理対象の画像ファイル(違うフォルダにある場合はそこへのパスも含める)
image_path = "testimage.jpg"

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

# 画像変換 : カラーからグレースケールへ
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 画像内にある"顔"を検出(顔を含む rectangle を返り値として受け取る)
face_rects = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=1, minSize=(50,50))

# 顔を含む rectangle を画像に描画
color = (255, 255, 255) #白い rectangle を書く
if len(face_rects) > 0:

    for rect in face_rects:
        cv2.rectangle(image, tuple(rect[0:2]), tuple(rect[0:2]+rect[2:4]), color, thickness=-1) # thickness=-1 は rectangle を塗りつぶすの意味

    # rectangle が描画された画像をオリジナルの画像とは別名で保存
    cv2.imwrite("detected_" + image_path, image)

各処理はソースコード内のコメントを見ていただければわかると思います。
少し付け加えるとすれば、まず "cascade_path"、これはOpenCVをインストールすると一緒にダウンロードされる「学習済みの識別器」が記述されたxmlファイルを指定しています。ファイルが保存されている場所は環境によって違うのですが、私はAnacondaで"OpenCV"という仮想環境を作成し、そこにOpenCVをインストールしたので、ソースコードに書いてある場所に保存されています(hogehogeはユーザ名です)。もちろん、xmlファイルを違う場所に移動して、そこを指定してもいいです。
また、detectMultiScale に幾つかパラメータがあると思います。例えば miSize は検出する顔の大きさの最小サイズ(ピクセルサイズなので解像度によって調整しましょう)です。微調整が必要な方はそれぞれのパラメータについて調べてみましょう。

出力結果

f:id:ooenoohji:20181111015429j:plain
本記事の最初の画像にも示しましたが、こんな感じです。ソースコード内で cv2.rectangle のパラメータ "thickness"を「-1」に設定していますが、これによって、検出した顔を含む四角は塗りつぶされます。このパラメータを、例えば3などに設定すると、太さが3ピクセルの四角(内側はオリジナル画像のまま)になります。本記事ではプライバシー保護のため、塗りつぶしました。

誤検出

f:id:ooenoohji:20181111015737j:plain
水色の丸で囲んだところは誤検出です。パラメータによってはこういうこともあります。この場合、すごく簡単に解決するなら、"detectMultiScale" におけるminSizeの値を大きくしてあげれば、この画像の中の誤検出は消せるでしょう。ですが、当然、他の画像に適用した場合、小さく写った顔は検出されなくなります。

その他の物体の検出

それからxmlファイルについてもう一つ、今回用いた"haarcascade_frontalface_alt.xml"は人間の顔(正面)を検出する識別器です。これを他のファイルに置き換えれば、例えば猫の顔や眼鏡の検出なども行えます。例えば以下のようなものがあります。

  • haarcascade_frontalcatface.xml : 猫の顔検出
  • haarcascade_eye_tree_eyeglasses.xml : 眼鏡検出

その他にもいろいろあるので試してみましょう。

まとめ

とにかく豊富で高度な処理が簡単に使えるOpenCV、是非使ってみてください。書籍もたくさん出ています。最近はpython+OpenCVの本も出ているようです。

OpenCVとPythonによる機械学習プログラミング

OpenCVとPythonによる機械学習プログラミング

  • 作者:Michael Beyeler
  • 発売日: 2018/08/29
  • メディア: 単行本(ソフトカバー)
また、C++になってしまいますが、OpenCVについて詳細に解説されている本がこちら。さらに、以下の本は初めての方には少々難解なVisual Studioでの設定が書かれています。
実践OpenCV 3 for C++画像映像情報処理

実践OpenCV 3 for C++画像映像情報処理

興味のある方は是非上の書籍も参照してみてください。
それにしても、こんなに簡単に実装できるなんて、長年画像処理の研究をしていた私は涙目です。。今後も本ブログで実装例を示していくので(画像処理や機械学習ディープラーニング系が多いと思います)、良かったらまた見に来てください。