OpenCVとUSBカメラと顔検出

Windows

はじめに

OpenCVで顔認識を行うプログラム。

環境

「OpenCVの環境構築」の記事を参照。

PERSOL PC380SN

使用したUSBカメラ。
ChipはSN9C102。
ドライバは本家から持ってくる。

顔の学習データ

OpenCVを解凍して下記からコピーしておく。
やはり検出精度は低い・・・。

opencv\data\haarcascades\haarcascade_frontalface_default.xml

コンパイル

「OpenCVとUSBカメラと顔検出」の記事を参照。

ソース

自分用。
グレー化、均一化は不要と思ったので未実装。
検出した顔に貼り付ける画像は適当に準備する。
ファイル名の拡張子は「cpp」にする。

#include <opencv2/opencv.hpp>

// 静的ライブラリを使う場合はコメントをとる
//今のところ私の環境ではコマンドラインでコンパイル出来ない。
//#define OPENCV_STATICLIB

#ifdef OPENCV_STATICLIB
#pragma comment(lib, "comctl32.Lib")
#pragma comment(lib, "vfw32.lib")

#ifdef _DEBUG
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_core231d.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_highgui231d.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_imgproc231d.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_calib3d231d.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_contrib231d.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_features2d231d.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_flann231d.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_gpu231d.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_legacy231d.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_ml231d.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_objdetect231d.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_ts231d.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_video231d.lib")

#pragma comment(lib, "C:\\opencv\\staticlib\\3rdparty\\zlibd.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\3rdparty\\libtiffd.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\3rdparty\\libpngd.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\3rdparty\\libjpegd.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\3rdparty\\libjasperd.lib")

#pragma comment(lib, "C:\\opencv\\staticlib\\tbb_debug.lib")

#pragma comment(linker, "/NODEFAULTLIB:\"libcmtd.lib\"")
#pragma comment(linker, "/NODEFAULTLIB:\"msvcprtd.lib\"")
#else
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_core231.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_highgui231.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_imgproc231.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_calib3d231.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_contrib231.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_features2d231.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_flann231.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_gpu231.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_legacy231.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_ml231.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_objdetect231.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_ts231.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\opencv_video231.lib")

#pragma comment(lib, "C:\\opencv\\staticlib\\3rdparty\\zlib.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\3rdparty\\libtiff.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\3rdparty\\libpng.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\3rdparty\\libjpeg.lib")
#pragma comment(lib, "C:\\opencv\\staticlib\\3rdparty\\libjasper.lib")

#pragma comment(lib, "C:\\opencv\\staticlib\\tbb.lib")

#pragma comment(linker, "/NODEFAULTLIB:\"libcmt.lib\"")
#pragma comment(linker, "/NODEFAULTLIB:\"msvcprt.lib\"")
#endif
#else
#ifdef _DEBUG
#pragma comment(lib, "C:\\opencv\\lib\\opencv_core231d.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_highgui231d.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_imgproc231d.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_calib3d231d.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_contrib231d.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_features2d231d.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_flann231d.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_gpu231d.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_legacy231d.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_ml231d.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_objdetect231d.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_ts231d.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_video231d.lib")

#pragma comment(lib, "C:\\opencv\\staticlib\\tbb_debug.lib")
#else
#pragma comment(lib, "C:\\opencv\\lib\\opencv_core231.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_highgui231.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_imgproc231.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_calib3d231.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_contrib231.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_features2d231.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_flann231.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_gpu231.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_legacy231.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_ml231.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_objdetect231.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_ts231.lib")
#pragma comment(lib, "C:\\opencv\\lib\\opencv_video231.lib")

#pragma comment(lib, "C:\\opencv\\staticlib\\tbb.lib")
#endif
#endif

