[Insight-users] Combining CompositeFilterExample and
CannyEdgeDetectionImageFilter
Dan Mueller
d.mueller at qut.edu.au
Sun Jul 2 20:19:04 EDT 2006
Hi Sholomo,
Here are my attempted answers to your questions:
1. Why divide the pipeline setup and execution between the constructor
and GenerateData(.) method? The main reason stems from the usage of the
pipeline: when a filter parameter is modified, the GenerateData(.)
methods for all upstream filters are re-executed to update the pipeline
result. If the code setting up the pipeline is included in the
GenerateData(.) method, it will be unnecessarily executed again when a
filter is updated. *Simple answer*=save unnecessary computation.
2. Why is GraftOutput(.) called on both the last filter in the pipeline
and the composite filter itself? I am not an expert regarding the
subject matter of this question; but I'll have a go. From inspecting the
code, the GraftOutput(.) method basically copies/overwrites the
PixelContainer pointer for an Image (see Image::Graft(.) method). The
first call ensures that the output of last filter in the composite
filter is set as the total output of the composite filter. The second
call ensures that the total output of the composite filter is set as the
output of the last filter in the composite filter. Basically this
results in the output Image of the composite filter pointing to the
PixelContainer of the last filter in the composite pipeline. *Simple
answer*=to ensure the output of the composite filter (ie. an Image) has
a pointer to the PixelContainer from the last filter in the mini-pipeline.
3. Are the GetInput(.) and GetOutput(.) methods the same inside or
outside a composite filter? Nearly, but not quite. At the ProcessObject
level the GetInput(.) and GetOutput(.) methods are similar - they both
return a pointer to a DataObject. However, most (all?) composite filters
will inherit from ImageSource which overrides GetOutput(.) to return an
OutputImageType pointer. Of course OutputImageType * is really Image<.>
* which is really DataObject *, so these representations are related
through inheritance. Ultimately, what you need to be aware of is (1) the
output of a ProcessObject is 1 or more DataObjects, and (2) the inputs
of a ProcessObject are DataObjects, and an Image is a subclass of
DataObject. *(sort of ) simple answer*=GetInput(.) and GetOutput(.) are
ways to obtain the DataObjects given to and resultant from ITK filters
(ie. ProcessObjects).
I hope this answered your questions adequately and accurately (any other
help or corrections?).
Cheers
Dan
Shlomo Kashani. wrote:
> Hi,
>
> I am writing a composite filter based amongst others on the
> CompositeFilterExample, the CannyEdgeDetectionImageFilter.cxx (which
> is based On 3 other filters) and several more filters which I havent
> written yet. I sucessfuly used the example CompositeFilterExample to
> convert CannyEdgeDetectionImageFilter to a composite
> filter in which the sequential filtering operation is done in the
> GenerateData() methood. Even though the filtering operation works
> well, I have a problem understanding the pipeline operation in the
> CompositeFilterExample class. The constructor sets up a pipeline as
> follows:
>
> template <class TImageType>
> CompositeIrisRecognitionFilter<TImageType>
> ::CompositeIrisRecognitionFilter()
> {
> m_CastToRealFilter = CastToRealFilter::New();
> m_CannyFilter = CannyFilter::New();
> m_RescaleFilter = RescaleFilter::New();
>
> // Set up the pipeline, this is MY code based exactly on
> CompositeFilterExample
> m_CannyFilter->SetInput( m_CastToRealFilter->GetOutput() );
> // Set the variance for the Gaussian smoothing filter
> m_CannyFilter->SetVariance(m_GaussianVariance);
> m_RescaleFilter->SetInput( m_CannyFilter->GetOutput() );
>
> // Default variance for the canny edge detector, tested on
> // the UPOL iris image database
> m_GaussianVariance=50.0;
> }
>
> And the GenerateData() methood executes the pipeline as folows:
>
> template <class TImageType>
> void
> CompositeIrisRecognitionFilter<TImageType>::
> GenerateData()
> {
> // The output of an edge filter is 0 or 1
> m_RescaleFilter->SetOutputMinimum( 0 );
> m_RescaleFilter->SetOutputMaximum( 255 );
>
> // Run the pipeline
> m_CastToRealFilter->SetInput( this->GetInput() );
> m_RescaleFilter->GraftOutput( this->GetOutput() );
> m_RescaleFilter->Update();
> this->GraftOutput( m_RescaleFilter->GetOutput() );
>
> }
>
> My questions are:
> 1-why are the pipeline set up and pipeline executions placed in two
> different methods? I placed both in the GenerateData methood And as
> expected it was still working. Is there an architectual advantage to
> the seperation of operations? I think it adds confusion and breaks
> the logic sequential order of operations
> 2-How does GraftOutput work exactly, why do I have to use it twice in
> this case?
> 3-is the invocation of the methood this->GetInput() equivalent to
> reader->GetOutput() in a non Composite filter (e.g one that does
> everything in the main methhod)?
>
> Thank you very much for your help,
>
> Shlomo.
>
> ------------------------------------------------------------------------
> Do you Yahoo!?
> Get on board. You're invited
> <http://us.rd.yahoo.com/evt=40791/*http://advision.webevents.yahoo.com/handraisers>
> to try the new Yahoo! Mail Beta.
> ------------------------------------------------------------------------
>
> _______________________________________________
> 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