はじめに

顔検出の仕組みは特徴点量というのを計算し、それを正解画像の特徴点量と比較してプログラムが「これは顔だ」、「これは顔じゃない」という風に判定しています。OpenCV を使うと数行のコードでこれができるのでイカ検出の取り掛かりとしてとりあえずアニメ顔を検出してみます。

プログラム概要

今回やる事です。

  • web カメラから画像を取得
  • アニメ顔検出器にかけて顔を四角形でマーキング

イカを見つけるためのベースになります。

サンプルコード

今回書いた実験用のコードです。

#include <opencv2/opencv.hpp>
#include <string>

cv::CascadeClassifier g_Cascade;

void detectFace( cv::Mat &image )
{
	std::vector<cv::Rect> faces;
	g_Cascade.detectMultiScale( image, faces, 1.1, 3, 0, cv::Size( 20, 20 ) );

	for ( int faceIdx = 0; faceIdx < faces.size(); faceIdx++ )
	{
		cv::rectangle( image, 
			cv::Point( faces[faceIdx].x, faces[faceIdx].y ), 
			cv::Point( faces[faceIdx].x + faces[faceIdx].width, faces[faceIdx].y + faces[faceIdx].height ),
			cv::Scalar( 200, 0, 200 ), 3, CV_AA );
	}
}

int main(int argc, char const *argv[]) {
	
#if 0	//!< 人顔検出器
	std::string cascade = "E:\\prj\\libraries\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalcatface.xml";
#else	//!< アニメ顔検出器
	std::string cascade = "lbpcascade_animeface.xml";	//!< https://github.com/nagadomi/lbpcascade_animeface から取得
#endif
	g_Cascade.load( cascade );

#if 0
	cv::VideoCapture cameraCapture( "anim_face.avi" );	//!< テスト用動画
#else
	cv::VideoCapture cameraCapture( 0 );	//!< カメラからキャプチャ
#endif

	cv::VideoWriter writer("detected.avi", CV_FOURCC_DEFAULT, 10, cv::Size(640, 480), true);

	while( true )
	{
		cv::Mat camCap;
		cameraCapture >> camCap;

		if (camCap.empty())
		{
			break;
		}

		detectFace( camCap );
		cv::imshow( "face detection", camCap );
		writer << camCap;
		if (cv::waitKey(16) >= 0) break;
	}

	return 0;
}

プログラム実行結果

プログラムの実行結果です。ipad に画像を表示し、それを PC の web カメラにかざします。プログラムは web カメラの画像を解析して、アニメ顔にマーキングします。

とりあえず認識はできているみたいですが認識できていないフレームもあります。下記フレームの様にブラー(画像のボケ)が入ると認識できないみたいです。

buller

スプラトゥーンでこの様なボケは発生するかの確認が必要ですね。

今後の課題とやること

今後の課題とやることを列挙しておきます。

  • 対象物体が拡大回転縮小した時の認識をどうするか
  • イカ用の検出器の作成
  • ブラー等、フレームにノイズが入った時の認識をどうするか

早く成果を出したいので、生存のフラグを示すこのアイコンを認識する検出器を次回作ってみましょうか。

ika_life