[Insight-users] Modifying the output (buffer) of an image filter

Miller, James V (GE, Research) millerjv at crd.ge.com
Tue Mar 28 14:05:49 EST 2006


When you modify the output of a filter directly, you run the risk of 
your changes being overwritten by another execution of the pipeline.

In other words, if you modify the output of a filter, and later call
update on the pipeline, your changes may be lost (overwritten by 
the filter producing the output again).

If you want to modify the output of a filter without sending it to 
another filter, you can disconnect the output from the pipeline.

someFilter->Update();
imagePtr = someFilter->GetOutput();
imagePtr->DisconnectPipeline();

This isolates imagePtr from the upstream pipeline, so another call
to Update() on the pipeline will not overwite the pixels you 
manipulated.

If you are worried about memory management, you can use the 
ReleaseDataFlagOn() for a filter.  This method will set a flag
on the output of the filter such that when the next downstream
filter executes, it will free the previous image.

Many ITK filters can also run "InPlace" so that no additional memory
is created in executing the filters.

Jim

-----Original Message-----
From: insight-users-bounces+millerjv=crd.ge.com at itk.org
[mailto:insight-users-bounces+millerjv=crd.ge.com at itk.org]On Behalf Of
Karthik Krishnan
Sent: Tuesday, March 28, 2006 11:30 AM
To: Stefan Engstrom
Cc: Insight-users at itk.org
Subject: Re: [Insight-users] Modifying the output (buffer) of an image
filter


Please post some minimal compiling code.

Meanwhile here's a hunch:

When you say: "When I try to use this image I get the same thing I had 
coming in.", how are you trying to use the image ?
You will see below in your code that you've mixed actual pipeline 
obeying filters with your own "filters" crafted via iterators.

An "Image" in ITK has a notion of MTime, that indicates when the data 
was last generated. Pipeline filters have a notion of modified time that 
will regenerate the data if they deem it to be out of date.

If you craft your own code snippets that via iterators, for instance
  imageIterator.Set( .. )
will not change the MTime of the Image. It would be very inefficient to 
do so. If you do want to force it to change its MTime to the current 
time, explicity call image->Modified(). (although the recommended 
approach is to wrap them into filters, so your code looks cleaner too .. )

My guess is that you are modifying your image's output via iterators, 
and at a later stage again calling update on them, either manually or 
because you passed it on as an input some other filter. This would 
bypass the iterators if a parameter of the pipeline filter changed later.


Stefan Engstrom wrote:

>I have an image processing task that is fairly well described by
>existing filters in ITK. It takes an input image and a kernel, finds a
>locally smoothed version of the input image and tries to subtract that
>from the original input before that is passed on to a detection
>correlation with the kernel.
>
>The local average is over the same size as the input kernel which can
>be large so the calculation is done as a correlation in Fourier space.
>I accomplish that with the fftw filters, by multiplying the complex
>transforms using image iterators. The essential part of the code that
>does that looks some thing like this:
>
>  workRegStart[0]=0;
>  workRegStart[1]=0;
>  workReg.SetSize(
>        fftlmInput->GetOutput()->GetLargestPossibleRegion().GetSize());
>  workReg.SetIndex(workRegStart);
>
>  ComplexConstIteratorType iterfftlmKernel(fftlmKernel->GetOutput(),workReg);
>  ComplexIteratorType iterfftlmInput(fftlmInput->GetOutput(),workReg);
>
>  for(iterfftlmKernel.GoToBegin(),iterfftlmInput.GoToBegin();
>        !iterfftlmKernel.IsAtEnd(); ++iterfftlmKernel,++iterfftlmInput) {
>    iterfftlmInput.Set(iterfftlmKernel.Get()*iterfftlmInput.Get());
>  }
>
>The point of showing this here is that the fflmInput buffer is
>manipulated directly by the iterator. A little later I have the input
>image and a smoothed (shifted) version of the local mean calculation
>that I am trying to calculate the difference of and again put back
>into the filter buffer, but this time it does not work. The relevant
>code looks like this:
>
>  inputResampler->Update(); // we just converted the input image to
>something useful
>
>// Write a snapshot of what we are working on
>  tmprescaler->SetInput( inputResampler->GetOutput() );
>  tmprescaler->SetOutputMinimum(  0  );
>  tmprescaler->SetOutputMaximum( 255 );
>  tmpwriter->SetFileName("tmp-inputimage.png");
>  tmpwriter->SetInput(tmprescaler->GetOutput());
>  tmpwriter->Update();
>
>  WorkImageType::RegionType wr1,wr2;
>  WorkImageType::RegionType::IndexType wrStart1,wrStart2;
>  WorkImageType::RegionType::SizeType wrSize;
>
>
>  wrStart1[0]=kernelsize[0];
>  wrStart1[1]=kernelsize[1];
>  wrStart2[0]=kernelsize[0]/2; // The evaluation point for the local
>mean is shifted
>  wrStart2[1]=kernelsize[0]/2; // by half the kernelsize
>  wrSize[0]=inputsize[0];
>  wrSize[1]=inputsize[1];
>  wr1.SetSize(wrSize);
>  wr2.SetSize(wrSize);
>  wr1.SetIndex(wrStart1);
>  wr2.SetIndex(wrStart2);
>
>  WorkIteratorWithIndexType iter1(inputResampler->GetOutput(),wr1);
>  WorkIteratorWithIndexType iter2(lmFlipper->GetOutput(),wr2);
>
>  WorkPixelType
>kernelarea=static_cast<WorkPixelType>(kernelsize[0]*kernelsize[1]);
>  WorkPixelType a,lmean;
>  for(iter1.GoToBegin(),iter2.GoToBegin();
>        !iter1.IsAtEnd(); ++iter1,++iter2) {
>    lmean=iter2.Get()/kernelarea;
>    a=iter1.Get();
>    iter1.Set(a-lmean);
>      std::cout << "subtract: idx1=" << iter1.GetIndex() <<
>        ", idx2=" << iter2.GetIndex() <<", a=" << a <<
>        ", b=" << lmean << ", diff=" << iter1.Get() << std::endl;
>  }
>
>The indicies look good. I get values for 'a' and iter1.Get() is
>properly set in the loop. When I try to use this image I get the same
>thing I had coming in.
>
>Is the Fourier routine special in some way in that it lets me modify
>the buffer directly?
>What is the recommended approach for this? I am already worried about
>excessive memory use by having a longish string of filters connected
>up. It seems like very poor use of memory to create so many instances
>of the images for the filter flow.
>An image adapter does not seem to be the answer since I need to
>evaluate the result of two images (which have different origins).
>
>Any leads, practial or philosophical to this would be greatly appreciated.
>
>Stefan
>_______________________________________________
>Insight-users mailing list
>Insight-users at itk.org
>http://www.itk.org/mailman/listinfo/insight-users
>
>  
>
_______________________________________________
Insight-users mailing list
Insight-users at itk.org
http://www.itk.org/mailman/listinfo/insight-users


More information about the Insight-users mailing list