diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 425714313d6b8bb066f3421c749487b3c6d22448..4b32d3d539e217a4c1865527a6ebed7fb9eda0ed 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -15,3 +15,11 @@ OTB_CREATE_APPLICATION(NAME SingleTileGRMGraph OTB_CREATE_APPLICATION(NAME AssembleGRMGraphs SOURCES otbAssembleGRMGraphs.cxx LINK_LIBRARIES ${${otb-module}_LIBRARIES} OTBGRM) + +OTB_CREATE_APPLICATION(NAME ConnectedComponentLabeling + SOURCES otbConnectedComponentLabeling.cxx + LINK_LIBRARIES ${${otb-module}_LIBRARIES}) + +OTB_CREATE_APPLICATION(NAME FillSegmentationHoles + SOURCES otbFillSegmentationHoles.cxx + LINK_LIBRARIES ${${otb-module}_LIBRARIES}) diff --git a/app/otbConnectedComponentLabeling.cxx b/app/otbConnectedComponentLabeling.cxx new file mode 100644 index 0000000000000000000000000000000000000000..01796036bd07eb95f92275c880e2ac51cf6ee05b --- /dev/null +++ b/app/otbConnectedComponentLabeling.cxx @@ -0,0 +1,91 @@ +/* + * Author: Raffaele GAETANO + * + * Affiliation: CIRAD, UMR TETIS + */ + +#include "otbWrapperApplication.h" +#include "otbWrapperApplicationFactory.h" + +#include "itkConnectedComponentImageFilter.h" +#include "otbOGRFeatureWrapper.h" + +namespace otb +{ +namespace Wrapper +{ +class ConnectedComponentLabeling : public Application +{ +public: + typedef ConnectedComponentLabeling Self; + typedef Application Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + typedef UInt32ImageType LabelImageType; + + typedef itk::ConnectedComponentImageFilter<LabelImageType, LabelImageType> CCLFIlterType; + + itkNewMacro(Self); + + itkTypeMacro(ConnectedComponent, otb::Application); + +private: + void DoInit() override + { + SetName("ConnectedComponentLabeling"); + SetDescription("This application performs ..."); + + SetDocLongDescription( + "..." + "..."); + SetDocLimitations("This application is proposed as part of the LSGRM Remote Module from Remi Cresson / Pierre Lassalle."); + SetDocAuthors("Raffaele Gaetano"); + + AddDocTag(Tags::Segmentation); + AddDocTag("LSGRM"); + + AddParameter(ParameterType_InputImage, "in", "Input binary image"); + SetParameterDescription("in", "The input binary image containing objects."); + + //AddParameter(ParameterType_InputImage, "mask", "Input mask"); + //SetParameterDescription("mask", + // "Optional mask to indicate which pixels are valid for vectorization."); + //MandatoryOff("mask"); + //DisableParameter("mask"); + + //AddParameter(ParameterType_Int, "bv", "Background Value"); + //SetParameterDescription("bv", "Value corresponding to no-object."); + //SetDefaultParameterInt("bv", 0); + + AddParameter(ParameterType_OutputImage, "out", "Output label image"); + SetParameterDescription("out", + "The output label image."); + + AddRAMParameter(); + + // Doc example parameter settings + SetDocExampleParameterValue("in", "binary.tif"); + SetDocExampleParameterValue("out", "labelled.tif"); + + } + + void DoUpdateParameters() override + { + } + + void DoExecute() override + { + + LabelImageType::Pointer labelIn = GetParameterUInt32Image("in"); + m_CCLFilterType = CCLFIlterType::New(); + m_CCLFilterType->SetInput(labelIn); + SetParameterOutputImage("out", m_CCLFilterType->GetOutput()); + + } + CCLFIlterType::Pointer m_CCLFilterType; +}; +} +} + +OTB_APPLICATION_EXPORT(otb::Wrapper::ConnectedComponentLabeling) diff --git a/app/otbFillSegmentationHoles.cxx b/app/otbFillSegmentationHoles.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e660527ddf1447a4c4ca94bd0c7f2e0e8595050a --- /dev/null +++ b/app/otbFillSegmentationHoles.cxx @@ -0,0 +1,120 @@ +/* + * Author: Raffaele GAETANO + * + * Affiliation: CIRAD, UMR TETIS + */ + +#include "otbWrapperApplication.h" +#include "otbWrapperApplicationFactory.h" + +#include "otbStreamingStatisticsImageFilter.h" +#include "itkConnectedComponentImageFilter.h" +#include "otbBandMathImageFilter.h" + +#include <string> + +namespace otb +{ +namespace Wrapper +{ +class FillSegmentationHoles : public Application +{ +public: + typedef FillSegmentationHoles Self; + typedef Application Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + typedef UInt32ImageType LabelImageType; + + typedef itk::ConnectedComponentImageFilter<LabelImageType, LabelImageType> CCLFIlterType; + typedef otb::BandMathImageFilter<LabelImageType> BandMathFilterType; + typedef otb::StreamingStatisticsImageFilter<LabelImageType> StatsFilterType; + + itkNewMacro(Self); + + itkTypeMacro(Segmentation, otb::Application); + +private: + void DoInit() override + { + SetName("FillSegmentationHoles"); + SetDescription("This application performs ..."); + + SetDocLongDescription( + "..." + "..."); + SetDocLimitations("This application is proposed as part of the LSGRM Remote Module from Remi Cresson / Pierre Lassalle."); + SetDocAuthors("Raffaele Gaetano"); + + AddDocTag(Tags::Segmentation); + AddDocTag("LSGRM"); + + AddParameter(ParameterType_InputImage, "in", "Input segmentation"); + SetParameterDescription("in", "The input segmentation label image."); + + AddParameter(ParameterType_InputImage, "mask", "Input validity mask"); + SetParameterDescription("mask", + "Optional mask to indicate which pixels are valid (any non-zero value)."); + MandatoryOff("mask"); + DisableParameter("mask"); + + AddParameter(ParameterType_OutputImage, "out", "Output segmentation"); + SetParameterDescription("out", + "The output segmentation with filled holes."); + + AddRAMParameter(); + + // Doc example parameter settings + SetDocExampleParameterValue("in", "seg.tif"); + SetDocExampleParameterValue("out", "seg_filled.tif"); + + } + + void DoUpdateParameters() override + { + } + + void DoExecute() override + { + + LabelImageType::Pointer labelIn = GetParameterUInt32Image("in"); + + m_StatsFilter = StatsFilterType::New(); + m_StatsFilter->SetInput(labelIn); + m_StatsFilter->Update(); + long unsigned M = m_StatsFilter->GetMaximum(); + std::cout << "Hole numbering starts at : " << 1 + M << std::endl; + + m_BandMathFilter = BandMathFilterType::New(); + m_BandMathFilter->SetNthInput(0, labelIn); + if (HasValue("mask")) { + LabelImageType::Pointer maskIn = GetParameterUInt32Image("mask"); + m_BandMathFilter->SetNthInput(1, maskIn); + m_BandMathFilter->SetExpression("b1==0 && b2!=0"); + } + else { + m_BandMathFilter->SetExpression("b1==0"); + } + + m_CCLFilter = CCLFIlterType::New(); + m_CCLFilter->SetInput(m_BandMathFilter->GetOutput()); + + m_OutBandMathFilter = BandMathFilterType::New(); + m_OutBandMathFilter->SetNthInput(0, labelIn); + m_OutBandMathFilter->SetNthInput(1, m_CCLFilter->GetOutput()); + std::string expr = "b1==0 ? " + std::to_string(M) + " + b2 : b1"; + m_OutBandMathFilter->SetExpression(expr); + SetParameterOutputImage("out", m_OutBandMathFilter->GetOutput()); + + } + + CCLFIlterType::Pointer m_CCLFilter; + BandMathFilterType::Pointer m_BandMathFilter; + StatsFilterType::Pointer m_StatsFilter; + BandMathFilterType::Pointer m_OutBandMathFilter; +}; +} +} + +OTB_APPLICATION_EXPORT(otb::Wrapper::FillSegmentationHoles) diff --git a/otb-module.cmake b/otb-module.cmake index b399ffe0b9fcfc28dbf5b49816830caa3153321d..71f6fb73082237fc4628784f1115d608cde934bb 100644 --- a/otb-module.cmake +++ b/otb-module.cmake @@ -6,6 +6,8 @@ otb_module(LSGRM OTBCommon OTBApplicationEngine OTBConversion + OTBMathParser + OTBStatistics OPTIONAL_DEPENDS OTBMPI TEST_DEPENDS