我正在使用函數cvHaarDetectObjects進行人臉檢測,並且使用valgrind進行內存泄漏檢查,即使我認爲我釋放了所有內存。我真的不知道如何解決內存泄漏問題。這是我的代碼:cvHaarDetectObjects內存泄漏
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* p
作爲成員的包裝類的IplImage的。如果構造函數使用IplImage* ppara
作爲參數,則成員p
將使用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);
我發佈圖和臉部下面的代碼,一旦對它們的操作完成。內存泄漏發生在Detect功能內部。我在64位操作系統的Fedora 16上使用OpenCV 2.3.1。除了內存泄漏外,整個程序可以正常終止。
非常感謝。