Skip to content
Snippets Groups Projects
Commit e69a38da authored by Julien Michel's avatar Julien Michel
Browse files

ENH: Rationalising parameters and adding examples

parent eb110a86
Branches
Tags
No related merge requests found
...@@ -128,24 +128,24 @@ private: ...@@ -128,24 +128,24 @@ private:
void DoInit() void DoInit()
{ {
SetName("Segmentation"); 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 // Documentation
SetDocName("Segmentation"); SetDocName("Segmentation");
SetDocLongDescription("This application allows to perform various segmentation algorithm on an multispectral image. " 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 " " 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 " " 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 " " 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 largescale mode. In this case, the output of the application is a " " 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 splitted into tiles (whose size can be set using the tilesize parameter), and each tile is loaded, segmented " " 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 writen into the output file or database. This piece-wise behaviour ensure that memory will never get overloaded, " " 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 largescale mode. The simplify option allows to simplify the geometry " " 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 " " (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. "); " 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"); SetDocAuthors("OTB-Team");
SetDocSeeAlso("MeanShiftSegmentation"); SetDocSeeAlso("MeanShiftSegmentation");
...@@ -224,83 +224,83 @@ private: ...@@ -224,83 +224,83 @@ private:
SetMaximumParameterFloatValue("filter.watershed.level",1); SetMaximumParameterFloatValue("filter.watershed.level",1);
AddParameter(ParameterType_Choice, "mode", "Processing mode"); 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"); AddChoice("mode.vector", "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."); 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"); AddChoice("mode.raster", "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."); SetParameterDescription("mode.raster","In this mode, the application will output a standard labeled raster. This mode can not handle large data.");
//Normal mode parameters //Raster mode parameters
AddParameter(ParameterType_OutputImage, "mode.normal.lout", "Output labeled image"); AddParameter(ParameterType_OutputImage, "mode.raster.out", "Output labeled image");
SetParameterDescription( "mode.normal.lout", "The output labeled image."); SetParameterDescription( "mode.raster.out", "The output labeled image.");
//Streaming vectorization parameters //Streaming vectorization parameters
AddParameter(ParameterType_OutputFilename, "mode.largescale.outvd", "Output vector file"); AddParameter(ParameterType_OutputFilename, "mode.vector.out", "Output vector file");
SetParameterDescription("mode.largescale.outvd", "The output vector file or database (name can be anything understood by OGR)"); 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"); AddParameter(ParameterType_InputImage, "mode.vector.inmask", "Mask Image");
SetParameterDescription("mode.largescale.inmask", "Only pixels whose mask value is strictly positive will be segmented."); SetParameterDescription("mode.vector.inmask", "Only pixels whose mask value is strictly positive will be segmented.");
MandatoryOff("mode.largescale.inmask"); MandatoryOff("mode.vector.inmask");
AddParameter(ParameterType_Empty, "mode.largescale.neighbor", "8-neighbor connectivity"); AddParameter(ParameterType_Empty, "mode.vector.neighbor", "8-neighbor connectivity");
SetParameterDescription("mode.largescale.neighbor", SetParameterDescription("mode.vector.neighbor",
"Activate 8-Neighbourhood connectivity (default is 4)."); "Activate 8-Neighbourhood connectivity (default is 4).");
MandatoryOff("mode.largescale.neighbor"); MandatoryOff("mode.vector.neighbor");
EnableParameter("mode.largescale.neighbor"); EnableParameter("mode.vector.neighbor");
AddParameter(ParameterType_Empty,"mode.largescale.stitch","Stitch polygons"); AddParameter(ParameterType_Empty,"mode.vector.stitch","Stitch polygons");
SetParameterDescription("mode.largescale.stitch", "Scan polygons on each side of tiles and stitch polygons which connect by more than one pixel."); SetParameterDescription("mode.vector.stitch", "Scan polygons on each side of tiles and stitch polygons which connect by more than one pixel.");
MandatoryOff("mode.largescale.stitch"); MandatoryOff("mode.vector.stitch");
EnableParameter("mode.largescale.stitch"); EnableParameter("mode.vector.stitch");
AddParameter(ParameterType_Int, "mode.largescale.minsize", "Minimum object size"); AddParameter(ParameterType_Int, "mode.vector.minsize", "Minimum object size");
SetParameterDescription("mode.largescale.minsize", SetParameterDescription("mode.vector.minsize",
"Objects whose size is below the minimum object size (area in pixels) will be ignored during vectorization."); "Objects whose size is below the minimum object size (area in pixels) will be ignored during vectorization.");
SetDefaultParameterInt("mode.largescale.minsize", 1); SetDefaultParameterInt("mode.vector.minsize", 1);
SetMinimumParameterIntValue("mode.largescale.minsize", 1); SetMinimumParameterIntValue("mode.vector.minsize", 1);
MandatoryOff("mode.largescale.minsize"); MandatoryOff("mode.vector.minsize");
DisableParameter("mode.largescale.minsize"); DisableParameter("mode.vector.minsize");
AddParameter(ParameterType_Float, "mode.largescale.simplify", "Simplify polygons"); AddParameter(ParameterType_Float, "mode.vector.simplify", "Simplify polygons");
SetParameterDescription("mode.largescale.simplify", 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."); "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); SetDefaultParameterFloat("mode.vector.simplify",0.1);
MandatoryOff("mode.largescale.simplify"); MandatoryOff("mode.vector.simplify");
AddParameter(ParameterType_String, "mode.largescale.layername", "Layer name"); AddParameter(ParameterType_String, "mode.vector.layername", "Layer name");
SetParameterDescription("mode.largescale.layername", "Name of the layer in the vector file or database (default is Layer)."); SetParameterDescription("mode.vector.layername", "Name of the layer in the vector file or database (default is Layer).");
SetParameterString("mode.largescale.layername", "layer"); SetParameterString("mode.vector.layername", "layer");
AddParameter(ParameterType_String, "mode.largescale.fieldname", "Geometry index field name"); AddParameter(ParameterType_String, "mode.vector.fieldname", "Geometry index field name");
SetParameterDescription("mode.largescale.fieldname", "Name of the field holding the geometry index in the output vector file or database."); SetParameterDescription("mode.vector.fieldname", "Name of the field holding the geometry index in the output vector file or database.");
SetParameterString("mode.largescale.fieldname", "DN"); SetParameterString("mode.vector.fieldname", "DN");
AddParameter(ParameterType_Int, "mode.largescale.tilesize", "Tiles size"); AddParameter(ParameterType_Int, "mode.vector.tilesize", "Tiles size");
SetParameterDescription("mode.largescale.tilesize", SetParameterDescription("mode.vector.tilesize",
"User defined tiles size for tile-based segmentation. Optimal tile size is selected according to available RAM if null."); "User defined tiles size for tile-based segmentation. Optimal tile size is selected according to available RAM if null.");
SetDefaultParameterInt("mode.largescale.tilesize",1024); SetDefaultParameterInt("mode.vector.tilesize",1024);
SetMinimumParameterIntValue("mode.largescale.tilesize",0); SetMinimumParameterIntValue("mode.vector.tilesize",0);
AddParameter(ParameterType_Int, "mode.largescale.startlabel", "Starting geometry index"); AddParameter(ParameterType_Int, "mode.vector.startlabel", "Starting geometry index");
SetParameterDescription("mode.largescale.startlabel", "Starting value of the geometry index field"); SetParameterDescription("mode.vector.startlabel", "Starting value of the geometry index field");
SetDefaultParameterInt("mode.largescale.startlabel", 1); SetDefaultParameterInt("mode.vector.startlabel", 1);
SetMinimumParameterIntValue("mode.largescale.startlabel", 1); SetMinimumParameterIntValue("mode.vector.startlabel", 1);
// Doc example parameter settings // Doc example parameter settings
SetExampleComment("Example of use with vector mode and watershed segmentation",0); SetExampleComment("Example of use with vector mode and watershed segmentation",0);
SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_PAN.tif"); SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_PAN.tif");
SetDocExampleParameterValue("mode","largescale"); SetDocExampleParameterValue("mode","vector");
SetDocExampleParameterValue("mode.largescale.outvd", "SegmentationVectorData.sqlite"); SetDocExampleParameterValue("mode.vector.out", "SegmentationVector.sqlite");
SetDocExampleParameterValue("filter", "watershed"); SetDocExampleParameterValue("filter", "watershed");
AddExample("Example of use with raster mode and mean-shift segmentation"); AddExample("Example of use with raster mode and mean-shift segmentation");
SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_PAN.tif",1); SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_PAN.tif",1);
SetDocExampleParameterValue("mode","normal",1); SetDocExampleParameterValue("mode","raster",1);
SetDocExampleParameterValue("mode.normal.lout", "SegmentationVectorData.tif uint16",1); SetDocExampleParameterValue("mode.raster.out", "SegmentationRaster.tif uint16",1);
SetDocExampleParameterValue("filter", "meanshift",1); SetDocExampleParameterValue("filter", "meanshift",1);
} }
...@@ -321,20 +321,20 @@ private: ...@@ -321,20 +321,20 @@ private:
SegmentationFilterType> StreamingVectorizedSegmentationOGRType; SegmentationFilterType> StreamingVectorizedSegmentationOGRType;
// Retrieve tile size parameter // 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 // Retrieve the 8-connected option
bool use8connected = IsParameterEnabled("mode.largescale.neighbor"); bool use8connected = IsParameterEnabled("mode.vector.neighbor");
// Retrieve min object size parameter // 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 // Switch on segmentation mode
const std::string segModeType = (dynamic_cast <ChoiceParameter *> (this->GetParameterByKey("mode")))->GetChoiceKey(GetParameterInt("mode")); const std::string segModeType = (dynamic_cast <ChoiceParameter *> (this->GetParameterByKey("mode")))->GetChoiceKey(GetParameterInt("mode"));
streamingVectorizedFilter->SetInput(inputImage); 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); otbAppLogINFO(<<"Use a mask as input." << std::endl);
} }
streamingVectorizedFilter->SetOGRDataSource(ogrDS); streamingVectorizedFilter->SetOGRDataSource(ogrDS);
...@@ -361,20 +361,20 @@ private: ...@@ -361,20 +361,20 @@ private:
streamingVectorizedFilter->SetMinimumObjectSize(minSize); streamingVectorizedFilter->SetMinimumObjectSize(minSize);
} }
const std::string layerName = this->GetParameterString("mode.largescale.layername"); const std::string layerName = this->GetParameterString("mode.vector.layername");
const std::string fieldName = this->GetParameterString("mode.largescale.fieldname"); const std::string fieldName = this->GetParameterString("mode.vector.fieldname");
// Retrieve start label parameter // 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->SetLayerName(layerName);
streamingVectorizedFilter->SetFieldName(fieldName); streamingVectorizedFilter->SetFieldName(fieldName);
streamingVectorizedFilter->SetStartLabel(startLabel); streamingVectorizedFilter->SetStartLabel(startLabel);
if(IsParameterEnabled("mode.largescale.simplify")) if(IsParameterEnabled("mode.vector.simplify"))
{ {
streamingVectorizedFilter->SetSimplify(true); streamingVectorizedFilter->SetSimplify(true);
streamingVectorizedFilter->SetSimplificationTolerance(GetParameterFloat("mode.largescale.simplify")); streamingVectorizedFilter->SetSimplificationTolerance(GetParameterFloat("mode.vector.simplify"));
otbAppLogINFO(<<"Simplify the geometry." << std::endl); otbAppLogINFO(<<"Simplify the geometry." << std::endl);
} }
else else
...@@ -382,7 +382,7 @@ private: ...@@ -382,7 +382,7 @@ private:
streamingVectorizedFilter->SetSimplify(false); streamingVectorizedFilter->SetSimplify(false);
} }
if (segModeType == "largescale") if (segModeType == "vector")
{ {
otbAppLogINFO(<<"Large scale segmentation mode which output vector data" << std::endl); 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"); AddProcess(streamingVectorizedFilter->GetStreamer(), "Computing " + (dynamic_cast <ChoiceParameter *> (this->GetParameterByKey("filter")))->GetChoiceKey(GetParameterInt("filter")) + " segmentation");
...@@ -390,14 +390,14 @@ private: ...@@ -390,14 +390,14 @@ private:
streamingVectorizedFilter->Initialize(); //must be called ! streamingVectorizedFilter->Initialize(); //must be called !
streamingVectorizedFilter->Update(); //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); otbAppLogINFO(<<"Segmentation mode which output label image" << std::endl);
streamingVectorizedFilter->GetSegmentationFilter()->SetInput(inputImage); streamingVectorizedFilter->GetSegmentationFilter()->SetInput(inputImage);
SetParameterOutputImage<UInt32ImageType> ("mode.normal.lout", dynamic_cast<UInt32ImageType *> (streamingVectorizedFilter->GetSegmentationFilter()->GetOutputs().at(outputNb).GetPointer())); SetParameterOutputImage<UInt32ImageType> ("mode.raster.out", dynamic_cast<UInt32ImageType *> (streamingVectorizedFilter->GetSegmentationFilter()->GetOutputs().at(outputNb).GetPointer()));
//TODO add progress reporting in normal mode //TODO add progress reporting in raster mode
// AddProcess(dynamic_cast <OutputImageParameter *> (GetParameterByKey("mode.normal.lout"))->GetWriter(), // AddProcess(dynamic_cast <OutputImageParameter *> (GetParameterByKey("mode.raster.out"))->GetWriter(),
// "Computing " + (dynamic_cast <ChoiceParameter *> // "Computing " + (dynamic_cast <ChoiceParameter *>
// (this->GetParameterByKey("filter")))->GetChoiceKey(GetParameterInt("filter")) // (this->GetParameterByKey("filter")))->GetChoiceKey(GetParameterInt("filter"))
// + " segmentation"); // + " segmentation");
...@@ -415,10 +415,10 @@ private: ...@@ -415,10 +415,10 @@ private:
otb::ogr::DataSource::Pointer ogrDS; otb::ogr::DataSource::Pointer ogrDS;
if(segModeType=="largescale") if(segModeType=="vector")
{ {
// Retrieve output filename as well as layer names // 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); ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::write);
} }
...@@ -431,9 +431,9 @@ private: ...@@ -431,9 +431,9 @@ private:
ConnectedComponentStreamingVectorizedSegmentationOGRType::Pointer ConnectedComponentStreamingVectorizedSegmentationOGRType::Pointer
ccVectorizationFilter = ConnectedComponentStreamingVectorizedSegmentationOGRType::New(); 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( ccVectorizationFilter->GetSegmentationFilter()->GetFunctor().SetExpression(
...@@ -513,15 +513,15 @@ private: ...@@ -513,15 +513,15 @@ private:
otbAppLogFATAL(<<"non defined filtering method "<<GetParameterInt("filter")<<std::endl); otbAppLogFATAL(<<"non defined filtering method "<<GetParameterInt("filter")<<std::endl);
} }
if (segModeType == "largescale" ) if (segModeType == "vector" )
{ {
ogrDS->SyncToDisk(); ogrDS->SyncToDisk();
// Stitching mode // Stitching mode
if(IsParameterEnabled("mode.largescale.stitch")) if(IsParameterEnabled("mode.vector.stitch"))
{ {
otbAppLogINFO(<<"Segmentation done, stiching polygons ..."); 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(); FusionFilterType::Pointer fusionFilter = FusionFilterType::New();
fusionFilter->SetInput(GetParameterFloatVectorImage("in")); fusionFilter->SetInput(GetParameterFloatVectorImage("in"));
...@@ -533,7 +533,7 @@ private: ...@@ -533,7 +533,7 @@ private:
fusionFilter->GenerateData(); fusionFilter->GenerateData();
} }
} }
else if (segModeType == "normal") else if (segModeType == "raster")
{ {
otbAppLogINFO(<<"implementation in progress..." << std::endl); otbAppLogINFO(<<"implementation in progress..." << std::endl);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment