Opencv cvHaarDetectObjects内存泄漏

Opencv cvHaarDetectObjects内存泄漏,opencv,memory-leaks,face-detection,Opencv,Memory Leaks,Face Detection,我正在使用函数cvhaardetecobjects进行人脸检测,虽然我认为我释放了所有的内存,但是valgrind进行了内存泄漏检查。我真的不知道如何修复内存泄漏。这是我的密码: int Detect(MyImage* Img,MyImage **Face) { Char* Cascade_name = new Char[1024]; strcpy(Cascade_name,"/usr/share/OpenCV/haarcascades/haarcascade_frontalface_

我正在使用函数cvhaardetecobjects进行人脸检测,虽然我认为我释放了所有的内存,但是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;
}
一旦对Img和Face进行了操作,我就在下面的代码中发布了它们。内存泄漏发生在检测功能内部。我在64位操作系统Fedora16上使用OpenCV 2.3.1。除内存泄漏外,整个程序可以正常终止


非常感谢

我找到了内存泄漏的原因。原因是:

MyImage
类构造函数中,我传入了一个
IplImage*p
指针,并执行以下操作:

mp = cvCloneImage(p);
其中,
mp
IplImage*
类的成员。我释放了创建新的
MyImage
类对象后传入的
IplImage*
指针,因为
cvCloneImage()
将创建一些内存。但是,我在类析构函数中释放了成员指针
mp
,而实际上它没有新的内存。它只指向由
cvCloneImage()
创建的内存。因此,
cvCloneImage()
创建的内存不会被释放。这就是内存泄漏的来源

因此,给定作为参数传入的
IplImage*p
,我在构造函数中执行以下操作:

mp = cvCreateImage(cvGetSize(p), p->depth, p->nChannels);
cvCopy(p, mp);
释放类析构函数中的
mp
指针将释放它创建的内存

执行此操作后,绝对丢失和间接丢失的内存将变为0,但仍有可能丢失内存,valgrind将所有丢失的记录指向OpenCV中的
cvHaarDetectObjects()
函数。而且大部分是由一些“新线程”问题引起的。因此,我在谷歌上搜索了这个问题,发现当涉及新线程时,
valgrind
有时确实会丢失内存。所以我监控了系统的内存使用情况。结果表明,当程序重复执行时,内存使用量没有增加

这就是我发现的

mp = cvCreateImage(cvGetSize(p), p->depth, p->nChannels);
cvCopy(p, mp);