Skip to content
Snippets Groups Projects

Refactor PanSharpening module to use FunctorImageFilter everywhere

Merged Julien Michel requested to merge refactor_pansharpening_with_FunctorImageFilter into develop

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 :thumbsup: votes from core developers, no :thumbsdown: 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

Approval is optional
Ready to merge by members who can write to the target branch.

Merge details

  • 1 commit and 1 merge commit will be added to develop.
  • Source branch will be deleted.

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
  • I agree for the use of RegisterPipeline() in this application.

  • @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 the DoExecute() 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 of filter2, my_filter2 will be destroyed at the end of the SetFilter2() function. So you must refactor the architecture to be able to use the RegisterPipeline()

  • Julien Michel added 1 commit

    added 1 commit

    • c1cfefdf - COMP: Fix compilation error (missing <array> include)

    Compare with previous version

  • Green, merging.

  • merged

  • Julien Michel mentioned in commit 4a2073fd

    mentioned in commit 4a2073fd

  • Cédric Traizet changed milestone to %7.0.0

    changed milestone to %7.0.0

Please register or sign in to reply
Loading