[Insight-users] more problems concerning memory and release data flags

Michael Kuhn michakuhn at gmx . ch
Wed, 03 Sep 2003 12:48:01 -0600


Hi,

I have two more problems concerning memory and release data flags.

1.) It seems to me, that there is a problem with release data flags and 
the VTKImageToImageFilter. I believe, that the filter that directely 
preceeds the VTKImageToImageFilter does not release its data even tough 
its release data flag is set to true.

2.) If I use a bspline interpolation for my ResampleImageFilter, the 
filter uses more memory than if I use a linear interpolation. The amount 
of the additional memory depends on the last template parameter. For 
double, the increase is 8 times, for float 4 times and for short twice 
the amount of pixels of the image (in bytes). So, it seems one copy of 
the whole image in the respective data type is stored during the 
resampling process. If no release data flag is set, this memory is not 
freed afterwards. Is it necessary to keep two copies of the data during 
resampling, and would it be possible to free this memory after the 
resampling process has finished (independent on whether the release data 
flag of the filter is set or not)?

I've again set up a simple program, that demonstrates these effects. 
After each update() call, there is a cin statement which is intended to 
stop the application. At these moments, the memory usage can easily be 
checked using a system tool like top (unix) or the windows task manager.

Thanks,

Michael




#include "itkImage.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkBSplineInterpolateImageFunction.h"
#include "itkVTKImageToImageFilter.h"
#include "itkResampleImageFilter.h"
#include "itkAffineTransform.h"
#include "vtkImageReslice.h"
#include "vtkIdentityTransform.h"

int main(int argc, char** argv) {
    char ch[10];
    cout << "starting memory debug project..." << endl;
    cout << "please enter a character to continue: ";
    cin >> ch;
    cout << "generating data..." << endl;
    int size = 100;
    vtkImageData* data = vtkImageData::New();
    data->SetDimensions(size, size, size);
    data->SetScalarTypeToShort();
    data->AllocateScalars();
    for (int x = 0; x < size; x++) {
        for (int y = 0; y < size; y++) {
            for (int z = 0; z < size; z++) {
                short* tmp = (short*)data->GetScalarPointer(x, y, z);
                if (x >= 2 && x < 10 && y >= 2 && y < 10 && z >= 2 && z 
< 10)
                {
                    *tmp = 5;
                } else {
                    *tmp = 0;
                }
            }
        }
    }

    cout << "Data generated." << endl;
    cout << "Enter a character to continue: ";
    cin >> ch;
    cout << "applying vtkFilter..." << endl;

    vtkImageReslice* vtkFilter = vtkImageReslice::New();
    vtkFilter->SetResliceTransform(vtkIdentityTransform::New());
    vtkFilter->SetReleaseDataFlag(true);
    vtkFilter->SetInput(data);
    vtkFilter->Update();

    cout << "vtkFilter updated." << endl;
    cout << "Enter a character to continue: ";
    cin >> ch;
    cout << "applying vtkFilter2..." << endl;

    vtkImageReslice* vtkFilter2 = vtkImageReslice::New();
    vtkFilter2->SetResliceTransform(vtkIdentityTransform::New());
    vtkFilter2->SetReleaseDataFlag(true);
    vtkFilter2->SetInput(vtkFilter->GetOutput());
    vtkFilter2->Update();

    cout << "vtkFilter2 updated." << endl;
    cout << "Enter a character to continue: ";
    cin >> ch;
    cout << "applying vtk2itk..." << endl;

    typedef itk::Image<short, 3> ImageType;
    typedef itk::VTKImageToImageFilter<ImageType> VTK2ITKType;
    VTK2ITKType::Pointer vtk2itk = VTK2ITKType::New();
    vtk2itk->SetInput(vtkFilter2->GetOutput());
    vtk2itk->GetImporter()->Update();
    ImageType::Pointer image1 = vtk2itk->GetImporter()->GetOutput();

    cout << "vtk2itk updated." << endl;
    cout << "Enter a character to continue: ";
    cin >> ch;
    cout << "applying resampleFilter..." << endl;

    typedef itk::ResampleImageFilter<ImageType, ImageType> 
ResampleFilterType;
    ResampleFilterType::Pointer resampleFilter = ResampleFilterType::New();
    
    
    // BSPLINE BLOCK
    typedef itk::BSplineInterpolateImageFunction<ImageType, double, float>
        BSplineType;
    BSplineType::Pointer interpolator = BSplineType::New();
    interpolator->SetSplineOrder(3);
    
    
    /*
    // LINEAR BLOCK
    typedef itk::LinearInterpolateImageFunction<ImageType, double>
        LinearType;
    LinearType::Pointer interpolator = LinearType::New();
    */    

    typedef itk::AffineTransform<double, 3> AffineType;
    AffineType::Pointer affineTransform = AffineType::New();

    AffineType::ParametersType affineParams(12);
    affineParams[0] = 1;
    affineParams[1] = 0;
    affineParams[2] = 0;
    affineParams[3] = 0;
    affineParams[4] = 1;
    affineParams[5] = 0;
    affineParams[6] = 0;
    affineParams[7] = 0;
    affineParams[8] = 1;
    affineParams[9] = 0;
    affineParams[10] = 0;
    affineParams[11] = 0;

    affineTransform->SetParameters(affineParams);
    resampleFilter->SetInterpolator(interpolator);
    resampleFilter->SetTransform(affineTransform);
    resampleFilter->SetInput(image1);

    resampleFilter->SetOutputOrigin(image1->GetOrigin());
    resampleFilter->SetOutputSpacing(image1->GetSpacing());
    resampleFilter->SetSize(image1->GetBufferedRegion().GetSize());
    resampleFilter->SetDefaultPixelValue(1);
    resampleFilter->Update();
    ImageType::Pointer image2 = resampleFilter->GetOutput();

    cout << "resampleFitler updated." << endl;
    cout << "Enter a character to continue: ";
    cin >> ch;
    cout << endl;

    for (int x = 0; x < 12; x++) {
        for (int y = 0; y < 12; y++) {
            for (int z = 0; z < 12; z++) {
                ImageType::IndexType idx;
                idx[0] = x;
                idx[1] = y;
                idx[2] = z;
                cout << image2->GetPixel(idx) << " ";
            }
            cout << endl;
        }
        cout << endl;
        cout << endl;
    }

    return 0;
}