やったこと
顔などの特定の物体がどこにあるかを認識するときにはカスケード分類器というものをつかいます(物体検出 — opencv v2.1 documentation)。ここではOpenCVによるアニメ顔検出ならlbpcascade_animeface.xmlで公開されているアニメ顔検出器を使っています。
#include <opencv2/opencv.hpp> using namespace std; using namespace cv; void detectAndDisplay(Mat image); CascadeClassifier face_cascade; int main(void){ //カスケードのロード face_cascade.load("lbpcascade_animeface.xml"); Mat image; image = imread("face.jpg"); detectAndDisplay(image); waitKey(0); return 0; } //認識と表示を行う関数 void detectAndDisplay(Mat image) { vector<Rect> faces; Mat frame_gray; //画像のグレースケール化 cvtColor(image, frame_gray, COLOR_BGR2GRAY ); //ヒストグラムの平坦化 equalizeHist(frame_gray, frame_gray); //顔の認識 face_cascade.detectMultiScale(frame_gray, faces); //顔を丸で囲む for(int i = 0; i<faces.size(); i++){ Point center(faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 ); ellipse(image, center, Size(faces[i].width/2, faces[i].height/2), 0, 0, 360, Scalar(255, 0, 255), 2, 8, 0); } //結果の表示 imshow("Result", image); }
コンパイル
g++ Anime.cpp -o anime `pkg-config opencv --cflags --libs`
結果
最後の画像以外は恐ろしく正確に検出できています。失敗したケースはおそらく目を閉じているのが原因だと思われます。目を閉じた顔も含めた学習用データを用意すれば精度が上がるかもしれませんが、今後の課題ということで。