Opencv cvHaarDetectObjects内存泄漏
我正在使用函数cvhaardetecobjects进行人脸检测,虽然我认为我释放了所有的内存,但是valgrind进行了内存泄漏检查。我真的不知道如何修复内存泄漏。这是我的密码: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_
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);