【C++】OpenCVによるリアルタイム顔認識プログラム【画像処理】

スポンサーリンク
C++
スポンサーリンク

はじめに

今回はOpenCVを使って、カメラに映る人の顔をリアルタイムで認識するプログラムを作ってみました。

わからないクラスなどがある場合には、前回の記事を参照してください。

カスケード分類機について

今回はカスケード分類機を利用して顔認証を行います。本来はカスケード分類機を作る必要がありますが、OpenCVには顔のカスケード分類機がもともと備え付けられているのでそれを利用します。

ソースコード

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

int main()
{
	cv::VideoCapture video(0); //カメラの起動

	if(!video.isOpened()){ //エラー処理
		 
		 std::cout << "video.error" << std::endl;
		 return -1;
	}
	
	cv::Mat frame; //フレーム格納用
	
	cv::CascadeClassifier cascade; //カスケード分類機格納用
	
	cascade.load("/usr/local/opt/opencv/share/opencv4/haarcascades/haarcascade_frontalface_default.xml"); //カスケードファイルの読み込み
	
	std::vector<cv::Rect> contour; //矩形格納用
	
	while(video.read(frame)){ //ループ
	
		cascade.detectMultiScale(frame, contour, 1.1, 5, 0, cv::Size(30, 30)); //対象の検出
		
		for(int i = 0; i < contour.size(); i++){ //検出個数分繰り返し
			cv::rectangle(frame, cv::Point(contour[i].x, contour[i].y), cv::Point(contour[i].x + contour[i].width, contour[i].y + contour[i].height), cv::Scalar(255, 255, 255), 1); //矩形の可視化
		}
		
		cv::imshow("frame", frame); //表示
		
		int key = cv::waitKey(1);
		
		if(key == 'q'){
			
			cv::destroyWindow("frame");
			break;
		}
	}
	
    return 0;
}

ソースコードの説明

カスケード分類機に関わる部分について説明します。その他については前回の記事を参照してください。

カスケード分類機格納用のクラス

cv::CascadeClassifier オブジェクト名;

「CascadeClassifier」はカスケード分類機を扱うオブジェクトを作るためのクラスです。

カスケードファイルの読み込み

オブジェクト.load(カスケード分類機のパス);

カスケード分類機のファイルは「load」で読み込むことができます。

また、OpenCV標準のカスケード分類機のパスは自分の動作環境下(MacOSX)では次の通りでした。

/usr/local/opt/opencv/share/opencv4/haarcascades/haarcascade_frontalface_default.xml

カスケード分類機による検出

オブジェクト.detectMultiScale(検出する画像, 出力用矩形ベクトル, ステップ, 近傍矩形の最小量, 過去の遺物(0としておく), 検出対象の最小サイズ);

「detectMultiScale」はカスケード分類機によって検出する画像から対象を検出し、対象を囲う範囲の矩形をベクトルの要素として出力します。対象が複数個ある場合は順番に格納されます。

尚、ベクトルを格納するオブジェクトは次のようにして作成します。

std::vector<cv::Rect> ベクトル名;

「Rect」が二次元の矩形のためのクラスで、可変長でオブジェクトを宣言します。

ステップは対象を検出する幅のようなもので、これが大きいと検出が大雑把になり、小さいと実行に時間がかかります。

近傍矩形の最小量はそのままの意味で候補となる矩形はここで指定した数だけ近傍矩形を含むように指定します。

過去の遺物はOpenCVの古いバージョンでは使っていましたが、現行では使われないため「0」としておきます。

検出対象の最小サイズはここで指定したサイズより小さいものを認識しないようにします。また、「cv::Size(cols,rows)」で指定する必要があります。

矩形の描画

cv::rectangle(描画する画像, 矩形の頂点, 対となる頂点, 描画する矩形の色, 矩形の太さ);

「rectangle」は矩形を描画するための関数です。

矩形の頂点は「cv::Point(x座標,y座標)」によって指定します。

矩形の色については「cv::Scalar(R,G,B)」によって指定します。

また、矩形ベクトルは「オブジェクト名.x」でx座標を、「オブジェクト名.y」でy座標を、「オブジェクト名.width」で幅を、「オブジェクト名.height」で高さを取得できます。

最後に

言葉選びが難しいので日本語として間違っていたらすみません。分かりにくい場所があれば修正します。

近いうちにカスケード分類機を自作してみようと思います。

コメント

タイトルとURLをコピーしました