我有一个运行良好的 c++-cli/opencv 程序,但它的一部分存在内存泄漏。我包括了内存泄漏最多的部分。我已经修复了轮廓 0 和轮廓 1 中的泄漏,这将内存泄漏减少了 1/3,但是仍然存在泄漏。有没有办法仍然减少内存泄漏?谢谢。
// capture video frame and convert to grayscale
const int nFrames0 = (int) cvGetCaptureProperty( capture0 , CV_CAP_PROP_FRAME_COUNT );
printf("LICENSECOUNT=%d\n",nFrames0);
img = cvQueryFrame( capture0 );
IplImage* frame1;
cvReleaseImage(&frame1);
frame1=cvCreateImage(cvSize(img->width,img->height),img->depth, 1 );
cvConvertImage(img, frame1,0);
// create blank images for storing
cvReleaseImage(&img00);
img00=cvCreateImage(cvSize(img->width,img->height),img->depth, 3 );
cvReleaseImage(&img10);
img10=cvCreateImage(cvSize(img->width,img->height),img->depth, 1 );
cvReleaseImage(&img20);
img20=cvCreateImage(cvSize(img->width,img->height),img->depth, 1 );
cvReleaseImage(&img30);
img30=cvCreateImage(cvSize(img->width,img->height),img->depth, 1 );
cvReleaseImage(&imggray1);
imggray1=cvCreateImage(cvSize(img->width,img->height),img->depth, 1 );
cvReleaseImage(&imgdiff);
imgdiff=cvCreateImage(cvSize(img->width,img->height),img->depth, 1 );
cvReleaseImage(&imgco);
imgco=cvCreateImage(cvSize(img->width,img->height),img->depth, 1 );
int flagp=1;
int licf=0;
CvSeq *contour0;
CvSeq* result0;
storage0 = cvCreateMemStorage(0);
CvRect r0;
//skip a few frames
for (int i=0;i<cf1-1;i++)
img = cvQueryFrame( capture0 );
// go through all frames to find frames that contain square with certain dimension
while ( key != 'q')
{
img = cvQueryFrame( capture0 );
if( !img ) break;
cvConvertImage(img,img00,0);
cvSetImageROI(img,cvRect(0,img->height-35,img->width,35));
cvZero(img);
cvResetImageROI(img);
cvConvertImage(img, img10,0);
cvConvertImage(img, img20,0);
cvConvertImage(img, imggray1,0);
int flagp=1;
cvAbsDiff(img10,frame1,imgdiff);
cvThreshold(imgdiff, imgdiff,60,255,CV_THRESH_BINARY);
mem0 = cvCreateMemStorage(0);
CvSeq *ptr,*polygon;
//vary threshold levels for segmentation
for (int thr=1;thr<11;thr++)
{
// do morphology if segmentation does not work
if (thr==10)
{
cvEqualizeHist( img20, img10 );
cvSetImageROI(img10,cvRect(0,0,20,img->height));
cvZero(img10);
cvResetImageROI(img10);
cvMorphologyEx(img20,img10,img20,cvCreateStructuringElementEx(20,10,10,5,CV_SHAPE_RECT,NULL),CV_MOP_TOPHAT,1);
IplImage *frame_copy1 = 0;
frame_copy1 = cvCreateImage(cvSize(img10->width,img10->height),IPL_DEPTH_16S,1 );
cvSobel(img10,frame_copy1,1,0,3);
cvConvertScaleAbs(frame_copy1, img10, 1, 0);
cvSetImageROI(img10,cvRect(0,0,20,img->height));
cvZero(img10);
cvResetImageROI(img10);
cvSetImageROI(img10,cvRect(img->width-20,0,20,img->height));
cvZero(img10);
cvResetImageROI(img10);
cvMorphologyEx(img10,img10,img20,cvCreateStructuringElementEx(16,5,8,3,CV_SHAPE_RECT,NULL),CV_MOP_CLOSE,1);
cvThreshold(img10,img10,180,255,CV_THRESH_BINARY | CV_THRESH_OTSU);
cvErode(img10,img10,cvCreateStructuringElementEx(10,5,5,2,CV_SHAPE_RECT,NULL),1);
cvErode(img10,img10,cvCreateStructuringElementEx(5,10,2,5,CV_SHAPE_RECT,NULL),1);
cvDilate(img10,img10,cvCreateStructuringElementEx(5,10,2,5,CV_SHAPE_RECT,NULL),1);
cvDilate(img10,img10,cvCreateStructuringElementEx(10,5,5,2,CV_SHAPE_RECT,NULL),1);
cvErode(img10,img10,cvCreateStructuringElementEx(10,5,5,2,CV_SHAPE_RECT,NULL),2);
cvDilate(img10,img10,cvCreateStructuringElementEx(10,5,5,2,CV_SHAPE_RECT,NULL),1);
}
//segmenation
else
{
cvThreshold(img20,img10,thr*255/11,255,CV_THRESH_BINARY);
cvDilate(img10,img10,cvCreateStructuringElementEx(10,5,5,2,CV_SHAPE_RECT,NULL),1);
cvDilate(img10,img10,cvCreateStructuringElementEx(20,30,10,15,CV_SHAPE_RECT,NULL),1);
}
//trim the sides of the image
cvSetImageROI(img10,cvRect(0,0,20,img->height));
cvZero(img10);
cvResetImageROI(img10);
cvSetImageROI(img10,cvRect(img->width-20,0,20,img->height));
cvZero(img10);
cvResetImageROI(img10);
cvReleaseImage(&imgco);
imgco = cvCloneImage(img10);
///find contours to find squares with certain dimension
cvRelease((void**)&contour0);
int Nc0;
Nc0= cvFindContours(imgco, storage0, &contour0, sizeof (CvContour),
CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
float k;
int white=0;
while( contour0 )
{
r0 = cvBoundingRect(contour0, 0);
double s,t;
if( ((r0.width*r0.height)>2000 || (r0.width*r0.height && thr==10)>1000) && (r0.width*r0.height) < 40000 && (float(r0.width)/float(r0.height))>1.7 && (float(r0.width)/float(r0.height))<5 )
{
k=0.8;
if (thr==10 && licf<2)
k=0.6 ;
cvSetImageROI(img10,r0);
cc=cvCountNonZero(img10);
cvResetImageROI(img10);
//if area of contour is a percentage of area of rectangle surrounding contour
if (cc>k*r0.width*r0.height && (cvCountNonZero(imgdiff)>10000))
{
cvSetImageROI(img,cvRect(0,img->height-35,img->width,35));
cvSet(img, cvScalar(255,255,255));
cvResetImageROI(img);
//process the image contained inside the contour area
cvSetImageROI(img,cvRect(r0.x-5,r0.y-10,r0.width+10,r0.height+20));
img30 = cvCreateImage( cvGetSize( img), IPL_DEPTH_8U, 1);
cvCvtColor( img, img30, CV_RGB2GRAY );
IplImage* img_temp=cvCreateImage(cvSize(2*r0.width,2*r0.height+20),img->depth, 1 );
IplImage* img_tempo=cvCreateImage(cvSize(2*r0.width,2*r0.height+20),img->depth, 1 );
cvResize(img30,img_tempo);
CvMemStorage *storage1;
CvSeq *contour1;
CvSeq* result1;
storage1 = cvCreateMemStorage(0);
CvRect r1;
//segment inside squares check if square contains letters or numbers with certain dimension
for (int th=20;th<200;th+=5)
{
cvThreshold(img_tempo, img_temp, th, 255, CV_THRESH_BINARY);
cvThreshold(img_temp, img_temp, 0, 255, CV_THRESH_BINARY_INV);
{
cvErode(img_temp,img_temp);
cvDilate(img_temp,img_temp);
cvErode(img_temp,img_temp);
}
cvResize(img_temp,img30);
cvRelease((void**)&contour1);
int Nc=cvFindContours(img30, storage1, &contour1, sizeof (CvContour),
CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE) ;
int count =0 ;
while( contour1)
{
r1 = cvBoundingRect(contour1, 0);
int s_y1av=0;
int s_y2av=0;
int s_x1av=0;
{
int s_x1=r1.x;
int s_y1=r1.y;
float width1=r1.width;
float height1=r1.height;
float ratio1= width1/height1;
//if contours match certain dimensions
if(ratio1>0.05 && ratio1<1 && height1>0.3*r0.height && width1>0.05*r0.width && width1<0.3*r0.width && width1*height1>60 && width1*height1<2000)
{
count+=1;
}
s_y1av=s_y1;
s_y2av=s_y1+height1;
}
contour1=contour1->h_next;
}
//if there are more than 3 letters/numbers and less than 9
if (count>=3 && count<9)
{
th=200;
thr=11;
if (thr!=10)
licf=1;
if (a)
{
cvNamedWindow( "license", 1 );
cvShowImage( "license", img00 );
cvWaitKey(1);
}
int jpeg_params[] = { CV_IMWRITE_JPEG_QUALITY, 80, 0 };
CvMat* buf0 = cvEncodeImage(".jpeg", img00, jpeg_params);
int img_sz=buf0->width*buf0->height;
array <Byte>^ hh = gcnew array<Byte> (img_sz);
Marshal::Copy( (IntPtr)buf0->data.ptr, hh, 0, img_sz );
if(!myResult->TryGetValue("PLATE", thisList4))
{
thisList4 = gcnew List<array<Byte>^>();
myResult->Add("PLATE", thisList4);}
thisList4->Add(hh);
}
cvResetImageROI(img);
}
}
}
contour0=contour0->h_next;
}
}
}