OpenCV代码中的“System.Runtime.InteropServices.SEHException”未处理的异常

时间:2011-07-22 15:17:17

标签: c++ exception-handling opencv

我现在在Windows 7上使用VC ++ 2008和OpenCV2.1。我正在尝试使用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 :(得分:0)

您是否加载级联以触发面部检测? 它似乎无法找到级联路径..

运行程序时,您需要一个级联来使用此人脸检测并在命令行中写下最后一个路径......

答案 1 :(得分:0)

load()的方法CascadeClassifier采用带有文件名作为输入的C ++ std::string

您使用的类型String可能是Visual Studio在某处定义的。我不确定这些类型是否兼容,所以你最好坚持使用#include <string>中的那个。

答案 2 :(得分:0)

我认为您应该在调试时将.xml文件的绝对路径放在命令行中。因为当打开这种文件时使用标准字符串库的方法,我认为它只是接收绝对路径。