# Moving data from VTK to ITK: issue in memory management

**URL:** https://discourse.vtk.org/t/moving-data-from-vtk-to-itk-issue-in-memory-management/16363
**Category:** Support
**Tags:** code
**Created:** [March 30, 2026, 12:54pm UTC](https://discourse.vtk.org/t/moving-data-from-vtk-to-itk-issue-in-memory-management/16363 "2026-03-30T12:54:34Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Boris38](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/b/b487fb/32.png) [@Boris38](https://discourse.vtk.org/u/Boris38)
#### Post date: [March 30, 2026, 12:54pm UTC](https://discourse.vtk.org/t/moving-data-from-vtk-to-itk-issue-in-memory-management/16363/1 "2026-03-30T12:54:34Z")

</div>

Hello everyone.

I use ITK (5.4.4) and VTK (9.5.2) in my code. I use some VTK classes (like vtkImageStencil) which use some mesh (vtkPolyData) and i want the result in an ITK image.  
To convert result of the vtkImageStencil in an ITK image, i use VTKImageToImageFilter.  
When i get the output of the VTKImageToImageFilter in my itk image, it seems that the data buffer is still managed by the vtkImageStencil. Indeed when i delete the vtkImageStencil and after try to access the data buffer of my itk image, the application crash.  
I try to duplicate the output of the VTKImageToImageFilter, before filling my ITK Image, it seems to fix my issue.  
I see nowhere in the documentation that the user must copy the buffer/the Stencil keep the control of the output buffer.

Am i using the right classes in the right way ?  
Is this a lack of detail in the documentation, or a bug in the expected behavior of the VTK classes?

Thank

Here a minimal sample:

```auto
#include “itkImage.h”
#include “itkVTKImageToImageFilter.h”

#include <vtkNew.h>
#include <vtkImageStencil.h>
#include <vtkPolyDataToImageStencil.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkDataArray.h>
#include <vtkImageData.h>
#include <vtkSphereSource.h>
#include // juste use for qDebug
#include “itkMinimumMaximumImageCalculator.h”

class Voxelisation
{
    public:

    Voxelisation() = default;
    ~Voxelisation() = default;

    void setInputData(vtkPolyData* p_inputData);

    void execute(itk::Image<unsigned char, 3>::Pointer& p_outputImage);

    std::array<double, 3> m_spacing {0.5, 0.5, 0.5};

    unsigned char m_backgroundValue {0};

    unsigned char m_foregroundValue {255};

    vtkNew<vtkImageStencil> m_vtkImageStencil;
};

void Voxelisation::setInputData(vtkPolyData* p_inputData)
{
    vtkNew whiteImage;
    std::array<double, 3> origin;
    {
        std::array<double, 6> bounds;
        p_inputData->GetBounds(bounds.data());
        whiteImage->SetSpacing(m_spacing.data());
        std::array<int, 3> dim;
        for (size_t i = 0; i < 3; i++)
        {
              dim[i] = static_cast(ceil((bounds[i * 2 + 1] - bounds[i * 2]) / m_spacing[i]));
        }
        whiteImage->SetDimensions(dim.data());
        whiteImage->SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1);
        origin[0] = bounds[0] + m_spacing[0] / 2;
        origin[1] = bounds[2] + m_spacing[1] / 2;
        origin[2] = bounds[4] + m_spacing[2] / 2;
        whiteImage->SetOrigin(origin.data());
        whiteImage->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
        const vtkIdType count = whiteImage->GetNumberOfPoints();
        for (vtkIdType i = 0; i < count; ++i)
        {
             whiteImage->GetPointData()->GetScalars()->SetTuple1(i, m_foregroundValue);
        }
    }
    vtkNew<vtkPolyDataToImageStencil> vtkPolyDataToImageStencil;
        {
        vtkPolyDataToImageStencil->SetInputData(p_inputData);
        vtkPolyDataToImageStencil->SetOutputOrigin(origin.data());
        vtkPolyDataToImageStencil->SetOutputSpacing(m_spacing.data());
        vtkPolyDataToImageStencil->SetOutputWholeExtent(whiteImage->GetExtent());
        vtkPolyDataToImageStencil->Update();
    }

    m_vtkImageStencil->SetInputData(whiteImage);
    m_vtkImageStencil->SetStencilConnection(vtkPolyDataToImageStencil->GetOutputPort());
    m_vtkImageStencil->ReverseStencilOff();
    m_vtkImageStencil->SetBackgroundValue(m_backgroundValue);
}

void Voxelisation::execute(itk::Image<unsigned char, 3>::Pointer& p_outputImage)
{
    m_vtkImageStencil->Update();
    auto VTKImageToImageFilter = itk::VTKImageToImageFilter<itk::Image<unsigned char, 3>>::New();
    VTKImageToImageFilter->SetInput(m_vtkImageStencil->GetOutput());
    VTKImageToImageFilter->UpdateLargestPossibleRegion();

    qDebug() << "refCount inside Voxelisation" << VTKImageToImageFilter->GetOutput()->GetReferenceCount(); //1

    p_outputImage = VTKImageToImageFilter->GetOutput();
    qDebug() << "refCount p_outputImage inside Voxelisation" << p_outputImage->GetReferenceCount(); // 2
    if( p_outputImage == nullptr)
    {
        qDebug() << "outputImage is nullptr";
    }
    else {
        qDebug() << "outputImage is not null"; // not null
    }
}

int main(int argc, char *argv)
{
    itk::Image<unsigned char, 3>::Pointer outputImage = nullptr;
    vtkNew<vtkPolyData> mesh;

    //Fill the Mesh with a Sphre inside
    vtkNew<vtkSphereSource> sphereSource;
    sphereSource->SetPhiResolution(21);
    sphereSource->SetThetaResolution(21);
    sphereSource->SetRadius(20);
    sphereSource->SetCenter(0,0,0);
    sphereSource->SetOutput(mesh);
    sphereSource->Update();

    Voxelisation voxelAlgo;
    voxelAlgo.setInputData(mesh);
    voxelAlgo.execute(outputImage);

    if(outputImage == nullptr)
    {
        qDebug() << "outputImage == nullptr";
        return 1;
    }

    //Check refcount of the output image
    qDebug() << "ref count of the output image" << outputImage->GetReferenceCount(); //1

    //check some value inside the output image
    {
        auto imageCalculatorFilter = itk::MinimumMaximumImageCalculator<itk::Image<unsigned char, 3>>::New();
        imageCalculatorFilter->SetImage(outputImage);
        imageCalculatorFilter->SetRegion(outputImage->GetLargestPossibleRegion());
        imageCalculatorFilter->ComputeMaximum();
        const unsigned char maximum = imageCalculatorFilter->GetMaximum();
        qDebug() << "maximum before delete" << maximum; // value is 255
    }

    // now delete the stencil object
    voxelAlgo.m_vtkImageStencil->Delete();

    //Check refcount of the output image again
    // must be the same
    qDebug() << "ref count of the output image again" << outputImage->GetReferenceCount(); //1

    //check some value inside the output image again
    {
        auto imageCalculatorFilter = itk::MinimumMaximumImageCalculator<itk::Image<unsigned char, 3>>::New();
        imageCalculatorFilter->SetImage(outputImage);
        imageCalculatorFilter->SetRegion(outputImage->GetLargestPossibleRegion());
        qDebug() << "before recalcul the maximum after delete";
        imageCalculatorFilter->ComputeMaximum(); //CRASH here
        qDebug() << "Crash just before";
        const unsigned char maximum = imageCalculatorFilter->GetMaximum();
        qDebug() << "maximum after delete" << maximum;
    }
}

```

Result of this code is:  
refCount inside Voxelisation 1  
refCount p\_outputImage inside Voxelisation 2  
outputImage is not null  
ref count of the output image 1  
maximum before delete 255  
ref count of the output image again 1  
before recalcul the maximum after delete

---

<div class="post-metadata">

### Author: ![mwestphal](https://discourse.vtk.org/user_avatar/discourse.vtk.org/mwestphal/32/19_2.png) [@mwestphal](https://discourse.vtk.org/u/mwestphal)
#### Post date: [March 30, 2026, 1:09pm UTC](https://discourse.vtk.org/t/moving-data-from-vtk-to-itk-issue-in-memory-management/16363/2 "2026-03-30T13:09:49Z")

</div>

You may want to ask on ITK discourse: [https://discourse.itk.org/](https://discourse.itk.org/)

---

<div class="post-metadata">

### Author: ![Boris38](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/b/b487fb/32.png) [@Boris38](https://discourse.vtk.org/u/Boris38)
#### Post date: [March 30, 2026, 1:56pm UTC](https://discourse.vtk.org/t/moving-data-from-vtk-to-itk-issue-in-memory-management/16363/3 "2026-03-30T13:56:31Z")

</div>

> **[Moving data from VTK to ITK: issue in memory management](https://discourse.itk.org/t/moving-data-from-vtk-to-itk-issue-in-memory-management/7740)**
>
> Hello everyone, I was advised to post this topic here. But the initial issue is here: Moving data from VTK to ITK: issue in memory management - Support - VTK I use ITK (5.4.4) and VTK (9.5.2) in my code. I use some VTK classes (like...

Ok i’ve juste create this issue on ITK discourse