int main( int argc, char **argv )
{
    int            i;
    int            input_key;
    int            fps;
    int            video_width, video_height;
    CvCapture      *frame;
    CvVideoWriter  *writer;
    IplImage       *img_src;
    char           *wn_src = "win_src";
    double         t;
    CvRect         *r;
    CvPoint        center;
    int            radius;
    IplImage       *img_face, *img_resize;

    static CvScalar colors[] =
    {
        {{0,   0,   255}},
        {{0,   128, 255}},
        {{0,   255, 255}},
        {{0,   255, 0}},
        {{255, 128, 0}},
        {{255, 255, 0}},
        {{255, 0,   0}},
        {{255, 0,   255}}
    };

    video_width  = 640;
    video_height = 480;
    fps          = 4; // 29.97

    // 顔に貼り付ける画像
    img_face = cvLoadImage( "hoge.jpg" );
    if ( img_face == NULL )
    {
        printf("Can not load image file. \n");
        return EXIT_FAILURE;
    }

    // 正面顔検出器の読み込み
    CvHaarClassifierCascade *cascade = (CvHaarClassifierCascade *)cvLoad("haarcascade_frontalface_default.xml");
    if ( cascade == NULL )
    {
        printf("Not found cascade file. \n");
        return EXIT_FAILURE;
    }

    // 検出用メモリの確保
    CvMemStorage *storage = cvCreateMemStorage( 0 );
    cvClearMemStorage ( storage );

    // 顔検出情報シーケンス
    CvSeq *face;

    // Window作成
    cvNamedWindow(wn_src, CV_WINDOW_AUTOSIZE);

    // Windowサイズの変更
    //cvResizeWindow(wn_src, video_width, video_height);

    // カメラ映像の取得
    frame = cvCaptureFromCAM( 0 );
    if ( frame == NULL )
    {
        printf("Not found video camera. \n");
        return EXIT_FAILURE;
    }

    // 初期フレーム取得
    img_src = cvQueryFrame( frame );

    // ビデオ保存
    // 2: fourcc is possible to pass -1 in order to choose compression from dialog
    // 5: is_color is currently supported on Windows only.
    // writer = cvCreateVideoWriter("test.avi", -1, fps, cvSize(video_width, video_height), 0);

    while ( 1 )
    {
        // 1フレーム取得
        img_src = cvQueryFrame( frame );

        // グレー化
        //cvCvtColor (src_img, src_gray, CV_BGR2GRAY);
        // ヒストグラムの均一化
        //cvEqualizeHist (src_gray, src_gray);

        cvClearMemStorage( storage );

        t = ( double )cvGetTickCount();

        // 検出
        face = cvHaarDetectObjects(img_src, cascade, storage);

        t = ( double )cvGetTickCount() - t;
        t = t / ( 1000.0 * ( double )cvGetTickFrequency() );
        printf( "検出時間: %g [ms] \n", t );

        for (i = 0; i < face->total; i++)
        {
            // 顔の位置情報を取得
            CvRect *faceRect = ( CvRect *)cvGetSeqElem(face, i);

            /*
            // 検出した顔に矩形を描画する
            cvRectangle(img_src,
            cvPoint(faceRect->x, faceRect->y),
            cvPoint(faceRect->x + faceRect->width, faceRect->y + faceRect->height),
            CV_RGB(0, 255 ,0),
            3, CV_AA);
            */
            /*
            // 検出した顔に円を描画する
            r = ( CvRect *)cvGetSeqElem( face, i );
            center.x = cvRound( (r->x + 0.5 * r->width ) );
            center.y = cvRound( (r->y + 0.5 * r->height ) );
            radius = cvRound( 0.25 * ( r->width + r->height ) );
            cvCircle( img_src, center, radius, colors[ i % 8 ], 3, 8, 0 );
            */

            // 検出した顔に画像を描画する
            CvRect rect;
            rect = *( CvRect *)cvGetSeqElem( face, i );
            cvSetImageROI( img_src, rect );
            img_resize = cvCreateImage( cvSize( rect.width, rect.height), img_face->depth, img_face->nChannels );
            cvResize( img_face, img_resize );
            cvCopy( img_resize, img_src );
            cvResetImageROI( img_src );
        }

        // 1フレーム表示
        cvShowImage(wn_src, img_src);

        // キー入力を待つ [ms]
        input_key = cvWaitKey( 1000 );

        // ESCキー入力で終了
        if ( input_key == 27 )
        {
            break;
        }
    }

    // 全Windowを破棄
    cvDestroyAllWindows();

    cvReleaseCapture( &frame );
    // cvReleaseVideoWriter( &writer );

    // 用意したメモリストレージを解放
    cvReleaseMemStorage( &storage );

    // カスケード識別器の解放
    cvReleaseHaarClassifierCascade( &cascade );

    return EXIT_SUCCESS;
}
created by Rinker
¥3,630 (2024/07/02 05:22:54時点 楽天市場調べ-詳細)

Comments