OpenCVで顔検出
カスケード分類器というものを使って入力した画像から顔を検出します。
カスケード分類器
カスケードとは、連続したもの、数珠繋ぎになったものを意味します。
カスケード分類器は、いくつかの特徴量をまとめた学習データです。
ここでの顔検出の流れは、
- 入力画像の特徴を抽出
- カスケード分類器よりその特徴にマッチする部分を探す
となります。
また、カスケード分類器は以下の特徴のどれかを使って作成することができます。
- Haar-Like特徴
- LBP特徴
- HOG特徴
(これらの特徴の詳しい説明は省きます・・・)
OpenCVではHaar-Like特徴とLBP特徴のカスケード分類器を標準で提供しています。
OpenCVで顔検出
ここではHaar-Like特徴を用いた分類器を使用します。
#include "opencv2/opencv.hpp" #include <iostream> using namespace std; using namespace cv; Mat detectFaceInImage(Mat &image, string &cascade_file){ CascadeClassifier cascade; cascade.load(cascade_file); vector<Rect> faces; cascade.detectMultiScale(image, faces, 1.1,3,0,Size(20,20)); for(int i = 0;i < faces.size(); i++){ rectangle(image, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width,faces[i].y + faces[i].height),Scalar(0,200,0),3,CV_AA); } return image; } int main(int argc, char const *argv[]){ Mat image = imread(argv[1]); string filename = argv[2]; Mat detectFaceImage = detectFaceInImage(image, filename); imwrite(argv[3], detectFaceImage); return 0; }
detectMultiScaleメソッドでカスケード分類器に基づいて物体検出しています。
void detectMultiScale( const Mat& image, vector<Rect>& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size());
- imageは入力画像(の行列)
- objectsは矩形を要素とするベクトル
- scaleFactorは各画像スケールにおける縮小量
- minNeighborsは検出される領域の候補となる矩形は最低でもこの数の近傍矩形を含む
- minSizeは検出される領域が取りうる最小サイズ
$ g++ `pkg-config opencv --cflags` `pkg-config opencv --libs` -o pic_detect pic_detect.cpp
実行
$ ./pic_detect lenna.png /usr/local/opt/opencv/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml lenna_out.png
第二引数ではカスケード特徴器を指定しています。これを変えると顔検出ではなく目の検出などもできるようになります。
画像検出
まずはlenna
できました。
次は複数人の画像
凄い。
参考
OpenCVで物体検出
OpenCVで物体検出器を作成する① ~基礎知識~ | Webサイト制作ならプロフェッサ(東京都/品川区)HOG特徴の実装
画像からHOG特徴量の抽出 - QiitaHaar-Like/LBP/HOG特徴の比較
OpenCVの機械学習ツールとHAAR/LBP/HOG検出アルゴリズムの比較と検討その1 - リンゴをかじれ秋田県立大のhaar-like特徴量のpdf
http://www.akita-pu.ac.jp/neuro/seika/haarlike.pdf猿でもわかる顔検出の原理
サルでもわかる顔検出の原理 - 科学信仰detectMultiScaleについて
物体検出(detectMultiScale)をパラメータを変えて試してみる(minNeighbors編) | Workpiles