[Insight-developers] Filters : GenerateData() : when to Allo cate ?

Miller, James V (CRD) millerjv@crd.ge.com
Wed, 31 Jan 2001 11:50:50 -0500


We'll put something together that will walk the programmer through the process.

As a stopgap...

There are two simple filters that illustrate the basic steps: ShrinkImage and NonThreadedShrinkImage.

If a filter can be multithreaded, then it will provide a ThreadedGenerateData() method. Otherwise a
filter must provide a GenerateData() method. In the multithreaded case, the GenerateData() method of
the superclass will divide the data into sections and call the ThreadedGenerateData() method for each
piece. The GenerateData() method always is responsible for allocating the output space.  This means
that if filter is single threaded, you are providing the GenerateData() method, and it is your
responsibility to call Allocate().  If your filter is multithreaded, then you are providing the
ThreadedGenerateData() method, and the superclass will call Allocate() for you.

For image processing filters, the default implementation of the pipeline mechanism will set the
Input's RequestedRegion to match the size of the Output's RequestedRegion. 

If a given filter needs more data on input (for neighborhood operators), the filter will need to
provide a GenerateInputRequestedRegion() method. (This addresses Paul's "neighborhood" and
"resampling" cases).

If a given filter cannot produce a subset of an image, for instance an FFT probably needs to produce
all of the output (i.e. it cannot stream), then the filter needs to override the
EnlargeOutputRequestedRegion(). In this case, the implementation would be something like 

  m_OutputImage->SetRequestedRegion( m_OutputImage->GetLargestPossibleRegion() );

Finally, a filter may need to override UpdateOutputInformation() if the output's "meta"-data is
different from it's input.  For instance, ShrinkImage needed to override this method so that it could
set the "spacing" of the output pixels.

If you override UpdateOutputInformation() you should call the superclass's implementation first and
then set only those components that need to be different for your filter.  This will make it easier
to add things down the line.


If you have provided the above methods, your GenerateData() method would look something like

  // Get the input and output pointers
  InputImagePointer  inputPtr = this->GetInput();
  OutputImagePointer outputPtr = this->GetOutput();

  // Since we are providing a GenerateData() method, we need to allocate the
  // output buffer memory (if we provided a ThreadedGenerateData(), then
  // the memory would have already been allocated for us).
  outputPtr->SetBufferedRegion( outputPtr->GetRequestedRegion() );
  outputPtr->Allocate();

...


The ShrinkImage class and the NonThreadedShrinkImage class are good examples of how to write a filter
that operates properly in the pipeline.  I tried to document these classes as "example" pipeline
objects.




-----Original Message-----
From: Paul Hughett [mailto:hughett@mercur.uphs.upenn.edu]
Sent: Wednesday, January 31, 2001 11:23 AM
To: luis.ibanez@ieee.org
Cc: insight-developers@public.kitware.com
Subject: Re: [Insight-developers] Filters : GenerateData() : when to
Allocate ?



Luis has said:

> Something  like:

> m_OutputImage->SetLargestPossibleRegion(
>   m_InputImage->GetLargestPossibleRegion() );

> m_OutputImage->SetBufferedRegion(
>   m_InputImage->GetBufferedRegion() );

> m_OutputImage->SetRequestedRegion(
>   m_InputImage->GetRequestedRegion() );

> m_OutputImage->Allocate();.

> ... and then process the pixels in RequestedRegion.


This particular protocol will work correctly only for point operations
on images.  Some other possibilities that need to be handled correctly:

neighborhood operations (convolution, dilation, etc): the source region
needs to be enough bigger than the destination to account for the
neighborhood of the operation

resampling: the source region needs to be determined by backprojecting
the destination through the transform, and enlarged enough to account
for the interpolation neighborhood

reductions (histogram, image moments, etc. that reduce the total number 
of pixels or data elements):  The source must be the entire image.


> According to the streaming policy, the output is the one
> that define the size of the region to compute,  and the
> input should be asked to produce this chunk of data,
> isn't it ?

> What is the right thing to do ?

We might want to actually write down a description of the architecture
and policies, so that latecomers like me have at least a fighting chance
of understanding it.  And I don't mean a PowerPoint presentation; I want
something complete and detailed enough that I can actually use it to
design code.

Paul Hughett

_______________________________________________
Insight-developers mailing list
Insight-developers@public.kitware.com
http://public.kitware.com/mailman/listinfo/insight-developers