C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++とOpenCVを使って顔の位置を追跡する方法

顔の位置を追跡したい場合、楕円で顔を囲む方法が効果的です。楕円には中心点が存在し、この中心が検出された顔の中心点と一致するため、顔の位置追跡をより正確に行うことができます。

以下のプログラムでは、検出された顔の中心を追跡し、その位置をコンソールウィンドウに表示します。

サンプルコード

#include<iostream>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
//このヘッダーにはrectangle()関数の定義が含まれています//
#include<opencv2/objdetect/objdetect.hpp>
//このヘッダーにはCascadeClassifierの定義が含まれています//
#include<string>
using namespace std;
using namespace cv;
int main(int argc, char** argv){
    Mat image_with_humanface;//顔を含む画像を読み込むための行列を宣言//
    image_with_humanface = imread("person.jpg");//顔が写っている画像を読み込む//
    namedWindow("Face Detection");//結果を表示するウィンドウを宣言//
    string trained_classifier_location = "C:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt.xml";//学習済みXML分類器のパスを文字列として定義//
    CascadeClassifier faceDetector;//CascadeClassifierクラスのオブジェクト'faceDetector'を宣言//
    faceDetector.load(trained_classifier_location);//学習済みXML分類器をオブジェクトに読み込む//
    vector<Rect>faces;//facesという名前の矩形ベクトルを宣言//
    faceDetector.detectMultiScale(image_with_humanface, faces, 1.1, 4, CASCADE_SCALE_IMAGE,Size(20,20));//'image_with_humanface'内の顔を検出//
    for (int i = 0; i < faces.size(); i++){ //検出された顔を処理するforループを開始//
        Point center(faces[i].x + faces[i].width * 0.5, faces[i].y + faces[i].height * 0.5);//顔の中心座標を取得//
        ellipse(image_with_humanface, center, Size(faces[i].width * 0.5, faces[i].height * 0.5), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0);//顔の周囲に楕円を描画//
        int horizontal = (faces[i].x + faces[i].width * 0.5);//座標の水平方向の値を取得//
        int vertical = (faces[i].y + faces[i].width * 0.5);//座標の垂直方向の値を取得//
    }
   cout << "Position of the face is at(x,y)=" << " ("<<CAP_PROP_XI_DECIMATION_HORIZONTAL<<","<<CAP_PROP_XI_DECIMATION_VERTICAL<<")"<< endl;//
    imshow("Face Detection", image_with_humanface);//検出結果を表示//
    waitKey(0);//キー入力を待ってプログラムを終了
    return 0;
}

コードの解説

このプログラムの処理の流れは以下のとおりです。

  1. 分類器の読み込み: Haar特徴ベースのカスケード分類器(haarcascade_frontalface_alt.xml)をCascadeClassifierオブジェクトに読み込みます。
  2. 顔の検出: detectMultiScale()関数を使用して画像内の顔を検出し、結果をRect型のベクトルに格納します。引数の1.1はスケールファクター、4は近傍矩形の最小数、Size(20,20)は検出対象の最小サイズを表します。
  3. 中心座標の計算: 検出された顔の矩形情報から中心座標を計算します。水平方向の中心は「x座標 + 幅 × 0.5」、垂直方向の中心は「y座標 + 高さ × 0.5」で求められます。
  4. 楕円の描画: ellipse()関数を使い、計算した中心座標を基準として顔を囲む楕円を描画します。色はScalar(255, 0, 255)でマゼンタ色に指定されています。

楕円の中心がそのまま顔の中心点となるため、この座標を利用することで、顔の位置を正確に追跡できます。

出力

C++とOpenCVを使って顔の位置を追跡する方法

プログラムを実行すると、画像内の検出された顔の周囲に楕円が描画され、コンソールウィンドウには顔の中心座標(x, y)が表示されます。

  1. C++とOpenCVを使って線を描画する方法

    OpenCVで線を描画するには、始点と終点の2つの座標が必要です。さらに、線を描くためのキャンバス(描画領域)も用意しなければなりません。線を描画するために必要な要素OpenCVでは、キャンバスとして機能するのが行列(Mat)です。この行列に対して、線の始点と終点を定義し、加えて以下の情報も指定します。線の色線の太さつまり、OpenCVで線を描くには、行列・2つの点・色・線の太さという4つの要素を宣言しておく必要があります。必要なヘッダーファイルOpenCVで線を描画するには、<imgproc.hpp>ヘッダーをインクルードします。これは、line()関数がこのヘッダー内で定義され

  2. C++とOpenCVで画像のチャンネル数を取得する方法を解説

    この記事では、OpenCVを使って画像のチャンネル数を調べる方法について解説します。プログラムを実行すると、コンソール画面に画像のチャンネル数が表示されます。チャンネル数を取得するには、OpenCVが提供するchannels()メソッドを使用します。このメソッドは、Matクラスのオブジェクト(画像行列)に対して呼び出すことで、その画像のチャンネル数を整数値として返します。例えば、カラー画像の場合は通常3チャンネル(BGR)、グレースケール画像の場合は1チャンネルとなります。画像処理を行う際、扱っている画像がカラーかモノクロかを判別するために、チャンネル数の確認は非常に重要な処理の一つです。以下