Refactor PanSharpening module to use FunctorImageFilter everywhere
Summary
This MR refactors PanSharpening
module to use FunctorImageFilter
.
Rationale
Avoids relying on TernaryFunctorImageFilter
(either itk version or our own version).
Gain performances by using the void operator()(Tout& out, ...)
form.
Implementation Details
Appart from the removal of otb::ImageFusionBase
which was a base class used only by BayesianFusionImageFilter
, all modifications are internal to filters and do not change the API.
A small refactoring has been done PanSharpening application to avoid a compilation error (trying to convert the BayesianFusionImageFilter
to the wrong instance of ImageToImageFilter
). Maybe we could use the new RegisterPipeline()
method here.
Copyright
The copyright owner is CNES and has signed the ORFEO ToolBox Contributor License Agreement.
Check before merging:
- All discussions are resolved
- At least 2
votes from core developers, no vote. - The feature branch is (reasonably) up-to-date with the base branch
- Dashboard is green
- Copyright owner has signed the ORFEO ToolBox Contributor License Agreement
Merge request reports
Activity
added refactoring label
@aregimbeau can you explain how to do it? I am not sure I can get it right.
Sure!
Old app snippet :void DoExecute() { my_filter1 = FilterType1::New(); SettingUpFilter1(my_filter1); m_Filters.push_back(my_filter1.GetPointer()); my_filter2 = FilterType2::New(); SettingUpFilter2(my_filter2); my_filter2->SetInput(my_filter1->GetOutput()); m_Filters.push_back(my_filter2.GetPointer()); my_filter3 = FilterType3::New(); SettingUpFilter3(my_filter2); my_filter3->SetInput(my_filter2->GetOutput()); SetParameterOutputImage("out", my_filter3->GetOutput() ); m_Filters.push_back(my_filter3.GetPointer()); } std::vector<ProcessObject*> m_Filters
So here you have a pipeline filter1->filter2->filter3. And the output of the filter3 is hold by the output parameter. Calling the
RegisterPipeline()
at the end of theDoExecute()
will register the different filters that belong to the pipeline (walk from DataObjects to their sources).New app snippet :
void DoExecute() { my_filter1 = FilterType1::New(); SettingUpFilter1(my_filter1); my_filter2 = FilterType2::New(); SettingUpFilter1(my_filter2); my_filter2->SetInput(my_filter1->GetOutput()); my_filter3 = FilterType3::New(); SettingUpFilter1(my_filter3); my_filter3->SetInput(my_filter2->GetOutput()); SetParameterOutputImage("out", my_filter3->GetOutput() ); RegisterPipeline(); }
What you need to be careful of, is that your whole pipeline is alive at the end of the function. If it is then it will be registered. An example that is not straightforward to refactor is :
void DoExecute() { my_filter1 = FilterType1::New(); SettingUpFilter1(my_filter1); m_Filters.push_back(my_filter1.GetPointer()); SetFilter2(); my_filter3 = FilterType3::New(); SettingUpFilter3(my_filter2); my_filter3->SetInput(my_filter2->GetOutput()); SetParameterOutputImage("out", my_filter3->GetOutput() ); m_Filters.push_back(my_filter3.GetPointer()); } void SetFilter2() { my_filter2 = FilterType2::New(); SettingUpFilter2(my_filter2); my_filter2->SetInput(m_Filters[0]->GetOutput()); m_Filters.push_back(my_filter2.GetPointer()); } std::vector<ProcessObject*> m_Filters
Here your pipeline is only alive thanks to the vector
m_Filters
. Without it the instance offilter2
,my_filter2
will be destroyed at the end of theSetFilter2()
function. So you must refactor the architecture to be able to use theRegisterPipeline()
added 1 commit
- c1cfefdf - COMP: Fix compilation error (missing <array> include)
mentioned in commit 4a2073fd
changed milestone to %7.0.0