C#で顔検出をする(Accord.NETによる方法)
Accord.NET Frameworkのインストール
C#で画像からの顔検出を行う.Accord.NET Frameworkで提供されているメソッドを使う.Accord.NET Frameworkは,機械学習や統計,コンピュータビジョン等の機能を.NETに提供するフレームワーク.
「C#でWEBカメラを使う AForge.NETによる方法」の記事で使用したAForge.NET Frameworkの拡張である.
インストールはNuget経由で行える.Accord.NETには様々ならライブラリがあるが,今回はコンピュータビジョン用のライブラリであるAccord.Visionをインストールする.プロジェクトの右クリックメニューから「Nugetパッケージの管理」をクリックし,出てきたダイアログで「Accord.Vision」を検索しインストールする.
顔検出方法
Accord.NETではViola-Jones法によって顔検出を行う.手法の詳細はこことかこことかわかりやすいページがあるので書かないが,概要だけ引用.
1.前処理:大量の学習データを用いたAdaBoostによる識別器の学習
コンピュータビジョンのセカイ - 今そこにあるミライ (10) 顔検出の主流アルゴリズム「Viola-Jones法」 | マイナビニュース
2.高速な処理:Haar-Like特徴量を用いたCascade構造の識別による画像中の高速全探索
1.の識別器の学習の部分で,いかに良い学習データを使って学習をしているかどうかが顔検出の正確さにかなり影響する(はず).OpenCVで,学習済みの識別器がXMLファイルで公開されている.そのXMLファイルがAccord.NETにおいてもそのまま使えるため,今回はその学習器を使う.
OpenCVの「data/haarcascades」というフォルダに格納されている.OpenCVをダウンロードするか,ここから直接XMLファイルをダウンロードする.
ソースコード
以下が顔検出と表示部分のソースコードである.各クラス・メソッドの詳細はリファレンスマニュアルを参照.
// カスケード識別器の読み込み var cascadeFace = Accord.Vision.Detection.Cascades.FaceHaarCascade.FromXml(@"haarcascades\haarcascade_frontalface_default.xml"); // Haar-Like特徴量による物体検出を行うクラスの生成 var detectorFace = new Accord.Vision.Detection.HaarObjectDetector(cascadeFace); // 読み込んだ画像から顔の位置を検出(顔の位置はRectangle[]で返される) var image = new Bitmap(@"lena_std.tif"); var faces = detectorFace.ProcessFrame(image); // 画像に検出された顔の位置を書き込みPictureBoxに表示 var markerFaces = new Accord.Imaging.Filters.RectanglesMarker(faces, Color.Yellow); pictureBox1.Image = markerFaces.Apply(image);
実行すると,以下のよう検出された顔の位置が表示される.
顔以外の検出
ちなみに,Viola-Jones法は学習すれば顔以外のものも検出可能である.OpenCVの中に目とか口とか鼻について学習済みの識別器のXMLファイルも用意されているため,それを使えば検出できる.
上のサンプルに加えてhaarcascade_mcs_eyepair_big.xmlによって左右の目のペアを検出した結果は以下のようになる.
ソースコードは以下.
// カスケード識別器の読み込み var cascadeFace = Accord.Vision.Detection.Cascades.FaceHaarCascade.FromXml(@"haarcascades\haarcascade_frontalface_default.xml"); // Haar-Like特徴量による物体検出を行うクラスの生成 var detectorFace = new Accord.Vision.Detection.HaarObjectDetector(cascadeFace); // 読み込んだ画像から顔の位置を検出(顔の位置はRectangle[]で返される) var image = new Bitmap(@"lena_std.tif"); var faces = detectorFace.ProcessFrame(image); // 画像に検出された顔の位置を書き込みPictureBoxに表示 var markerFaces = new Accord.Imaging.Filters.RectanglesMarker(faces, Color.Yellow); image = markerFaces.Apply(image); // 以下,顔と同様に目の検出および表示 var cascadeEye = Accord.Vision.Detection.Cascades.FaceHaarCascade.FromXml(@"haarcascades\haarcascade_mcs_eyepair_big.xml"); var detectorEye = new Accord.Vision.Detection.HaarObjectDetector(cascadeEye); var eyes = detectorEye.ProcessFrame(image); var markerEyes = new Accord.Imaging.Filters.RectanglesMarker(eyes, Color.Blue); image = markerFaces.Apply(image); pictureBox1.Image = markerEyes.Apply(image);