[Insight-users] How to re-use a filter output?

Miller, James V (Research) millerjv at crd.ge.com
Thu Jul 15 09:51:54 EDT 2004


Yann,

I'd need to see more of your code to provide a meaningful answer. But here
is some background that may help.

It sounds like you may need to add a GraftOutput() capability to your 
filter.  You can do this without actually providing a GraftOutput() method, 
just put in the equivalent type of code in your GenerateData().

GraftOutput() does not do a deep copy of the data.  Rather, it merely
copies pointers.  In your case, you will need to determine whether you 
can copy the pointers safely.  In the case of images, the pixel data is held
in PixelContainer which is a subclass of Object.  So the PixelContainer
is reference counted and accessed via a SmartPointer. So copying pointers
to PixelContainers is a safe operation. Scope is properly managed.

In the case of images, GraftOutput() does two operations.  One it copies the

meta-data (spacing, origin, regions), and two it shallow copies the pixel
container.  In many uses of GraftOutput(), you will see two calls to 
GraftOutput within a single GenerateData() method.  The first call sets up
the mini-pipeline to compute on the same regions as specified for the
outer filter.  The second call puts the pixel data output back on the output

of the filter.

Grafting is used instead of calling SetOutput()/SetNthOutput() because you
typically need keep the same DataObject between filters.  For example, if
we have filters Alpha and Beta and a pipeline that looks like

Beta->SetInput( Alpha->GetOutput() );

Alpha's output DataObject serves as the connection between filters Alpha
and Beta.  If Alpha's output DataObject is replaced by a new DataObject
during
its GenerateData() method, then the pipeline is disconnected.  Beta's input
is still Alpha's original output. So once Alpha is finished executing, Beta
will execute but it will operate on the original output of Alpha and not on 
the new output of Alpha.

So grafting is used to keep the same DataObjects between filters to maintain

pipeline connectivity and grafting merely shallow copies the pixel data from

one DataObject to another.  You can think of this as now having two 
separate DataObjects that reference the same data.  Usually, one of these 
DataObjects will fall out of scope, and the pixel data will end up with one
owner.

Jim





-----Original Message-----
From: Lemeur Yann [mailto:Yann.Lemeur at stage.cnes.fr]
Sent: Thursday, July 15, 2004 3:08 AM
To: insight-users at itk.org
Subject: RE: [Insight-users] How to re-use a filter output?


Thanks Luis,

I had seen the GraftOutput() method in a mini-pipeline (it was
itkWatershedImageFilter). But the problem is that my filters don't give an
image as output. So there aren't an ImageToImageFilter and then, I can't use
the GraphtOutput() method which is implemented in itkImageSource.
I suppose the solution is to make such GraphtOutput method for my output
object, but this is equivalent to a copy. Since my output object can be very
heavy, I wanted to avoid this copy.
Is there really no mean to collect the output of my last filter in the
output of the mini-pipeline by pointer?

thanks a lot!

Yann 



> ----------
> De : 	Luis Ibanez[SMTP:luis.ibanez at kitware.com]
> Date :	mardi 13 juillet 2004 22:19
> A :	Lemeur Yann
> Cc :	insight-users at itk.org
> Objet :	Re: [Insight-users] How to re-use a filter output?
> 
> 
> Hi Lemeur,
> 
> When you create a filter with a mini-pipeline inside
> You should use GraftOutput() in order to take the output
> image of your mini-pipeline and graft it as the output of
> your own filter.
> 
> 
> For an example, you may want to look a the files
> 
>    Insight/Code/BasicFilter/
>     itkSmoothingRecursiveGaussianImageFilter.txx
> 
> 
> In your code it will be something like
> 
>         this->GraftOutput( M->GetOutput() );
> 
> instead of
> 
>         this->SetNthOutput( output ).
> 
> 
> Regards,
> 
> 
>     Luis,
> 
> 
> ------------------
> 
> Lemeur Yann wrote:
> 
> > Hi all!
> > 
> > I'm confronted to a problem with filters derived from itkProcessObject.
> > I've made my own filters (3 filters: A, B and C) which use some
DataObjects I've also created.
> > In order to simplify the use of these filters, I've packed them in one
filter called M.
> > In the GenerateData() of M, the three filters are executed to produce
the output of M (this output is a Tree, a class I've made):
> > 
> > M::GenerateData()
> > {
> > 		.....
> > 		.....
> > 		.....
> > 		
> > typename TreeType::Pointer output= this->GetOutput();
> > 
> > A->SetInput(M->GetInput());
> > B->SetInput(A->GetOutput());
> > C->SetInput(B->GetOutput());
> > 
> > output=M->GetOutput();
> > C->Update();
> > 
> > this->SetNthOutput(0,output);
> > 
> > } // end of M::GenerateData()
> > 
> > In a main file, I've written:
> > 
> > TreeType::Pointer tree=M->GetOutput();
> > M->Update();
> > 
> > I've seen that the output var is ok after the C->Update() in the
M::GenerateData() method. But in my main program, the pointer tree seems to
be assigned to an empty Tree.
> > 
> > I think the problem is that the GetOutput() method return a raw pointer
so the output var is not available outside the scope of GenerateData() (it
might be deleted somewhere...).
> > So I can't produce the output of M!
> > 
> > Daes anybody know how to link the output of M whith the output of C,
without copying the Tree objects (ie without making
*output=*(C->GetOutput()) ) ?
> > 
> > Thanks.    
> > 
> > _______________________________________________
> > 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