OpenCV Programming on Windows

OpenCVを用いて顔と目を認識する (cv::CascadeClassifier)


2016.07.19: created by

前提として理解しておくべき知識


顔認識

顔認識によって得られた矩形領域をROI (Region of Interest)として取り出して、 その領域に目の認識を適用します。

目と眼鏡を同時に認識させようと分類器として haarcascade_eye_tree_eyeglasses.xml を使ったら無限ループになるので、 目だけを認識させています(2016/07/25)。


プログラム作成の手順

  1. OpenCVを用いて顔を認識する (cv::CascadeClassifier)」 の Visual Studio 2015 のプロジェクトを用いて作成します。
  2. OpenCV と共に配布されている 「顔認識用の xml ファイル」 haarcascade_eye.xml を main.cpp と同じフォルダにコピーします。 そして、プロジェクトに追加します。
  3. これで、プロジェクト内の xml ファイルは2つになります。

  4. main.cppの内容を以下のように変更します。
  5. main.cpp (赤字の部分)
    #include <iostream>
    #include <sstream>
    
    #include <opencv2/opencv.hpp>
    
    using namespace std;
    
    void doJob() {
      
    string path = "";
      string cascadeName = "haarcascade_frontalface_alt.xml";
      string cascadeName2 = "haarcascade_eye.xml";
      cv::CascadeClassifier cascade, cascade2;
      if (!cascade.load(path + cascadeName)) throw runtime_error(cascadeName + " not found");
      if (!cascade2.load(path + cascadeName2)) throw runtime_error(cascadeName2 + " not found");
    
      cv::VideoCapture cap(0);
      if (!cap.isOpened()) throw runtime_error("VideoCapture open failed");  
      cv::Mat image;
      cv::Mat gray;
      while (1) {
        cap >> image;
        cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
        equalizeHist(gray, gray);
        vector<cv::Rect> founds, founds2;
        cascade.detectMultiScale(gray, founds, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30));
        for (auto faceRect: founds) {
          cv::rectangle(image, faceRect, cv::Scalar(0, 0, 255), 2);
          cv::Mat roi = gray(faceRect);
          cascade2.detectMultiScale(roi, founds2, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30));
          for (auto eyeRect: founds2) {
    	cv::Rect rect(faceRect.x + eyeRect.x, faceRect.y + eyeRect.y, eyeRect.width, eyeRect.height);
    	cv::rectangle(image, rect, cv::Scalar(0, 255, 0), 2);
          }
        }
        cv::imshow("video", image);
        auto key = cv::waitKey(1);
        if (key == 'q') break;
      }
      cv::destroyAllWindows();
    }
    
    int main(int argc, char** argv) {
      try {
        doJob();
      }
      catch (exception &ex) {
        cout << ex.what() << endl;
        string s;
        cin >> s;
      }
      return 0;
    }
    
  6. プログラムを実行するとRGB画像が表示されます。"q"キーで終了します。
  7. 左の例では目も正しく認識されていますが、右の例では左眉も目と誤認識しています。


      

  8. サンプルのプロジェクトはこちら


http://ynitta.com/