C++とOpenCVを使って静止画から顔を検出する方法をわかりやすく解説
OpenCVでは、画像から顔を検出することができます。顔検出には「detectMultiScale()」関数を使用します。
この関数の基本的な書式は以下の通りです。
構文
detectMultiScale(ソース行列, ベクター, 検出スケール係数, 最小近傍数, フラグ, 最小特徴サイズ)
引数を変更することで、「detectMultiScale()」関数の動作を細かく制御できます。各引数の役割は次の通りです。
ソース行列(Source Matrix)
顔を検出する対象となる行列です。この場合、画像データを保持している行列を指定します。
ベクター(Vector)
「detectMultiScale()」関数の検出結果は、矩形型のベクターとして格納されます。OpenCVでは矩形もベクターとして扱うため、vector型として定義する必要があります。
検出スケール係数(searchScaleFactor)
検出スケール係数は、関数が何種類のサイズの顔を探索するかを決定します。通常は1.1を使用します。必要に応じて1.2に設定すると検出処理が速くなりますが、その場合は1.1を使ったときほど頻繁に顔が検出されなくなる点に注意してください。
最小近傍数(minNeighbours)
このパラメータは、検出器の信頼度を表します。つまり、検出器がどの程度の確信を持って「これは顔だ」と判断したかを示すものです。信頼性を高めたい場合は大きい値を設定しますが、処理速度は低下します。逆に小さい値を設定すると処理は速くなりますが、信頼性は下がります。一般的には3または4程度が推奨されます。
フラグ(flags)
デフォルト設定では、関数はすべての顔を検索します。フラグの値に「CASCADE_FIND_BIGGEST_OBJECT」を指定すると、最も大きな顔のみを検出するため、処理が高速になります。一方、「CASCADE_SCALE_IMAGE」を指定すると、複数の顔を検索できます。
最小特徴サイズ(minFeatureSize)
minFeatureSizeは、検出対象とする顔の最小サイズを決定します。カメラから遠い位置にある顔を検出したい場合は小さい値を、近い位置にある顔を検出したい場合は大きい値を使用します。標準的な距離では(20×20)または(30×30)のサイズがよく使われます。本記事のサンプルでは、detectMultiScale()関数を以下のように使用しています。
faceDetector.detectMultiScale(image_with_humanface, faces, 1.1, 4, CASCADE_SCALE_IMAGE, Size(20, 20));
以下のコードは、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("friends.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という名前の矩形ベクターを宣言//
vector<Rect>boundary;//boundaryという名前の矩形ベクターを宣言//
faceDetector.detectMultiScale(image_with_humanface, faces, 1.1, 4, CASCADE_SCALE_IMAGE, Size(20, 20));//「image_with_humanface」行列内の顔を検出//
for (size_t i = 0; i < faces.size(); i++){ //検出した顔の周囲に矩形を描画するループ//
Mat faceROI = image_with_humanface(faces[i]);//顔を行列に格納//
int x = faces[i].x;//顔矩形の開始点の行の値を取得//
int y = faces[i].y;//顔矩形の開始点の列の値を取得//
int h = y + faces[i].height;//矩形の高さを計算//
int w = x + faces[i].width;//矩形の幅を計算//
rectangle(image_with_humanface, Point(x, y), Point(w, h), Scalar(255, 0, 255), 2, 8, 0);//顔の周囲に矩形を描画//
}
imshow("Face Detection", image_with_humanface);//検出された顔を表示//
waitKey(0);//キー入力を待ってプログラムを終了//
return 0;
}
実行結果

-
C++とOpenCVを使って線を描画する方法
OpenCVで線を描画するには、始点と終点の2つの座標が必要です。さらに、線を描くためのキャンバス(描画領域)も用意しなければなりません。線を描画するために必要な要素OpenCVでは、キャンバスとして機能するのが行列(Mat)です。この行列に対して、線の始点と終点を定義し、加えて以下の情報も指定します。線の色線の太さつまり、OpenCVで線を描くには、行列・2つの点・色・線の太さという4つの要素を宣言しておく必要があります。必要なヘッダーファイルOpenCVで線を描画するには、<imgproc.hpp>ヘッダーをインクルードします。これは、line()関数がこのヘッダー内で定義され
-
C++とOpenCVで画像のチャンネル数を取得する方法を解説
この記事では、OpenCVを使って画像のチャンネル数を調べる方法について解説します。プログラムを実行すると、コンソール画面に画像のチャンネル数が表示されます。チャンネル数を取得するには、OpenCVが提供するchannels()メソッドを使用します。このメソッドは、Matクラスのオブジェクト(画像行列)に対して呼び出すことで、その画像のチャンネル数を整数値として返します。例えば、カラー画像の場合は通常3チャンネル(BGR)、グレースケール画像の場合は1チャンネルとなります。画像処理を行う際、扱っている画像がカラーかモノクロかを判別するために、チャンネル数の確認は非常に重要な処理の一つです。以下