vtkWindowToImageFilter 导致内存泄漏?

vtkWindowToImageFilter causing memory leak?

我编写了一个小工具,可以从不同的摄像机角度创建多个 STL 的屏幕截图。 vtkWindowToImageFiltervtkWin32OpenGLRenderWindow 的内容转换为图像,之后 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);
   }
}

因为我注意到该工具从同一相机视角创建了多个屏幕截图(由 vtkWindowToImageFilter 的 SetInput 方法在循环外使用引起),我重写了代码以创建一个 vtkWindowToImageFiltervtkPngWriterforeach 循环中。这使我可以在使用它们后对其进行处理,从而释放内存。

请注意,在以前版本的代码中,我还尝试在循环结束后立即处理 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);
    }
}