ぴよ猫ちゃんの機械学習

AI、人工知能、機械学習について色々記事にしています。

OpenCVで画像データから顔を抽出する方法

OpenCVで顔認識 顔認識を作ってみたいんだけど、どういう方法があるの?
OpenCVで顔認識 顔認識はOpenCVを使うのが簡単です。
やり方を説明します💛

今回はOpenCVで顔認識を実装する方法を解説します。
本記事の顔認識は、特定の人物の顔を識別するものではなく、写真などの画像から人物の顔部分を抽出する方法になります。

1.顔認識を行う3つの方法

顔認識の方法は大きく3つ

顔認識を行うには大きく3つの方法があります。

  1. GoogleAPIなどのAPIを使う
  2. オープンソースOpenCVを使う
  3. 自作する

GoogleAPIなどのAPIを使う

顔認識を行う最も手軽な方法がGoogle, Amazonなどが提供するAPIを使う方法です。

APIを用いた画像認識】
Googleの画像認識APIは最強!!画像認識API徹底比較結果 - ぴよ猫ちゃんの機械学習

APIはただ呼び出せばよいので最もお手軽です。 しかし、APIはサーバで動くのでクライアントで処理するより遅いことと、APIの使用料がかかることがデメリットとして挙げられます。

オープンソースOpenCVを使う

顔認識をするもう一つの方法がOpenCVを使う方法です。 OpenCVインテルが開発したオープンソースのコンピュータビジョン向けライブラリで、画像解析機能を手軽に実現することが出来ます。

OpenCVはクライアントだけで画像解析が出来るので、APIを用いるより処理が早く使用料もかかりません。 ただし、APIを用いるよりは実装の難易度があがります。(とは言え、それほど難しいものでもありません。)

自作する

顔認識をする最後の方法がkerasやTensorflowを用いて自作することです。 動画をリアルタイムで画像解析するなど、高い性能が必要でOpenCVの精度、性能では満足できない場合は選択肢となります。 インテルの技術者に勝つぞ!という意欲のある方はチャンレンジしてみて下さい。

顔認識の方法まとめ

結論を述べると顔認識を行う場合、OpenCVが最もお勧めの方法です。 クラアインとだけで処理できるので処理が早いですし、お金もかかりません。 APIを使うより実装難易度はあがりますが、そこまで難しいプログラムではありませんので、GoogleなどのAPIを使うよりOpenCVを使った方が良いと思います。 なので、この記事ではOpenCVを用いて顔認識(画像から顔を抽出する方法)について解説します。

2.OpenCVで顔認識(Java

OpenCVとは

OpenCVインテルが開発したオープンソースのコンピュータビジョン向けライブラリです。 画像分割、領域結合、輪郭検出などの画像処理や、物体検出などを手軽に行うことが出来ます。

opencv.org

OpenCVを扱える言語

OpenCVC/C++JavaPythonで使うことが出来ます。
サーバーサイドのプログラムで顔認識をする場合は、PythonJavaが選択肢となります。
Android端末で顔認識を行う場合はJavaの1択となります。
今回は、Androidアプリで顔認識を行う方法を紹介したいと思います。

OpenCVの開発環境を整える

OpenCVの開発環境を整える方法はQiitaに綺麗にまとまっていたので、Qiitaに丸投げします。
以下の記事がとても参考になります。

qiita.com

顔評価器をresフォルダに格納する

OpenCVは予め学習済の評価器を用いて顔認識を行います。 OpenCVをインストールしたディレクトリの「OpenCV-android-sdk\sdk\etc\haarcascades」に学習済の評価器が格納されているので、この中の「haarcascade_frontalface_alt.xml」をAndroidプロジェクトのres\assetsフォルダに格納します。

◆ haarcascade_frontalface_alt.xmlの格納場所(例:D:\opt\OpenCV-android-sdkOpenCVをインストールしている場合) f:id:shibayu2002:20191019095231p:plain

◆ haarcascade_frontalface_alt.xmlの格納先 f:id:shibayu2002:20191019095510p:plain

OpenCVに予め用意されている学習済の評価器

ファイル名 内容
haarcascade_eye.xml
haarcascade_eye_tree_eyeglasses.xml 眼鏡
haarcascade_frontalcatface.xml 猫の顔(正面)
haarcascade_frontalcatface_extended.xml 猫の顔(正面)
haarcascade_frontalface_alt.xml 顔(正面)
haarcascade_frontalface_alt2.xml 顔(正面)
haarcascade_frontalface_alt_tree.xml 顔(正面)
haarcascade_frontalface_default.xml 顔(正面)
haarcascade_fullbody.xml 全身
haarcascade_lefteye_2splits.xml 左目
haarcascade_licence_plate_rus_16stages.xml ロシアのナンバープレート(全体)
haarcascade_lowerbody.xml 下半身
haarcascade_profileface.xml 顔(証明写真)
haarcascade_righteye_2splits.xml 右目
haarcascade_russian_plate_number.xml ロシアのナンバープレート(数字)
haarcascade_smile.xml 笑顔
haarcascade_upperbody.xml 上半身

顔認識のプログラム(Java

private static final String FILE_NAME = "haarcascade_frontalface_alt.xml";

// 顔認識を行う操作
private void xxxxxx(){
  // 1.評価器を読み込む
  File file = new File(getFilesDir().getPath() + File.separator + FILE_NAME);
  CascadeClassifier cascadeClassifier = new CascadeClassifier(file.getAbsolutePath());

  // 2.評価対象の画像をmatインスタンスに格納する
  Mat mat = new Mat();
  Utils.bitmapToMat(mBitmap, mat);  // mBitmapは評価対象画像のBitmapデータ

  //  3.OpenCVを実行し評価対象画像から顔の部分を抽出する
  //        抽出した顔の部分の画像はMatOfRectインスタンスに格納される
  MatOfRect matOfRect = new MatOfRect();
  cascadeClassifier.detectMultiScale(mat, matOfRect);

  // 4.抽出された顔の部分毎に処理を行う(MatOfRectの配列分処理を行う)
  Bitmap resultImg = Bitmap.createBitmap(mBitmap);
  File mFile = null;
  for (Rect rect : matOfRect.toArray()) {
    if(rect.width < 100 && rect.height < 100){
      // 小さい矩形は無視
    } else {
      // 5.元画像の顔部分を四角で囲む
      Imgproc.rectangle(mat, new Point(rect.x, rect.y),
          new Point(rect.x + rect.width, rect.y + rect.height),
          new Scalar(0, 255, 0), 5);
    }
  }
  // 結果をBitmapに格納
  Utils.matToBitmap(mat, bitmap);
}

3.顔認識でスカウターを作って遊んでみた

顔認識を利用してスカウターを作ってみましたーーーー。

syuuai.hatenablog.com

面白いと思うので良ければダウンロードして下さいm(_ _)m
AIで本当に戦闘力を測定します。(;^_^A

蛇足。
今回作ったスカウターは顔部分を矩形で括る様にしましたが、ドラゴンボールの作中だと顔部分ではなくて体全体が黄色い線で覆われましたね~~。
これも今の画像認識技術なら難なく出来ると思います。アニメの中の技術が現実になってきて、世の中、進歩したなーと思います。

f:id:shibayu2002:20191019100508p:plain
スカウター

画像解析API徹底比較 それではまたー💛