2

私は OpenCV 2.4.3 と Logitech C920 カメラを使って、原始的な顔認識スキームを実現したいと考えています。非常にシンプルで、洗練されたものではありません。

#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/features2d.hpp"


#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

/** Function Headers */
void grabcurrentuser();
void capturecurrentuser( Mat vsrc );

/** Global Variables **/
string face_cascade_name = "haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade;

int main( void ){//[main]
    grabcurrentuser();

}//]/main]

void grabcurrentuser(){//[grabcurrentuser]
    CvCapture* videofeed;
    Mat videoframe;

    //Load face cascade
    if( !face_cascade.load( face_cascade_name ) ){
        printf("Can't load haarcascade_frontalface_alt.xml\n");
    }
    //Read from source video feed for current user
    videofeed = cvCaptureFromCAM( 1 );
    if( videofeed ){
            for(int i=0; i<10;i++){//Change depending on platform
            videoframe = cvQueryFrame( videofeed );

            //Debug source videofeed with display
            if( !videoframe.empty() ){
            imshow( "Source Video Feed", videoframe ); 
            //Perform face detection on videoframe
            capturecurrentuser( videoframe );
        }else{ 
            printf("Videoframe is empty or error!!!"); break; 
        }

            int c = waitKey(33);//change to increase or decrease delay between frames
            if( (char)c == 'q' ) { break; }

            }
    }
}//[/grabcurrentuser]

void capturecurrentuser( Mat vsrc ){//[capturecurrentuser]
    std::vector<Rect> faces;
    Mat vsrc_gray;
    Mat currentuserface;

    //Preprocess frame for face detection
    cvtColor( vsrc, vsrc_gray, CV_BGR2GRAY );
    equalizeHist( vsrc_gray, vsrc_gray );

    //Find face
    face_cascade.detectMultiScale( vsrc_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30,30) );
    //Take face and crop out into a Mat
    currentuserface = vsrc_gray( faces[0] );
    //Save the mat into a jpg file on disk
    imwrite( "currentuser.jpg", currentuserface );
    //Show saved image in a window  
    imshow( "Current User Face", currentuserface ); 

}//[/capturecurrentuser]

上記のコードは、このシステムの最初のコンポーネントです。その仕事は、ビデオ フィードを受け入れ、10 フレームほど (したがって for ループ) を取得し、フレームに対して haar カスケードを実行して顔を取得することです。顔が取得されると、その顔をマットに切り取り、作業ディレクトリに jpg として保存します。

これまでのところ機能していますが、非常に気まぐれなコードのようです。ほとんどの場合、目的の出力が得られます (より正確または正確にする方法をここで尋ねるつもりはありませんが、お気軽に教えてください:D) が、セグメンテーション違反で終了する場合もあります。以下は、通常の出力の例です (見回したところ、VIDIOC の無効な引数は無視できるものであることがわかりました。簡単に修正できる場合は、お気軽に教えてください)。

VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
init done 
opengl support available 
Segmentation fault (core dumped)

このプログラムを同時に実行すると、上記のような単一または一連のセグメンテーション違反の結果が発生する場合とそうでない場合がある理由を誰か教えてもらえますか? このプログラムは、私が書いた別のプログラムに分流される出力を作成するように設計されているため、このように私を捕まえることはできません。

とても有難い!

4

1 に答える 1

0

問題は次の行にあります。

currentuserface = vsrc_gray( faces[0] );

私の経験から、存在しないものにアクセスしているときにセグメンテーション違反が発生します。faces[0] にデータが含まれているため、顔が検出された場合、プログラムは正常に動作します。ただし、顔が検出されない (カメラを覆う) 場合は、faces[0] に四角形は格納されません。したがって、エラーが発生します。

何も検出されないときに imshow と imwrite が機能するように、次のように初期化してみてください。

cv::Mat currentuserface = cv::Mat::zeros(vsrc.size(), CV_8UC1);

次に、現在のユーザーフェイスを初期化する前に、フェイスが空かどうかを確認します。

if( !faces.empty() )

currentuserface = vsrc_gray( faces[0] );
于 2014-08-10T10:29:04.533 に答える