Visual Studio 2013 Express
 Visual C++( アンマネージドコード )
 OpenCV 3.1

■291.OpenCV 顔検出 Prev Top Next
関連ページ:

今回はmp4の動画から顔検出します。分類器にはOpenCVにサンプルとして存在するxmlファイルを使用します。 機械学習については後程取り上げます。

横顔や首を傾げたりすると認識できなかったり、シミュラクラ現象のように模様を誤認識することがありますが、 それなりに正しく検出されます。

実行には opencv_ffmpeg300_64.dll が必要となります。


---main.cpp---

#include <windows.h>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>

#pragma comment( lib, "opencv_world300d.lib" )
#pragma comment( lib, "winmm.lib" )

void onMouse(int event, int x, int y, int flags, void* param)
{
   // 何らかのマウス操作を行われたとき下記の状態であればイベントが発生する
   switch (flags)
   {
   case CV_EVENT_FLAG_LBUTTON: // 左ボタンが押されている
      bool* b = (bool*)param;
      *b = true;
      break;
   }
}

int main(int argc, const char* argv[])
{
   int hr = -1;

   try
   {
      cv::Mat src, dst, gray;
      std::vector<cv::Rect> objects;

      // Video読み込み
      cv::VideoCapture cap = cv::VideoCapture("D:/TEMP/MaverickProj/Image/OpenCV/53/video.mp4");
      if (cap.isOpened() == false)
      {
         CV_Error(CV_StsError, "cv::VideoCapture() Failed");
      }

      // 動画のfpsから1フレームあたりの時間( ミリ秒 )を計算
      long fps = 1000 / (DWORD)cap.get(CV_CAP_PROP_FPS);

      std::string filename = "D:/TEMP/MaverickProj/Image/OpenCV/53/haarcascade_frontalface_alt.xml";

      cv::CascadeClassifier cascade;

      // ファイルから分類器を読み込み.以前の内容は破棄
      if (!cascade.load(filename))
      {
         CV_Error(CV_StsError, "cv::CascadeClassifier::load() Failed");
      }

      // ウィンドウを生成
      cv::namedWindow("dst", cv::WINDOW_AUTOSIZE);

      bool onClick = false;
      cv::setMouseCallback("dst", onMouse, &onClick);

      while (true)
      {
         DWORD now = timeGetTime();
         
         // cv::VideoCapture から1フレーム分の画像を取得してcv::Matに格納
         cap >> dst;

         if (onClick == true)
         {
            break;
         }

         // 取得できないときは終了
         if (dst.empty())
         {
            break;
         }

         // グレースケール変換
         cv::cvtColor(dst, gray, CV_BGR2GRAY);

         // 入力画像中から異なるサイズの物体を検出
         cascade.detectMultiScale(
            gray,                  // CV_8U 型の行列.ここに格納されている画像中から物体が検出される
            objects,               // 検出した物体の矩形
            1.1,                   // 各画像スケールにおける縮小量
            3,                     // 物体候補となる矩形は,最低でもこの数だけの近傍矩形を含む必要がある
            0,                     // 新しいカスケードでは利用されない
            cv::Size(30, 30)       // 物体がとりうる最小サイズ.これより小さい物体は破棄
            );

         for (auto object : objects)
         {
            // 矩形の描画
            cv::rectangle(dst, object, cv::Scalar(0, 0, 255), 1);
         }

         // ウィンドウに動画から取得した画像を表示
         cv::imshow("dst", dst);

         long t = timeGetTime() - now;
         long wait = fps - t;
         if (wait < 0)
         {
            wait = 1;
         }
         cv::waitKey(wait);
      }

      hr = 0;
   }

   catch (cv::Exception ex)
   {
      std::cout << ex.err << std::endl;
   }

   // ウィンドウの破棄
   cv::destroyAllWindows();

   return hr;
}


Prev Top Next
inserted by FC2 system