Утечка памяти в функции cvLoadImage

Я сделал измеритель интенсивности в картинке. Для создания этого измерителя интенсивности я использовал рисунок в качестве Dialer (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;

}

Этот код работает нормально и дает вывод в соответствии с моим требованием. Но единственная проблема заключается в том, что когда я открываю форму, это вызывает утечку памяти. Я видел в диспетчере задач, а также использовал профилировщик Intel Vtune. Этот профилировщик показывает Несоответствующее распределение / освобождение на следующей строке

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

Нам нужно перезагрузить это изображение, потому что мы рисуем линию на изображении, а когда указатель иглы изменился, требуется изображение номеронабирателя без иглы.

Может кто-нибудь, пожалуйста, предложите мне любое решение для решения этой проблемы утечки памяти.

Любая помощь будет оценена.

1

Решение

Кажется, что drawImageMeter() вызывается не раз. Проблема в том, что каждый раз cvLoadImage() выполняется, он выделяет пространство в HEAP для пикселей. Таким образом, после отображения изображения вы должны отпустить его с cvReleaseImage() поэтому данные освобождаются.

Быстрое и грязное (и ужасное) решение было бы сделать variableстатический:

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

Но ты должен действительно изменить дизайн вашего приложения так Background он выделяется только один раз. Для этого вы можете сделать его глобальной переменной и загрузить его в main() метод или сделать его параметром drawImageMeter():

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]