Необработанное исключение «System.Runtime.InteropServices.SEHException» в коде OpenCV - PullRequest
0 голосов
/ 22 июля 2011

Я сейчас использую VC ++ 2008 и OpenCV2.1 в Windows 7. Я пробую пример facedetect.cpp. Когда я запускаю программу, появляется окно с сообщением:

An unhandled exception of type 'System.Runtime.InteropServices.SEHException' occurred in Test Console 2.exe

Additional information: External component has thrown an exception.

Вот весь код:

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include <iostream>
#include <cstdio>
using namespace std;
using namespace cv;

void detectAndDraw( Mat& img,
                   CascadeClassifier& cascade, CascadeClassifier& nestedCascade,
                   double scale);

String cascadeName =
"C:/OpenCV2.1/data/haarcascades/haarcascade_frontalface_alt.xml";
String nestedCascadeName =
"C:/OpenCV2.1/data/haarcascades/haarcascade_eye_tree_eyeglasses.xml";

int main( int argc, const char** argv )
{
    CvCapture* capture = 0;
    Mat frame, frameCopy, image;
    const String scaleOpt = "--scale=";
    size_t scaleOptLen = scaleOpt.length();
    const String cascadeOpt = "--cascade=";
    size_t cascadeOptLen = cascadeOpt.length();
    const String nestedCascadeOpt = "--nested-cascade";
    size_t nestedCascadeOptLen = nestedCascadeOpt.length();
    String inputName;

    CascadeClassifier cascade, nestedCascade;
    double scale = 1;

    for( int i = 1; i < argc; i++ )
    {
        if( cascadeOpt.compare( 0, cascadeOptLen, argv[i], cascadeOptLen ) == 0 )
            cascadeName.assign( argv[i] + cascadeOptLen );
        else if( nestedCascadeOpt.compare( 0, nestedCascadeOptLen, argv[i], nestedCascadeOptLen ) == 0 )
        {
            if( argv[i][nestedCascadeOpt.length()] == '=' )
                nestedCascadeName.assign( argv[i] + nestedCascadeOpt.length() + 1 );
            if( !nestedCascade.load( nestedCascadeName ) )
                cerr << "WARNING: Could not load classifier cascade for nested objects" << endl;
        }
        else if( scaleOpt.compare( 0, scaleOptLen, argv[i], scaleOptLen ) == 0 )
        {
            if( !sscanf( argv[i] + scaleOpt.length(), "%lf", &scale ) || scale < 1 )
                scale = 1;
        }
        else if( argv[i][0] == '-' )
        {
            cerr << "WARNING: Unknown option %s" << argv[i] << endl;
        }
        else
            inputName.assign( argv[i] );
    }

    if( !cascade.load( cascadeName ) )
    {
        cerr << "ERROR: Could not load classifier cascade" << endl;
        cerr << "Usage: facedetect [--cascade=\"<cascade_path>\"]\n"
            "   [--nested-cascade[=\"nested_cascade_path\"]]\n"
            "   [--scale[=<image scale>\n"
            "   [filename|camera_index]\n" ;
        return -1;
    }

    if( inputName.empty() || (isdigit(inputName.c_str()[0]) && inputName.c_str()[1] == '\0') )
        capture = cvCaptureFromCAM( inputName.empty() ? 0 : inputName.c_str()[0] - '0' );
    else if( inputName.size() )
    {
        image = imread( inputName, 1 );
        if( image.empty() )
            capture = cvCaptureFromAVI( inputName.c_str() );
    }
    else
        image = imread( "lena.jpg", 1 );

    cvNamedWindow( "result", 1 );

    if( capture )
    {
        for(;;)
        {
            IplImage* iplImg = cvQueryFrame( capture );
            frame = iplImg;
            if( frame.empty() )
                break;
            if( iplImg->origin == IPL_ORIGIN_TL )
                frame.copyTo( frameCopy );
            else
                flip( frame, frameCopy, 0 );

            detectAndDraw( frameCopy, cascade, nestedCascade, scale );

            if( waitKey( 10 ) >= 0 )
                goto _cleanup_;
        }

        waitKey(0);
_cleanup_:
        cvReleaseCapture( &capture );
    }
    else
    {
        if( !image.empty() )
        {
            detectAndDraw( image, cascade, nestedCascade, scale );
            waitKey(0);
        }
        else if( !inputName.empty() )
        {
            /* assume it is a text file containing the
            list of the image filenames to be processed - one per line */
            FILE* f = fopen( inputName.c_str(), "rt" );
            if( f )
            {
                char buf[1000+1];
                while( fgets( buf, 1000, f ) )
                {
                    int len = (int)strlen(buf), c;
                    while( len > 0 && isspace(buf[len-1]) )
                        len--;
                    buf[len] = '\0';
                    cout << "file " << buf << endl;
                    image = imread( buf, 1 );
                    if( !image.empty() )
                    {
                        detectAndDraw( image, cascade, nestedCascade, scale );
                        c = waitKey(0);
                        if( c == 27 || c == 'q' || c == 'Q' )
                            break;
                    }
                }
                fclose(f);
            }
        }
    }

    cvDestroyWindow("result");

    return 0;
}

Исключение вырвало здесь:

if( !cascade.load( cascadeName ) )
{
    cerr << "ERROR: Could not load classifier cascade" << endl;
    cerr << "Usage: facedetect [--cascade=\"<cascade_path>\"]\n"
        "   [--nested-cascade[=\"nested_cascade_path\"]]\n"
        "   [--scale[=<image scale>\n"
        "   [filename|camera_index]\n" ;
    return -1;
}

Остальная часть кода работает. Когда я комментирую вышеупомянутую часть, остальная часть всего кода работает. Открывается окно камеры, хотя, очевидно, распознавание лица не срабатывает.

Может кто-нибудь сказать мне, что происходит?

РЕДАКТИРОВАТЬ: я посмотрел на консоль во время исключения и нашел это:

OpenCV error:NULL pointer <NULL filename> in unknown function , file ..\..\..\..\ocv\opencv\src\cxcore\cxpersistence.cpp, line 2568

Что это должно означать?

Ответы [ 3 ]

0 голосов
/ 26 июля 2011

Метод load() из CascadeClassifier принимает C ++ std::string с именем файла в качестве ввода.

Вы используете тип String, который, вероятно, где-то определен Visual Studio. Я не уверен, что эти типы совместимы, так что лучше придерживайтесь типа #include <string>.

0 голосов
/ 02 марта 2012

Я думаю, что вы должны указать абсолютный путь к XML-файлу в командной строке при его отладке.Поскольку при открытии такого файла используется метод стандартной библиотеки строк, я думаю, он просто получает абсолютный путь.

0 голосов
/ 26 июля 2011

Вы загрузили каскад для запуска обнаружения лица? Кажется, он не может найти каскадный путь ..

Вам нужен каскад, чтобы использовать это распознавание лиц и записать путь этого последнего в командной строке при запуске программы ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...