diff --git a/Applications/Segmentation/otbSegmentation.cxx b/Applications/Segmentation/otbSegmentation.cxx index ed914a1e9607341fd01ca4585d11437420a8c449..b44b191d81e11fdb561ee632b6a485f27c376706 100644 --- a/Applications/Segmentation/otbSegmentation.cxx +++ b/Applications/Segmentation/otbSegmentation.cxx @@ -128,24 +128,24 @@ private: void DoInit() { SetName("Segmentation"); - SetDescription("Performs segmentation of an image, with an optional large scale mode to handle large images."); + SetDescription("Performs segmentation of an image, and output either a raster or a vector file. In vector mode, large input datasets are supported."); // Documentation SetDocName("Segmentation"); SetDocLongDescription("This application allows to perform various segmentation algorithm on an multispectral image. " - "Available segmentation algorithms are two different version of Mean-Shift segmentation algorithm (one beeing multi-threaded)," + "Available segmentation algorithms are two different version of Mean-Shift segmentation algorithm (one being multi-threaded)," " simple pixel based connected components according to a user-defined criterion, and watershed from the gradient of the intensity " - "(norm of spectral bands vector). The application has two different modes that affects the nature of its output.\n\nIn normal mode," + "(norm of spectral bands vector). The application has two different modes that affects the nature of its output.\n\nIn raster mode," " the output of the application is a classical image of unique labels identifying the segmented regions. The labeled output can be passed to the " - " ColorMapping application to render regions with contrasted colors. Please note that this mode loads the whole input image into memory, and as such " - " can not handle large images. \n\nTo segment large data, one can use the largescale mode. In this case, the output of the application is a " - " vector file or database. The input image is splitted into tiles (whose size can be set using the tilesize parameter), and each tile is loaded, segmented " - " with the chosen algorithm, vectorized, and writen into the output file or database. This piece-wise behaviour ensure that memory will never get overloaded, " - " and that images of any size can be processed. There are few more options in the largescale mode. The simplify option allows to simplify the geometry " + " ColorMapping application to render regions with contrasted colours. Please note that this mode loads the whole input image into memory, and as such " + " can not handle large images. \n\nTo segment large data, one can use the vector mode. In this case, the output of the application is a " + " vector file or database. The input image is split into tiles (whose size can be set using the tilesize parameter), and each tile is loaded, segmented " + " with the chosen algorithm, vectorized, and written into the output file or database. This piece-wise behaviour ensure that memory will never get overloaded, " + " and that images of any size can be processed. There are few more options in the vector mode. The simplify option allows to simplify the geometry " " (i.e. remove nodes in polygons) according to a user-defined tolerance. The stitch option allows to application to try to stitch together polygons corresponding " " to segmented region that may have been splitted by the tiling scheme. "); - SetDocLimitations("In normal mode, the application can not handle large input images. Stiching step of largescale mode might become slow with very large input images."); + SetDocLimitations("In raster mode, the application can not handle large input images. Stitching step of vector mode might become slow with very large input images."); SetDocAuthors("OTB-Team"); SetDocSeeAlso("MeanShiftSegmentation"); @@ -224,83 +224,83 @@ private: SetMaximumParameterFloatValue("filter.watershed.level",1); AddParameter(ParameterType_Choice, "mode", "Processing mode"); - SetParameterDescription("mode", "Choice of processing mode, either normal or large-scale."); + SetParameterDescription("mode", "Choice of processing mode, either raster or large-scale."); - AddChoice("mode.largescale", "Tile-based large-scale segmentation with vector output"); - SetParameterDescription("mode.largescale","In this mode, the application will output a vector file or database, and process the input image piecewise. This allows to perform segmentation of very large images."); + AddChoice("mode.vector", "Tile-based large-scale segmentation with vector output"); + SetParameterDescription("mode.vector","In this mode, the application will output a vector file or database, and process the input image piecewise. This allows to perform segmentation of very large images."); - AddChoice("mode.normal", "Standard segmentation with labeled raster output"); - SetParameterDescription("mode.normal","In this mode, the application will output a standard labeled raster. This mode can not handle large data."); + AddChoice("mode.raster", "Standard segmentation with labeled raster output"); + SetParameterDescription("mode.raster","In this mode, the application will output a standard labeled raster. This mode can not handle large data."); - //Normal mode parameters - AddParameter(ParameterType_OutputImage, "mode.normal.lout", "Output labeled image"); - SetParameterDescription( "mode.normal.lout", "The output labeled image."); + //Raster mode parameters + AddParameter(ParameterType_OutputImage, "mode.raster.out", "Output labeled image"); + SetParameterDescription( "mode.raster.out", "The output labeled image."); //Streaming vectorization parameters - AddParameter(ParameterType_OutputFilename, "mode.largescale.outvd", "Output vector file"); - SetParameterDescription("mode.largescale.outvd", "The output vector file or database (name can be anything understood by OGR)"); + AddParameter(ParameterType_OutputFilename, "mode.vector.out", "Output vector file"); + SetParameterDescription("mode.vector.out", "The output vector file or database (name can be anything understood by OGR)"); - AddParameter(ParameterType_InputImage, "mode.largescale.inmask", "Mask Image"); - SetParameterDescription("mode.largescale.inmask", "Only pixels whose mask value is strictly positive will be segmented."); - MandatoryOff("mode.largescale.inmask"); + AddParameter(ParameterType_InputImage, "mode.vector.inmask", "Mask Image"); + SetParameterDescription("mode.vector.inmask", "Only pixels whose mask value is strictly positive will be segmented."); + MandatoryOff("mode.vector.inmask"); - AddParameter(ParameterType_Empty, "mode.largescale.neighbor", "8-neighbor connectivity"); - SetParameterDescription("mode.largescale.neighbor", + AddParameter(ParameterType_Empty, "mode.vector.neighbor", "8-neighbor connectivity"); + SetParameterDescription("mode.vector.neighbor", "Activate 8-Neighbourhood connectivity (default is 4)."); - MandatoryOff("mode.largescale.neighbor"); - EnableParameter("mode.largescale.neighbor"); + MandatoryOff("mode.vector.neighbor"); + EnableParameter("mode.vector.neighbor"); - AddParameter(ParameterType_Empty,"mode.largescale.stitch","Stitch polygons"); - SetParameterDescription("mode.largescale.stitch", "Scan polygons on each side of tiles and stitch polygons which connect by more than one pixel."); - MandatoryOff("mode.largescale.stitch"); - EnableParameter("mode.largescale.stitch"); + AddParameter(ParameterType_Empty,"mode.vector.stitch","Stitch polygons"); + SetParameterDescription("mode.vector.stitch", "Scan polygons on each side of tiles and stitch polygons which connect by more than one pixel."); + MandatoryOff("mode.vector.stitch"); + EnableParameter("mode.vector.stitch"); - AddParameter(ParameterType_Int, "mode.largescale.minsize", "Minimum object size"); - SetParameterDescription("mode.largescale.minsize", + AddParameter(ParameterType_Int, "mode.vector.minsize", "Minimum object size"); + SetParameterDescription("mode.vector.minsize", "Objects whose size is below the minimum object size (area in pixels) will be ignored during vectorization."); - SetDefaultParameterInt("mode.largescale.minsize", 1); - SetMinimumParameterIntValue("mode.largescale.minsize", 1); - MandatoryOff("mode.largescale.minsize"); - DisableParameter("mode.largescale.minsize"); + SetDefaultParameterInt("mode.vector.minsize", 1); + SetMinimumParameterIntValue("mode.vector.minsize", 1); + MandatoryOff("mode.vector.minsize"); + DisableParameter("mode.vector.minsize"); - AddParameter(ParameterType_Float, "mode.largescale.simplify", "Simplify polygons"); - SetParameterDescription("mode.largescale.simplify", + AddParameter(ParameterType_Float, "mode.vector.simplify", "Simplify polygons"); + SetParameterDescription("mode.vector.simplify", "Simplify polygons according to a given tolerance (in pixel). This option allows to reduce the size of the output file or database."); - SetDefaultParameterFloat("mode.largescale.simplify",0.1); - MandatoryOff("mode.largescale.simplify"); + SetDefaultParameterFloat("mode.vector.simplify",0.1); + MandatoryOff("mode.vector.simplify"); - AddParameter(ParameterType_String, "mode.largescale.layername", "Layer name"); - SetParameterDescription("mode.largescale.layername", "Name of the layer in the vector file or database (default is Layer)."); - SetParameterString("mode.largescale.layername", "layer"); + AddParameter(ParameterType_String, "mode.vector.layername", "Layer name"); + SetParameterDescription("mode.vector.layername", "Name of the layer in the vector file or database (default is Layer)."); + SetParameterString("mode.vector.layername", "layer"); - AddParameter(ParameterType_String, "mode.largescale.fieldname", "Geometry index field name"); - SetParameterDescription("mode.largescale.fieldname", "Name of the field holding the geometry index in the output vector file or database."); - SetParameterString("mode.largescale.fieldname", "DN"); + AddParameter(ParameterType_String, "mode.vector.fieldname", "Geometry index field name"); + SetParameterDescription("mode.vector.fieldname", "Name of the field holding the geometry index in the output vector file or database."); + SetParameterString("mode.vector.fieldname", "DN"); - AddParameter(ParameterType_Int, "mode.largescale.tilesize", "Tiles size"); - SetParameterDescription("mode.largescale.tilesize", + AddParameter(ParameterType_Int, "mode.vector.tilesize", "Tiles size"); + SetParameterDescription("mode.vector.tilesize", "User defined tiles size for tile-based segmentation. Optimal tile size is selected according to available RAM if null."); - SetDefaultParameterInt("mode.largescale.tilesize",1024); - SetMinimumParameterIntValue("mode.largescale.tilesize",0); + SetDefaultParameterInt("mode.vector.tilesize",1024); + SetMinimumParameterIntValue("mode.vector.tilesize",0); - AddParameter(ParameterType_Int, "mode.largescale.startlabel", "Starting geometry index"); - SetParameterDescription("mode.largescale.startlabel", "Starting value of the geometry index field"); - SetDefaultParameterInt("mode.largescale.startlabel", 1); - SetMinimumParameterIntValue("mode.largescale.startlabel", 1); + AddParameter(ParameterType_Int, "mode.vector.startlabel", "Starting geometry index"); + SetParameterDescription("mode.vector.startlabel", "Starting value of the geometry index field"); + SetDefaultParameterInt("mode.vector.startlabel", 1); + SetMinimumParameterIntValue("mode.vector.startlabel", 1); // Doc example parameter settings SetExampleComment("Example of use with vector mode and watershed segmentation",0); SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_PAN.tif"); - SetDocExampleParameterValue("mode","largescale"); - SetDocExampleParameterValue("mode.largescale.outvd", "SegmentationVectorData.sqlite"); + SetDocExampleParameterValue("mode","vector"); + SetDocExampleParameterValue("mode.vector.out", "SegmentationVector.sqlite"); SetDocExampleParameterValue("filter", "watershed"); AddExample("Example of use with raster mode and mean-shift segmentation"); SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_PAN.tif",1); - SetDocExampleParameterValue("mode","normal",1); - SetDocExampleParameterValue("mode.normal.lout", "SegmentationVectorData.tif uint16",1); + SetDocExampleParameterValue("mode","raster",1); + SetDocExampleParameterValue("mode.raster.out", "SegmentationRaster.tif uint16",1); SetDocExampleParameterValue("filter", "meanshift",1); } @@ -321,20 +321,20 @@ private: SegmentationFilterType> StreamingVectorizedSegmentationOGRType; // Retrieve tile size parameter - const unsigned int tileSize = static_cast<unsigned int> (this->GetParameterInt("mode.largescale.tilesize")); + const unsigned int tileSize = static_cast<unsigned int> (this->GetParameterInt("mode.vector.tilesize")); // Retrieve the 8-connected option - bool use8connected = IsParameterEnabled("mode.largescale.neighbor"); + bool use8connected = IsParameterEnabled("mode.vector.neighbor"); // Retrieve min object size parameter - const unsigned int minSize = static_cast<unsigned int> (this->GetParameterInt("mode.largescale.minsize")); + const unsigned int minSize = static_cast<unsigned int> (this->GetParameterInt("mode.vector.minsize")); // Switch on segmentation mode const std::string segModeType = (dynamic_cast <ChoiceParameter *> (this->GetParameterByKey("mode")))->GetChoiceKey(GetParameterInt("mode")); streamingVectorizedFilter->SetInput(inputImage); - if (HasValue("mode.largescale.inmask")) + if (HasValue("mode.vector.inmask")) { - streamingVectorizedFilter->SetInputMask(this->GetParameterUInt32Image("mode.largescale.inmask")); + streamingVectorizedFilter->SetInputMask(this->GetParameterUInt32Image("mode.vector.inmask")); otbAppLogINFO(<<"Use a mask as input." << std::endl); } streamingVectorizedFilter->SetOGRDataSource(ogrDS); @@ -361,20 +361,20 @@ private: streamingVectorizedFilter->SetMinimumObjectSize(minSize); } - const std::string layerName = this->GetParameterString("mode.largescale.layername"); - const std::string fieldName = this->GetParameterString("mode.largescale.fieldname"); + const std::string layerName = this->GetParameterString("mode.vector.layername"); + const std::string fieldName = this->GetParameterString("mode.vector.fieldname"); // Retrieve start label parameter - const unsigned int startLabel = this->GetParameterInt("mode.largescale.startlabel"); + const unsigned int startLabel = this->GetParameterInt("mode.vector.startlabel"); streamingVectorizedFilter->SetLayerName(layerName); streamingVectorizedFilter->SetFieldName(fieldName); streamingVectorizedFilter->SetStartLabel(startLabel); - if(IsParameterEnabled("mode.largescale.simplify")) + if(IsParameterEnabled("mode.vector.simplify")) { streamingVectorizedFilter->SetSimplify(true); - streamingVectorizedFilter->SetSimplificationTolerance(GetParameterFloat("mode.largescale.simplify")); + streamingVectorizedFilter->SetSimplificationTolerance(GetParameterFloat("mode.vector.simplify")); otbAppLogINFO(<<"Simplify the geometry." << std::endl); } else @@ -382,7 +382,7 @@ private: streamingVectorizedFilter->SetSimplify(false); } - if (segModeType == "largescale") + if (segModeType == "vector") { otbAppLogINFO(<<"Large scale segmentation mode which output vector data" << std::endl); AddProcess(streamingVectorizedFilter->GetStreamer(), "Computing " + (dynamic_cast <ChoiceParameter *> (this->GetParameterByKey("filter")))->GetChoiceKey(GetParameterInt("filter")) + " segmentation"); @@ -390,14 +390,14 @@ private: streamingVectorizedFilter->Initialize(); //must be called ! streamingVectorizedFilter->Update(); //must be called ! } - else if (segModeType == "normal") + else if (segModeType == "raster") { otbAppLogINFO(<<"Segmentation mode which output label image" << std::endl); streamingVectorizedFilter->GetSegmentationFilter()->SetInput(inputImage); - SetParameterOutputImage<UInt32ImageType> ("mode.normal.lout", dynamic_cast<UInt32ImageType *> (streamingVectorizedFilter->GetSegmentationFilter()->GetOutputs().at(outputNb).GetPointer())); - //TODO add progress reporting in normal mode - // AddProcess(dynamic_cast <OutputImageParameter *> (GetParameterByKey("mode.normal.lout"))->GetWriter(), + SetParameterOutputImage<UInt32ImageType> ("mode.raster.out", dynamic_cast<UInt32ImageType *> (streamingVectorizedFilter->GetSegmentationFilter()->GetOutputs().at(outputNb).GetPointer())); + //TODO add progress reporting in raster mode + // AddProcess(dynamic_cast <OutputImageParameter *> (GetParameterByKey("mode.raster.out"))->GetWriter(), // "Computing " + (dynamic_cast <ChoiceParameter *> // (this->GetParameterByKey("filter")))->GetChoiceKey(GetParameterInt("filter")) // + " segmentation"); @@ -415,10 +415,10 @@ private: otb::ogr::DataSource::Pointer ogrDS; - if(segModeType=="largescale") + if(segModeType=="vector") { // Retrieve output filename as well as layer names - std::string dataSourceName = GetParameterString("mode.largescale.outvd"); + std::string dataSourceName = GetParameterString("mode.vector.out"); ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::write); } @@ -431,9 +431,9 @@ private: ConnectedComponentStreamingVectorizedSegmentationOGRType::Pointer ccVectorizationFilter = ConnectedComponentStreamingVectorizedSegmentationOGRType::New(); - if (HasValue("mode.largescale.inmask")) + if (HasValue("mode.vector.inmask")) { - ccVectorizationFilter->GetSegmentationFilter()->SetMaskImage(this->GetParameterUInt32Image("mode.largescale.inmask")); + ccVectorizationFilter->GetSegmentationFilter()->SetMaskImage(this->GetParameterUInt32Image("mode.vector.inmask")); } ccVectorizationFilter->GetSegmentationFilter()->GetFunctor().SetExpression( @@ -513,15 +513,15 @@ private: otbAppLogFATAL(<<"non defined filtering method "<<GetParameterInt("filter")<<std::endl); } - if (segModeType == "largescale" ) + if (segModeType == "vector" ) { ogrDS->SyncToDisk(); // Stitching mode - if(IsParameterEnabled("mode.largescale.stitch")) + if(IsParameterEnabled("mode.vector.stitch")) { otbAppLogINFO(<<"Segmentation done, stiching polygons ..."); - const std::string layerName = this->GetParameterString("mode.largescale.layername"); + const std::string layerName = this->GetParameterString("mode.vector.layername"); FusionFilterType::Pointer fusionFilter = FusionFilterType::New(); fusionFilter->SetInput(GetParameterFloatVectorImage("in")); @@ -533,7 +533,7 @@ private: fusionFilter->GenerateData(); } } - else if (segModeType == "normal") + else if (segModeType == "raster") { otbAppLogINFO(<<"implementation in progress..." << std::endl); }