山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他OpenCVを使用してjpgファイルの顔認識をする
概要
OpenCVのMat型を使用してjpgファイルであるtest.jpgをウィンドウに表示し顔検出器haarcascade_frontalface_default.xmlを使用して顔を検出し、顔に緑の円を描画します。
顔は1個では無く複数の顔にも対応しています。たとえばAKBとかOSUの集合写真などにも適用できます。
Visual C++ を対象としておりOpenCVのインストールが必要である。
上図はプログラムを実行した結果です。プログラムで使用したtest.jpgはOpenCVサンプルのC:\opencv2.4.10\opencv\sources\samples\cpp\rena.jpgをコピーして名前をtest.jpgとして画像サイズを256*256に変更したものです。 検出器は、C:\opencv2.4.10\opencv\sources\data\haarcascades\haarcascade_frontalface_default.xmlをカレントフォルダにコピーして使用しています。
顔の検出をしやすくなるために、グレースケールに変換後、ヒストグラムを均一化し顔検出を実行しています。
顔は1個では無く複数の顔にも対応しています。たとえばAKBとかOSUの集合写真などにも適用できます。
Visual C++ を対象としておりOpenCVのインストールが必要である。
上図はプログラムを実行した結果です。プログラムで使用したtest.jpgはOpenCVサンプルのC:\opencv2.4.10\opencv\sources\samples\cpp\rena.jpgをコピーして名前をtest.jpgとして画像サイズを256*256に変更したものです。 検出器は、C:\opencv2.4.10\opencv\sources\data\haarcascades\haarcascade_frontalface_default.xmlをカレントフォルダにコピーして使用しています。
顔の検出をしやすくなるために、グレースケールに変換後、ヒストグラムを均一化し顔検出を実行しています。
test.jpg | |
グレースケール変換後 | |
ヒストグラムを均一化後 |
テスト環境
コンパイラ
Visual C++ 2008 Express(32bit)/Standard(32/64bit) with OpenCV2.3.1Visual C++ 2013 Express 32bit/64bit with OpenCV2.4.10
実行環境
Windows 7 32/64bitOpenCVのインストール及び環境設定
プログラムソースの概要
#include の後の行からusing namespace cv;の手前までは、Visual C++のバージョン及びRelease/Debug 32bit/64bit 静的リンク/動的リンクに合わせてロードするLIBのファイル名を自動的に作成するために記述しています。
固定された環境であれば、簡素に記述可能です。
例えば Visual C++ 2013 32bit Release 動的リンクであれば、以下のように簡素に記述できます。
imread関数でjpgファイルをMat型の変数imgにロードします。
imgのメンバー変数のdataがNULLの場合は、ロードに失敗しているのでプログラムを終了させます。
検出しやすくするために、cvtColorによりグレースケールに変換します。結果はgrayに保存されます。
grayをequalizeHistによりヒストグラムを均一化しgrayに保存します。
loadにより正面顔検出器をロードします。
検出器はOpenCVのインストールフォルダC:\opencv2.4.10\opencv\sources\data\haarcascades\にありますので、実行時に参照できる位置にコピーしておいてください。フォルダーの中にはいろいろな検出器があります。
detectMultiScaleにより顔検出を実行します。facesに顔が含まれる四角形の座標が保存されます。
facesから四角形の個数分の四角形の座標を取り出し、ellipseにより円をimgに描画します。
namedWindow関数によりウィンドウを開きます。
imshow関数によりimgをウィンドウに表示します。
waitkey()によりキー入力があるまで待機します。
固定された環境であれば、簡素に記述可能です。
例えば Visual C++ 2013 32bit Release 動的リンクであれば、以下のように簡素に記述できます。
#pragma comment(lib, "c:/opencv2.4.10/opencv/build/vc12/x86/lib/opencv_core2410.lib")
#pragma comment(lib, "c:/opencv2.4.10/opencv/build/vc12/x86/lib/opencv_highgui2410.lib")
using namespace cv; により名前空間をcvにします。これを定義しない場合は、OpenCVの関数を使う場合には関数名の前にcv::を付加する必要があります。
_tWinMain
fileName変数で開くjpgファイルのファイル名を指定しています。imread関数でjpgファイルをMat型の変数imgにロードします。
imgのメンバー変数のdataがNULLの場合は、ロードに失敗しているのでプログラムを終了させます。
検出しやすくするために、cvtColorによりグレースケールに変換します。結果はgrayに保存されます。
grayをequalizeHistによりヒストグラムを均一化しgrayに保存します。
loadにより正面顔検出器をロードします。
検出器はOpenCVのインストールフォルダC:\opencv2.4.10\opencv\sources\data\haarcascades\にありますので、実行時に参照できる位置にコピーしておいてください。フォルダーの中にはいろいろな検出器があります。
detectMultiScaleにより顔検出を実行します。facesに顔が含まれる四角形の座標が保存されます。
facesから四角形の個数分の四角形の座標を取り出し、ellipseにより円をimgに描画します。
namedWindow関数によりウィンドウを開きます。
imshow関数によりimgをウィンドウに表示します。
waitkey()によりキー入力があるまで待機します。
ソースコード
// OpenCVを使用してtest.jpgに含まれる顔の範囲を緑の円で描画するサンプル
// Open CV 2.3.1/2.4.10 サポート
// 例えばVisual C++ 2013でOpen CV 2.4.10でコンパイルする場合の設定は以下の通りとなる
// VCのインクルードディレクトリに C:\opencv2.4.10\opencv\build\include; を付加
// 動的リンクで作成した場合は、サンプルの実行には環境変数PATHに以下のフォルダーを登録する必要がある。
// win64 C:\opencv2.4.10\opencv\build\x64\vc12\bin
// win32 C:\opencv2.4.10\opencv\build\x86\vc12\bin
// 動作確認
// Visual C++ 2008 Standard Release 64bit 動的/静的 OpenCV 2.3.1
// Visual C++ 2008 Standard Debug 64bit 動的/静的 OpenCV 2.3.1
// Visual C++ 2008 Standard Release 32bit 動的/静的 OpenCV 2.3.1
// Visual C++ 2008 Standard Debug 32bit 動的/静的 OpenCV 2.3.1
// Visual C++ 2013 Express Debug 32bit 動的/静的 OpenCV 2.4.10
// Visual C++ 2013 Express Release 32bit 動的/静的 OpenCV 2.4.10
// Visual C++ 2013 Express Debug 64bit 動的/静的 OpenCV 2.4.10
// Visual C++ 2013 Express Release 64bit 動的/静的 OpenCV 2.4.10
#include <windows.h>
#include <opencv2/opencv.hpp>
#include <tchar.h>
#ifdef _DLL // 動的リンク
#define CV_LINK_MODE "/lib/"
#else // 静的リンク
#define CV_LINK_MODE "/staticlib/"
#endif
// バージョン取得
#define CV_VERSION_STR CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) CVAUX_STR(CV_SUBMINOR_VERSION)
#define CV_INST_SUB_DIR "opencv" ## CVAUX_STR(CV_MAJOR_VERSION) ## "." CVAUX_STR(CV_MINOR_VERSION) ## "." CVAUX_STR(CV_SUBMINOR_VERSION)
#define CV_INST_DIR "c:/" ## CV_INST_SUB_DIR ## "/opencv/build"
// 32bit/64bit ランタイムのリンクモード等に応じてLIBファイルのフォルダー名(CV_LIB_DIR)を作成
#ifdef _WIN64
#ifdef _DLL
#define CV_LIB_DIR CV_INST_DIR ## "/x64/" ## CV_MS_VER ## "/lib/"
#else
#define CV_LIB_DIR CV_INST_DIR ## "/x64/" ## CV_MS_VER ## "/staticlib/"
#endif
#else
#ifdef _DLL
#define CV_LIB_DIR CV_INST_DIR ## "/x86/" ## CV_MS_VER ## "/lib/"
#else
#define CV_LIB_DIR CV_INST_DIR ## "/x86/" ## CV_MS_VER ## "/staticlib/"
#endif
#endif
#if _MSC_VER==1500
#define VCVER 2008
#define CV_MS_VER "vc9"
#endif
#if _MSC_VER==1600
#define VCVER 2010
#define CV_MS_VER "vc10"
#endif
#if _MSC_VER==1700
#define VCVER 2012
#define CV_MS_VER "vc11"
#endif
#if _MSC_VER==1800
#define VCVER 2008
#define CV_MS_VER "vc12"
#endif
#ifdef _DEBUG // デバック
#define CV_EXT_STR "d.lib"
#else // リリース
#define CV_EXT_STR ".lib"
#endif
#pragma comment(lib, CV_LIB_DIR "opencv_core" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, CV_LIB_DIR "opencv_highgui" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, CV_LIB_DIR "opencv_objdetect" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, CV_LIB_DIR "opencv_imgproc" CV_VERSION_STR CV_EXT_STR)
#ifdef _DLL // 動的リンク
#else
#pragma comment(lib,"comctl32.lib")
#pragma comment(linker, "/nodefaultlib:\"msvcprt" CV_EXT_STR "\"")
#if CV_MAJOR_VERSION==2 && CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION==10
#pragma comment(lib, CV_LIB_DIR "IlmImf" CV_EXT_STR )
#endif
#pragma comment(lib, CV_LIB_DIR "libjasper" CV_EXT_STR )
#pragma comment(lib, CV_LIB_DIR "libjpeg" CV_EXT_STR )
#pragma comment(lib, CV_LIB_DIR "libpng" CV_EXT_STR )
#pragma comment(lib, CV_LIB_DIR "libtiff" CV_EXT_STR )
#pragma comment(lib, CV_LIB_DIR "zlib" CV_EXT_STR )
#endif
using namespace cv;
int WINAPI _tWinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, TCHAR* CmdLine, int nCmdShow){
char* fileName = "test.jpg";
Mat img=imread(fileName);
if(img.data==NULL){
MessageBox(0,_TEXT("test.jpgが開けません"),_TEXT("エラー"),MB_OK);
return 1;
}
Mat gray;
// グレースケールに変換
cvtColor(img,gray,COLOR_RGB2GRAY);
// ヒストグラムを均一化
equalizeHist(gray,gray);
CascadeClassifier cascade;
/* 正面顔検出器のロード */
if(cascade.load("haarcascade_frontalface_default.xml")==NULL){
MessageBox(0,_TEXT("検出器が開けません"),_TEXT("エラー"),MB_OK);
return 1;
}
vector<Rect> faces;
/* 顔検出 */
cascade.detectMultiScale(gray,faces);
/* 顔領域の描画 */
for (unsigned i = 0; i < faces.size(); i++){
Point pt[4];
pt[0]=Point(faces[i].x+faces[i].width/2 , faces[i].y+faces[i].height/2);
ellipse(img,pt[0],Size(faces[i].width/2, faces[i].height/2), 0,0,360,Scalar(0,255,0),2,8,0);
}
/* 画像の表示 */
namedWindow("detect",CV_WINDOW_AUTOSIZE);
imshow("detect",img);
waitKey();
return 0;
}
Copyright (C) 2012 山本ワールド All Rights Reserved.