vtkWindowToImageFilter导致内存泄漏?

c# memory-leaks vtk

200 观看

1回复

167 作者的声誉

我编写了一个小工具,可以从不同的摄影机角度创建许多STL的屏幕截图。vtkWindowToImageFilter将的内容转换为vtkWin32OpenGLRenderWindow图像,然后vtkPngWriter用于将图像写入文件。

我已经注意到,该工具的内存使用量随着它制作的每个屏幕截图而不断增加。经过一些调试后,我发现导致内存增加的代码行有时无法释放

windowToImageFilter.Update();

有谁知道我是否应该释放使用的内存vtkWindowToImageFilter

这是一项完整功能,可以从一组不同的摄像机角度为一组STL创建屏幕截图。

public void makeImage(vtkRenderWindow window, vtkRenderer renderer, string filePrefix="")
{
    if (_parts.Count == 0)
       return;

    // Make cameras
    Cameras cameras = new Cameras(_axial, _coronal, _sagittal, _parts[0].center, _parts[0].zoomfactor);

    // VTK
    // Setup vtkPNGwriter
    vtkPNGWriter writer = vtkPNGWriter.New();
    // Setup window to image filter
    vtkWindowToImageFilter windowToImageFilter = vtkWindowToImageFilter.New();
    windowToImageFilter.SetInput(window);
    windowToImageFilter.SetMagnification(2); // set the resolution of the output image (3 times the current resolution of vtk render window)

    foreach (string camName in cameraNames)
    {
       vtkCamera cam = cameras.getCameraByName(camName);
       if (cam == null)
           continue;

       // Skip already created screenshots
       if (File.Exists(getFilename(camName,filePrefix)))
            continue;

       // Clear renderer
       renderer.RemoveAllViewProps();

       // Show parts
       this.show(renderer);

       // Set camera
       renderer.SetActiveCamera(cam);
       renderer.GetActiveCamera().SetClippingRange(1.0, 1000);
       window.Render();

       // Update window to image filter
       windowToImageFilter.Update();

       // Write to png
       writer.SetFileName(tempFile);
       writer.SetInput(windowToImageFilter.GetOutput());
       writer.Write();

       // Crop png image
       Bitmap img = new Bitmap(tempFile);
       Bitmap imgCrop = cropImage(img);
       imgCrop.MakeTransparent(Color.White);
       imgCrop.Save(getFilename(camName,filePrefix));

       // Dispose images (necessary to avoid memory filling)
       img.Dispose();
       imgCrop.Dispose();

       // Delete temporary file
       File.Delete(tempFile);
   }
}
作者: Yurrit Avonds 的来源 发布者: 2016 年 1 月 8 日

回应 (1)


0

167 作者的声誉

决定

因为我注意到该工具从同一摄像机角度创建了多个屏幕截图(由SetInput方法vtkWindowToImageFilter在循环外部使用引起),所以我重新编写了代码以在循环内部创建vtkWindowToImageFilter和。这使我可以在使用完它们后对其进行处置,以释放内存。vtkPngWriterforeach

请注意,在以前的代码版本中,我还尝试在循环结束后立即处理vtkWindowToImageFiltervtkPngWriter,但是似乎没有释放任何内存。不幸的是,我不清楚为什么这行不通。

如前所述,当前版本的代码看起来像这样,不会引起内存泄漏。

public void makeImage(vtkRenderWindow window, vtkRenderer renderer,string filePrefix="")
{
    if (_parts.Count == 0)
        return;

    // Make cameras
    Cameras cameras = new Cameras(_axial, _coronal, _sagittal, _parts[0].center, _parts[0].zoomfactor);

    foreach (string camName in cameraNames)
    {
        vtkCamera cam = cameras.getCameraByName(camName);
        if (cam == null)
            continue;
        // Skip already created screenshots
        if (File.Exists(getFilename(camName, filePrefix)))
            continue;

        // Clear renderer
        renderer.RemoveAllViewProps();

        // Show parts
        this.show(renderer);

        // Set camera
        renderer.SetActiveCamera(cam);
        renderer.GetActiveCamera().SetClippingRange(1.0, 1000);
        window.Render();

        // Update window to image filter
        vtkWindowToImageFilter windowToImageFilter = vtkWindowToImageFilter.New();
        windowToImageFilter.SetMagnification(4); // set the resolution of the output image (3 times the current resolution of vtk render window)
        windowToImageFilter.SetInput(window);

        // Write to png
        vtkPNGWriter writer = vtkPNGWriter.New();
        writer.SetInputConnection(windowToImageFilter.GetOutputPort());
        writer.SetFileName(tempFile);
        writer.Write();

        // Dispose pipeline parts
        windowToImageFilter.Dispose();
        writer.Dispose();

        // Crop png image
        Bitmap img = new Bitmap(tempFile);
        Bitmap imgCrop = cropImage(img, squareImages);
        imgCrop.MakeTransparent(Color.White);
        imgCrop.Save(getFilename(camName,filePrefix));

        // Dispose images (necessary to avoid memory filling)
        img.Dispose();
        imgCrop.Dispose();

        // Delete temporary file
        File.Delete(tempFile);
    }
}
作者: Yurrit Avonds 发布者: 15.01.2016 12:19
32x32