简体   繁体   English

cvLoadImage函数中的内存泄漏

[英]Memory leak in cvLoadImage function

I have made an Intensity meter in a pictureBox. 我在pictureBox中制作了一个强度计。 For making this intensity meter I have used a picture as Dialer(Dialer.bmp) and making needle using a line. 为了制作这种强度计,我使用了一张照片作为Dialer(Dialer.bmp)并使用一条线制作针。 I am doing this using openCV. 我是用openCV做的。 And changing the needle pointer we have created a thread at form load. 并且更改了针指针,我们在表单加载时创建了一个线程。 And the code is as follows 代码如下

private: System::Void FocusExposure_Load(System::Object^  sender, System::EventArgs^  e) {
 if(ExposureThreadStatus)
                     th->Abort();
                 th = gcnew Thread(gcnew ThreadStart(this,&FocusExposure::UpdateIntensity)); 
                th->Start();
                ExposureThreadStatus = true;
                }


void UpdateIntensity()
{
Intensity_Values data;
 while(1)
 {

 data = ReadImage(focusBuffer);
    System::Drawing::Bitmap ^bmp=drawImageMeter(data.Max);
     this->pictureBox1->Image =this->pictureBox1->Image->FromHbitmap(bmp->GetHbitmap());
     delete bmp;
     Sleep(1000);                   
 }
}

 System::Drawing::Bitmap^ drawImageMeter(float intensity_value)
{
        IplImage  *Background =cvLoadImage("Dialer.bmp", 1);
        int width,height;
        if(counter==1)
        {
        width=Background->width;
           height=Background->height;
            counter++;
        needle_center.x=width/2;
        needle_center.y=height/2;
        needle_top.x=needle_center.x;
        needle_top.y=needle_center.y-140;
        }
            double const PI = 3.14159265358979323;
           int x1 = needle_top.x; 
           int y1 = needle_top.y;
           int x0=needle_center.x;
           int y0=needle_center.y;
           float angle;
            CurrIntensity = intensity_value;
            angle = CurrIntensity-PreIntensity;
            angle= 0.0703125f * angle;
           // degrees, not radians
           float radians = angle * (PI / 180.0f);   // convert degrees to radians

           if (current_max==1)
            {
                current_max++;
                int N1x1 = needle_top.x; 
                int N1y1 = needle_top.y;
                needle1_top.x = ((N1x1-x0) * cos(radians)) - ((N1y1-y0) * sin(radians)) + x0; 
                needle1_top.y = ((N1x1-x0) * sin(radians)) + ((N1y1-y0) * cos(radians)) + y0;
            }
           needle_top.x = ((x1-x0) * cos(radians)) - ((y1-y0) * sin(radians)) + x0; 
           needle_top.y = ((x1-x0) * sin(radians)) + ((y1-y0) * cos(radians)) + y0;

           cvLine(Background, needle_center, needle1_top, CV_RGB(0, 0, 255), 1, 4, 0);
           cvLine(Background, needle_center, needle_top, CV_RGB(255, 0, 0), 1, 4, 0);
         System::Drawing::Bitmap ^bmp = gcnew System::Drawing::Bitmap(Background->width,Background->height,Background->widthStep,System::Drawing::Imaging::PixelFormat::Format24bppRgb,(System::IntPtr)Background->imageData);
         PreIntensity = CurrIntensity;
         return bmp;

}

This code is working fine and giving output as per my requirement. 此代码工作正常,并根据我的要求提供输出。 But The only problem is that when I am opening the form It is giving memory leak. 但唯一的问题是,当我打开表单时它会给内存泄漏。 I have seen in task manager and also used Intel Vtune profiler. 我在任务管理器中看到过并且还使用了英特尔Vtune分析器。 This profiler is showing Mismatched allocation/deallocation at the following line 此分析器在以下行显示不匹配的分配/取消分配

IplImage *Background =cvLoadImage("Dialer.bmp", 1);

We need to reload this image because we are drawing the line at the image and when needle pointer has changed it require the Dialer Image without needle. 我们需要重新加载此图像,因为我们在图像上绘制线条,当针指针发生变化时,它需要不带针的拨号器图像。

Can anybody please suggest me any solution to solve this memory leak Issue. 任何人都可以建议我解决这个内存泄漏问题的任何解决方案。

Any help will be appreciated. 任何帮助将不胜感激。

It seems that drawImageMeter() is being called more than once. 似乎drawImageMeter()被多次调用。 The problem is that each time cvLoadImage() is executed, it allocates space on the HEAP for the pixels. 问题是每次执行cvLoadImage() ,它都会在HEAP上为像素分配空间。 So after displaying the image you should release it with cvReleaseImage() so the data get's freed. 因此,在显示图像后,您应该使用cvReleaseImage()释放它,以便释放数据。

A quick and dirty (and horrible) fix would be to make the variable static : 一个快速而肮脏(和可怕)的修复方法是使variable变为静态

static IplImage* Background =cvLoadImage("Dialer.bmp", 1);

But you should really change the design of your application so Background it's allocated only once. 但是你应该真正改变你的应用程序的设计,所以Background只分配一次。 To do that you can either make it global variable and load it on the main() method, or make it a parameter of drawImageMeter() : 要做到这一点,你可以使它成为全局变量并将其加载到main()方法,或使其成为drawImageMeter()的参数:

System::Drawing::Bitmap^ drawImageMeter(IplImage* Background, float intensity_value)
{
   // code
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM