Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ cvLoadImage函数中的内存泄漏_C++_C_Winforms_Visual Studio 2010_Opencv - Fatal编程技术网

C++ cvLoadImage函数中的内存泄漏

C++ cvLoadImage函数中的内存泄漏,c++,c,winforms,visual-studio-2010,opencv,C++,C,Winforms,Visual Studio 2010,Opencv,我在一个画框里做了一个强度计。为了制作这个强度计,我使用了一张图片作为拨号器(Dialer.bmp),并使用一条线来制作针。我正在使用openCV进行此操作。通过改变指针,我们在表单加载时创建了一个线程。代码如下 private: System::Void FocusExposure_Load(System::Object^ sender, System::EventArgs^ e) { if(ExposureThreadStatus) th-&g

我在一个画框里做了一个强度计。为了制作这个强度计,我使用了一张图片作为拨号器(Dialer.bmp),并使用一条线来制作针。我正在使用openCV进行此操作。通过改变指针,我们在表单加载时创建了一个线程。代码如下

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;

}
此代码工作正常,并根据我的要求提供输出。但唯一的问题是,当我打开表单时,它会导致内存泄漏。我在任务管理器中见过,也使用过“英特尔Vtune分析器”。此探查器在下一行显示不匹配的分配/解除分配

IplImage*Background=cvLoadImage(“Dialer.bmp”,1)

我们需要重新加载此图像,因为我们正在图像上画线,当指针指针发生变化时,需要不带指针的拨号器图像

有人能给我建议解决内存泄漏问题的方法吗


任何帮助都将不胜感激。

似乎有人不止一次调用了
drawImageMeter()
。问题是每次执行
cvLoadImage()
时,它都会在堆上为像素分配空间。因此,在显示图像后,应使用
cvReleaseImage()
释放图像,以便释放数据

一个快速而肮脏(可怕)的解决方案是:

但是您确实应该更改应用程序的设计以便
后台
只分配一次。为此,您可以将其设置为全局变量并将其加载到
main()
方法中,或者将其设置为
drawImageMeter()
的参数:


cvReleaseImage(背景)怎么样?听起来像是一个需要帮助的人step@vasile谢谢你的回复。当我使用cvReleaseImage(&Background)时,我无法在pictureBox上看到拨号器图像,我的应用程序突然关闭。因为您在释放图像时仍在使用bmp中打包的数据。因此,我的建议是返回几个步骤,学习一些关于一般编程问题、指针和内存管理的课程。不要把它当成个人的东西,但你真的需要它;花了数小时试图找出javacpp opencv应用程序内存泄漏的原因。最后,我开始注释所有代码,直到第一行包含
cvLoadImage()
,在一个大的训练图像目录上循环调用。。就在那时,我在谷歌上搜索到了正确的词,最终来到了这里。谢谢你。@SND很高兴你找到了它!这同样适用于JavaCV,在JavaCV中使用
image.release()
似乎不起作用,但
cvReleaseImage(image)
起作用。
static IplImage* Background =cvLoadImage("Dialer.bmp", 1);
System::Drawing::Bitmap^ drawImageMeter(IplImage* Background, float intensity_value)
{
   // code
}