我正在使用函数 cvHaarDetectObjects 进行人脸检测,并且使用 valgrind 进行内存泄漏检查,即使我认为我释放了所有内存。我真的不知道如何修复内存泄漏。这是我的代码:
int Detect(MyImage* Img,MyImage **Face)
{
Char* Cascade_name = new Char[1024];
strcpy(Cascade_name,"/usr/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml");
// Create memory for calculations
CvMemStorage* Storage = 0;
// Create a new Haar classifier
CvHaarClassifierCascade* Cascade = 0;
int Scale = 1;
// Create two points to represent the face locations
CvPoint pt1, pt2;
int Loop;
// Load the HaarClassifierCascade
Cascade = (CvHaarClassifierCascade*)cvLoad( Cascade_name, 0, 0, 0 );
// Check whether the cascade has loaded successfully. Else report and error and quit
if( !Cascade )
{
fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
exit(0);
}
// Allocate the memory storage
Storage = cvCreateMemStorage(0);
// Clear the memory storage which was used before
cvClearMemStorage( Storage );
// Find whether the cascade is loaded, to find the faces. If yes, then:
if( Cascade )
{
// There can be more than one face in an image. So create a growable sequence of faces.
// Detect the objects and store them in the sequence
CvSeq* Faces = cvHaarDetectObjects( Img->Image(), Cascade, Storage,
1.1, 2, CV_HAAR_DO_CANNY_PRUNING,
cvSize(40, 40) );
int MaxWidth = 0;
int MaxHeight = 0;
if(Faces->total == 0)
{
cout<<"There is no face."<<endl;
return 1;
}
//just get the first face
for( Loop = 0; Loop <1; Loop++ )
{
// Create a new rectangle for drawing the face
CvRect* Rect = (CvRect*)cvGetSeqElem( Faces, Loop );
// Find the dimensions of the face,and scale it if necessary
pt1.x = Rect->x*Scale;
pt2.x = (Rect->x+Rect->width)*Scale;
if(Rect->width>MaxWidth) MaxWidth = Rect->width;
pt1.y = Rect->y*Scale;
pt2.y = (Rect->y+Rect->height)*Scale;
if(Rect->height>MaxHeight) MaxHeight = Rect->height;
cvSetImageROI( Img->Image(), *Rect );
MyImage* Dest = new MyImage(cvGetSize(Img->Image()),IPL_DEPTH_8U, 1);
cvCvtColor( Img->Image(), Dest->Image(), CV_RGB2GRAY );
MyImage* Equalized = new MyImage(cvGetSize(Dest->Image()), IPL_DEPTH_8U, 1);
// Perform histogram equalization
cvEqualizeHist( Dest->Image(), Equalized->Image());
(*Face) = new MyImage(Equalized->Image());
if(Equalized)
delete Equalized;
Equalized = NULL;
if(Dest)
delete Dest;
Dest = NULL;
cvResetImageROI(Img->Image());
}
if(Cascade)
{
cvReleaseHaarClassifierCascade( &Cascade );
delete Cascade;
Cascade = NULL;
}
if(Storage)
{
cvClearMemStorage(Storage);
cvReleaseMemStorage(&Storage);
delete Storage;
Storage = NULL;
}
if(Cascade_name)
delete [] Cascade_name;
Cascade_name = NULL;
return 0;
}
在代码中,MyImage
是一个 IplImage 的包装类,其中包含IplImage* p
一个成员。如果构造函数将 aIplImage* ppara
作为参数,则该成员将使用andp
创建内存。如果它以大小、深度和通道作为参数,那么只做。然后析构函数做。该函数的调用如下:cvCreateImage(cvGetSize(ppara), ppara->depth, ppara->nChannels)
cvCopy(ppara, p)
cvCreateImage
cvReleaseImage(&p)
int Detect(MyImage *Img, MyImage **Face)
IplImage *Temp = cvLoadImage(ImageName);
MyImage* Img = new MyImage(Temp);
if(Temp)
cvReleaseImage(&Temp);
Temp = NULL;
MyImage * Face = NULL;
Detect(Img, &Face);
完成对它们的操作后,我在以下代码中发布了 Img 和 Face。并且内存泄漏发生在 Detect 函数内部。我在 64 位操作系统 fedora 16 上使用 OpenCV 2.3.1。整个程序可以正常终止,但内存泄漏除外。
非常感谢。