[Insight-developers] Confused about persistance of filter outputs

Hans Johnson hans-johnson@uiowa.edu
Mon, 28 Apr 2003 11:02:35 -0500


Luis,

You are correct, I ment itk::Image<>::Pointer in all the examples below. 
    I should know better than to ask for help, and then provide poor 
description of what I want help on.

I have worked through my problems up to this point, so do not feel that 
I need a personal response.  I just feel that these comments may help 
other developers, and would be a good addition to the software guide. 
Some of this information is in the Software guide already, but it is of 
such importance to using ITK that I think it needs a little more emphasis.

I have not run into many problems when designing new applications, 
because the are ITK'ized from the start, and all the magic smartpointer 
handeling is behind the scenes appropriatly.  My problems have been in 
handeling the instatiation and assignement of images while trying to 
insert our in-house functions in the middle of an ITK image processing 
stream.

I gave the example template problems that I have found to be most 
difficult to figure out when integrating ITK into current projects. 
Because most of the projects that I work on have a "c" programming 
mentality (pass images/objects through functions that modify the 
images/objects), it is often difficult to flip back to the ITK piple 
mentality.

For example, how should I set up a pipeline to process 100 images? 
Should I set up 100 identical pipelines?  Should I instantiate a new 
pipeline for every image?  Is there a simple pipeline call that will 
release the output smart pointer, and instantiate a new output pointer 
for the next image?

Finally, something that I still do not fully understand is how 
"messages" get propogated back through the pipeline to initiate 
evaluation.  When several filters are chained together, how does the 
message get propogated back?

===========================================================
itk::ImageFileWriter<> myfio=itk::ImageFileWriter<>::New()
{
itk::Image::Pointer IntermediateImage;
{
     itk::Image::Pointer InputImage<>;
     Filter1->SetInput(InputImage);
     Filter2->SetInput(Filter1->GetOutput());
     ...

     IntermediateImage=Filter19.GetOutput();
     myfio->SetInput(IntermediateImage);
     // ERROR:  myfio->Update()
     Filter20->SetInput(Filter19->GetOutput());
     Filter20->Update();  //Initiate processing of all filters
     itk::Image::Pointer OutputImage<>=Filter20->GetOutput();
     myfio->Update(); //This is OK Write out the buffer image that was 
created as part of the Filter19 exection;

     IntermediateImage=Filter20->GetOutput();//Reference count to 
Filter19 internal output buffer is decremented by one, and reference 
count to internal Filter29 output buffer is incremented by one.
     }//All memory and internal buffers from filters 1-19 are deleted. 
The interal output buffer of Filter20 will persist because it is still 
referenced by IntermediateImage.

   myfio->Update(); //Write out the buffer image that was created as 
part of the Filter20 execution.
   }

myfio->Update(); //OK
===========================================================

When does IntermediateImage become usable?
Does filter 20 interally make a call analogus to 
Filter19->GetOutput()->Update()?

I just don't have a good understanding of how this works.

Thanks,
Hans

PS:  Thanks Luis and James for your quick and helpful responses!

Luis Ibanez wrote:
> 
> Hi Hans,
> 
> About your second set of examples:
> 
> All of them are missing the SmartPointers.
> 
> Is this intentional in the code you want to
> illustrate or is it just an omission ?
> 
> For example, and STL list of <itk::Image<>>
> will not work. You could only use raw pointers
> to images or smart pointers to images.
> 
> Default constructors have been declared protected
> in order to prevent images from being declared as
> static variables.
> 
> The same goes for filters.
> 
> 
> Luis
> 
> 
> -------------------------
> Hans Johnson wrote:
> 
>> Luis,
> 
> 
> 
>> ...
>>
>> 2) A common pitfalls appendix with examples
>>      -) All of the images in MyNewImagesList will have a smart pointer 
>> to the same image.
>>
>>         std::list<itk::Image<>::Pointer> MyImagesList;
>>         std::list<itk::Image<>::Pointer> MyNewImagesList;
>>         itk::FilterX::Pointer X=itk::FilterX::New()
>>         for( currImage in MyImagesList )
>>         {
>>             X->SetInput(currImage);
>>             X->Update();
>>             MyNewImagesList.push_back(X->GetOutput);
>>          }
>>
>>       -) This will cause errors because MyNewImage was never allocated.
>>
>>         itk::Image<>::Pointer MyImage;
>>         itk::Image<>::Pointer MyNewImage;
>>         {
>>            itk::FilterX::Pointer X=itk::FilterX::New()
>>            X->SetInput(MyImage);
>>            //NOTE: No UpdateCommand
>>            MyNewImage=X->GetOutput();
>>          }
>>          itk::FilterY::Pointer Y=itk::FilterY::New();
>>          Y->SetInput(MyNewImage);
>>          Y->Update();
>>
>>
>> Both of these issues are closely related to not fully understanding 
>> the pipeline, and making improper assumptions about it's behavior.
>>
>> Again, Thanks for all your help.
>>
>> Hans
>>
>>
>>
>>

-- 
===================================================================
Hans J. Johnson                              W294 GH
hans-johnson@uiowa.edu                       Dept. of Psychiatry
http://www.psychiatry.uiowa.edu/~hjohnson    The University of Iowa
(319) 353-8587                               Iowa City, IA 52242
===================================================================