[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
===================================================================