我现在在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] == ' ') )
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] = ' ';
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 ........ocvopencvsrccxcorecxpersistence.cpp, line 2568
这是什么意思?
是否加载了级联来触发人脸检测?它似乎找不到级联路径…
您需要一个级联来使用此人脸检测,并在运行程序时在命令行中最后写入此路径…
cascadecclassifier的load()
方法接受一个带有文件名的c++ std::string
作为输入
您使用的类型String
可能是由Visual Studio某处定义的。我不确定这些类型是否兼容,所以您最好坚持使用#include <string>
中的类型。
我认为您应该在调试时将.xml文件的绝对路径放在命令行中。因为当打开这种文件时,使用了标准字符串库的方法,我认为它只是接收绝对路径。