Request for Changes-17: Provide a default output pixel type in applications

From OTBWiki
Jump to: navigation, search

[Request for Changes - 17] Provide a default output pixel type in applications

Status

Summary

This RFC adds a default pixel type for output image parameters in the ApplicationEngine.

Rationale

An issue was raised on develop list, that the classification application always cast outputs to uint8 pixel type, which can be a problem with class labels greater than 255. The output pixel type is float by default but applications can change it in the DoInit(). It is useful to know the default output pixel type in a help message (and not the current value of the output pixel type).

Implementation details

Classes and files

M       Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
M       Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h
M       Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h
M       Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
M       Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx
M       Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx

A protected attribute "m_DefaultPixelType" (resp. "m_DefaultComplexPixelType") has been added to the OutputImageParameter class (resp. ComplexOutputImageParameter). The classes also offer static methods to convert a pixel type into "human readable" string (ConvertPixelTypeToString).

The Reset() method is re-implemented in those classes in order to reset the pixel type to default, however, this reset is not actually used in application launchers (cli or gui).

The class Application offers 2 methods to set a default pixel type to an OutputImageParameter or a ComplexOutputImageParameter.

M       Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx

The help message from command line launcher has been improved : it now reads the default pixel type from (Complex)OutputImageParameter and displays it.

Applications

M       Modules/Applications/AppClassification/app/otbClassificationMapRegularization.cxx
M       Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx
M       Modules/Applications/AppClassification/app/otbImageClassifier.cxx
M       Modules/Applications/AppClassification/app/otbKMeansClassification.cxx
M       Modules/Applications/AppClassification/app/otbSOMClassification.cxx
M       Modules/Applications/AppImageUtils/app/otbColorMapping.cxx
M       Modules/Applications/AppSegmentation/app/otbHooverCompareSegmentation.cxx
M       Modules/Applications/AppSegmentation/app/otbLSMSSegmentation.cxx
M       Modules/Applications/AppSegmentation/app/otbLSMSSmallRegionsMerging.cxx
M       Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
M       Modules/Applications/AppStereo/app/otbBlockMatching.cxx

Among all the OutputImageParameter in the applications, some of them produce RGB color images, binray mask or label images. For these cases, the default pixel type should be different than Float :

  • RGB color image : uint8
  • binary mask : uint8
  • class label image : uint8 (although in some cases, uint16 is necessary)
  • region label from segmentation : uint32

Tests

(no impact)

Documentation

Additional notes

Full patch

diff --git a/Modules/Applications/AppClassification/app/otbClassificationMapRegularization.cxx b/Modules/Applications/AppClassification/app/otbClassificationMapRegularization.cxx
index 1ecd2c9..4e000cd 100644
--- a/Modules/Applications/AppClassification/app/otbClassificationMapRegularization.cxx
+++ b/Modules/Applications/AppClassification/app/otbClassificationMapRegularization.cxx
@@ -78,7 +78,7 @@ private:
 
     AddParameter(ParameterType_OutputImage, "io.out",  "Output regularized image");
     SetParameterDescription( "io.out", "The output regularized labeled image.");
-    SetParameterOutputImagePixelType( "io.out", ImagePixelType_uint8);
+    SetDefaultOutputPixelType( "io.out", ImagePixelType_uint8);
 
 
     AddParameter(ParameterType_Group,"ip","Regularization parameters");
diff --git a/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx b/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx
index 848d41b..f518994 100644
--- a/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx
+++ b/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx
@@ -156,6 +156,7 @@ private:
 
     AddParameter(ParameterType_OutputImage,"out","The output classification image");
     SetParameterDescription("out","The output classification image resulting from the fusion of the input classification images.");
+    SetDefaultOutputPixelType("out",ImagePixelType_uint8);
 
     // Doc example parameter settings
     SetDocExampleParameterValue("il", "classification1.tif classification2.tif classification3.tif");
diff --git a/Modules/Applications/AppClassification/app/otbImageClassifier.cxx b/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
index 8cd4c5b..a47a006 100644
--- a/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
@@ -93,7 +93,7 @@ private:
 
     AddParameter(ParameterType_OutputImage, "out",  "Output Image");
     SetParameterDescription( "out", "Output image containing class labels");
-    SetParameterOutputImagePixelType( "out", ImagePixelType_uint8);
+    SetDefaultOutputPixelType( "out", ImagePixelType_uint8);
 
     AddParameter(ParameterType_OutputImage, "confmap",  "Confidence map");
     SetParameterDescription( "confmap", "Confidence map of the produced classification. The confidence index depends on the model : \n"
@@ -107,7 +107,7 @@ private:
       "    * NormalBayes : (not supported)\n"
       "    * RandomForest : proportion of decision trees that classified the sample to the second class (only works for 2-class models)\n"
       "    * SVM : distance to margin (only works for 2-class models)\n");
-    SetParameterOutputImagePixelType( "confmap", ImagePixelType_double);
+    SetDefaultOutputPixelType( "confmap", ImagePixelType_double);
     MandatoryOff("confmap");
 
     AddRAMParameter();
diff --git a/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx b/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx
index 4844205..c7ba58f 100644
--- a/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx
+++ b/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx
@@ -181,6 +181,7 @@ private:
     SetParameterDescription("in", "Input image to classify.");
     AddParameter(ParameterType_OutputImage, "out", "Output Image");
     SetParameterDescription("out", "Output image containing the class indexes.");
+    SetDefaultOutputPixelType("out",ImagePixelType_uint8);
 
     AddRAMParameter();
 
diff --git a/Modules/Applications/AppClassification/app/otbSOMClassification.cxx b/Modules/Applications/AppClassification/app/otbSOMClassification.cxx
index 9d9dd94..5e3daf1 100644
--- a/Modules/Applications/AppClassification/app/otbSOMClassification.cxx
+++ b/Modules/Applications/AppClassification/app/otbSOMClassification.cxx
@@ -87,6 +87,7 @@ private:
 
     AddParameter(ParameterType_OutputImage,  "out",   "OutputImage");
     SetParameterDescription("out", "Output classified image (each pixel contains the index of its corresponding vector in the SOM).");
+    SetDefaultOutputPixelType("out",ImagePixelType_uint8);
 
     AddParameter(ParameterType_InputImage,  "vm",   "ValidityMask");
     SetParameterDescription("vm", "Validity mask (only pixels corresponding to a mask value greater than 0 will be used for learning)");
diff --git a/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx b/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx
index c20d69a..432ba75 100644
--- a/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx
@@ -291,6 +291,7 @@ private:
     SetParameterDescription("in", "Input image filename");
     AddParameter(ParameterType_OutputImage, "out", "Output Image");
     SetParameterDescription("out","Output image filename");
+    SetDefaultOutputPixelType("out",ImagePixelType_uint8);
 
     AddRAMParameter();
 
diff --git a/Modules/Applications/AppSegmentation/app/otbHooverCompareSegmentation.cxx b/Modules/Applications/AppSegmentation/app/otbHooverCompareSegmentation.cxx
index 9b52f3b..74423df 100644
--- a/Modules/Applications/AppSegmentation/app/otbHooverCompareSegmentation.cxx
+++ b/Modules/Applications/AppSegmentation/app/otbHooverCompareSegmentation.cxx
@@ -165,10 +165,12 @@ private:
 
     AddParameter(ParameterType_OutputImage,  "outgt",    "Colored ground truth output");
     SetParameterDescription( "outgt", "The colored ground truth output image." );
+    SetDefaultOutputPixelType("outgt",ImagePixelType_uint8);
     MandatoryOff("outgt");
 
     AddParameter(ParameterType_OutputImage,  "outms",    "Colored machine segmentation output");
     SetParameterDescription( "outms", "The colored machine segmentation output image." );
+    SetDefaultOutputPixelType("outms",ImagePixelType_uint8);
     MandatoryOff("outms");
 
     // TODO : add color settings ?
diff --git a/Modules/Applications/AppSegmentation/app/otbLSMSSegmentation.cxx b/Modules/Applications/AppSegmentation/app/otbLSMSSegmentation.cxx
index 1af6e23..bafff60 100644
--- a/Modules/Applications/AppSegmentation/app/otbLSMSSegmentation.cxx
+++ b/Modules/Applications/AppSegmentation/app/otbLSMSSegmentation.cxx
@@ -225,6 +225,7 @@ private:
 
     AddParameter(ParameterType_OutputImage, "out", "Output Image");
     SetParameterDescription( "out", "The output image. The output image is the segmentation of the filtered image. It is recommended to set the pixel type to uint32." );
+    SetDefaultOutputPixelType("out",ImagePixelType_uint32);
 
     AddParameter(ParameterType_Float, "ranger", "Range radius");
     SetParameterDescription("ranger", "Range radius defining the radius (expressed in radiometry unit) in the multi-spectral space.");
diff --git a/Modules/Applications/AppSegmentation/app/otbLSMSSmallRegionsMerging.cxx b/Modules/Applications/AppSegmentation/app/otbLSMSSmallRegionsMerging.cxx
index 9ea8f90..c2122b5 100644
--- a/Modules/Applications/AppSegmentation/app/otbLSMSSmallRegionsMerging.cxx
+++ b/Modules/Applications/AppSegmentation/app/otbLSMSSmallRegionsMerging.cxx
@@ -90,6 +90,7 @@ private:
 
     AddParameter(ParameterType_OutputImage, "out", "Output Image");
     SetParameterDescription( "out", "The output image. The output image is the input image where the minimal regions have been merged." );
+    SetDefaultOutputPixelType("out",ImagePixelType_uint32);
 
     AddParameter(ParameterType_Int, "minsize", "Minimum Region Size");
     SetParameterDescription("minsize", "Minimum Region Size. If, after the segmentation, a region is of size lower than this criterion, the region is merged with the \"nearest\" region (radiometrically).");
diff --git a/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx b/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
index 8015f13..bce82fc 100644
--- a/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
+++ b/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
@@ -251,6 +251,7 @@ private:
     //Raster mode parameters
     AddParameter(ParameterType_OutputImage,  "mode.raster.out",    "Output labeled image");
     SetParameterDescription( "mode.raster.out", "The output labeled image.");
+    SetDefaultOutputPixelType("mode.raster.out",ImagePixelType_uint32);
 
     //Streaming vectorization parameters
     AddParameter(ParameterType_OutputFilename, "mode.vector.out", "Output vector file");
diff --git a/Modules/Applications/AppStereo/app/otbBlockMatching.cxx b/Modules/Applications/AppStereo/app/otbBlockMatching.cxx
index 51fcada..246fef0 100644
--- a/Modules/Applications/AppStereo/app/otbBlockMatching.cxx
+++ b/Modules/Applications/AppStereo/app/otbBlockMatching.cxx
@@ -155,6 +155,7 @@ private:
 
     AddParameter(ParameterType_OutputImage, "io.outmask", "The output mask corresponding to all criterions");
     SetParameterDescription("io.outmask","A mask image corresponding to all citerions (see masking parameters). Only required if variance threshold or nodata criterions are set.");
+    SetDefaultOutputPixelType("io.outmask",ImagePixelType_uint8);
     DisableParameter("io.outmask");
     MandatoryOff("io.outmask");
 
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
index 9c83a78..955a76b 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
@@ -247,6 +247,20 @@ public:
    */
   void SetDefaultParameterFloat(std::string parameter, float value);
 
+  /** Set a default pixel type for an output image parameter
+   *
+   * \param[in] parameter Name of the output image parameter
+   * \param[in] type Default pixel type
+   */
+  void SetDefaultOutputPixelType(std::string parameter, ImagePixelType type);
+
+  /** Set a default complex pixel type for an output complex image parameter
+   *
+   * \param[in] parameter Name of the output complex image parameter
+   * \param[in] type Default complex pixel type
+   */
+  void SetDefaultOutputComplexPixelType(std::string parameter, ComplexImagePixelType type);
+
  /* Set a minimum int value, must used in the
    * DoInit when setting a value by default
    * for the parameter
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h
index 6500d54..5edf833 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h
@@ -61,14 +61,27 @@ public:
   /** Return any value */
   ImageBaseType* GetValue( void );
 
-  /** Set/Get PixelType to be used when saving */
+  /** Set/Get m_ComplexPixelType to be used when saving */
   itkSetMacro(ComplexPixelType, ComplexImagePixelType);
   itkGetMacro(ComplexPixelType, ComplexImagePixelType);
 
+  /** Set/Get m_DefaultComplexPixelType*/
+  itkSetMacro(DefaultComplexPixelType, ComplexImagePixelType);
+  itkGetMacro(DefaultComplexPixelType, ComplexImagePixelType);
+
   /** Set/Get available RAM value */
   itkSetMacro(RAMValue, unsigned int);
   itkGetMacro(RAMValue, unsigned int);
 
+  /** Implement the reset method (replace pixel type by default type) */
+  virtual void Reset()
+  {
+    m_ComplexPixelType = m_DefaultComplexPixelType;
+  }
+
+  /** Static method to convert pixel type into string */
+  static std::string ConvertPixelTypeToString(ComplexImagePixelType type);
+
   /** Return true if a filename is set */
   bool HasValue() const;
 
@@ -106,7 +119,7 @@ protected:
   ImageBaseType::Pointer m_Image;
   std::string            m_FileName;
   ComplexImagePixelType         m_ComplexPixelType;
-
+  ComplexImagePixelType         m_DefaultComplexPixelType;
 
   typedef otb::ImageFileWriter<ComplexFloatImageType>  ComplexFloatWriterType;
   typedef otb::ImageFileWriter<ComplexDoubleImageType> ComplexDoubleWriterType;
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h
index a8dc212..3313e5a 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h
@@ -66,10 +66,23 @@ public:
   itkSetMacro(PixelType, ImagePixelType);
   itkGetMacro(PixelType, ImagePixelType);
 
+  /** Set/Get DefaultPixelType  */
+  itkSetMacro(DefaultPixelType, ImagePixelType);
+  itkGetMacro(DefaultPixelType, ImagePixelType);
+
   /** Set/Get available RAM value */
   itkSetMacro(RAMValue, unsigned int);
   itkGetMacro(RAMValue, unsigned int);
 
+  /** Implement the reset method (replace pixel type by default type) */
+  virtual void Reset()
+  {
+    m_PixelType = m_DefaultPixelType;
+  }
+
+  /** Static method to convert pixel type into string */
+  static std::string ConvertPixelTypeToString(ImagePixelType type);
+
   /** Return true if a filename is set */
   bool HasValue() const;
 
@@ -113,6 +126,7 @@ protected:
   ImageBaseType::Pointer m_Image;
   std::string            m_FileName;
   ImagePixelType         m_PixelType;
+  ImagePixelType         m_DefaultPixelType;
 
   typedef otb::ImageFileWriter<UInt8ImageType>  UInt8WriterType;
   typedef otb::ImageFileWriter<Int16ImageType>  Int16WriterType;
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
index 8176e2f..2612a7c 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
@@ -657,6 +657,29 @@ void Application::SetDefaultParameterFloat(std::string parameter, float value)
     }
 }
 
+void Application::SetDefaultOutputPixelType(std::string parameter, ImagePixelType type)
+{
+  Parameter* param = GetParameterByKey(parameter);
+  OutputImageParameter* paramDown = dynamic_cast<OutputImageParameter*>(param);
+  if (paramDown)
+    {
+    paramDown->SetDefaultPixelType(type);
+    paramDown->SetPixelType(type);
+    }
+}
+
+void
+Application::SetDefaultOutputComplexPixelType(std::string parameter, ComplexImagePixelType type)
+{
+  Parameter* param = GetParameterByKey(parameter);
+  ComplexOutputImageParameter* paramDown = dynamic_cast<ComplexOutputImageParameter*>(param);
+  if (paramDown)
+    {
+    paramDown->SetDefaultComplexPixelType(type);
+    paramDown->SetComplexPixelType(type);
+    }
+}
+
 void Application::SetMinimumParameterIntValue(std::string parameter, int value)
 {
   Parameter* param = GetParameterByKey(parameter);
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx
index e87df13..d4f157e 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx
@@ -26,7 +26,9 @@ namespace Wrapper
 {
 
 ComplexOutputImageParameter::ComplexOutputImageParameter()
-  : m_ComplexPixelType(ComplexImagePixelType_float), m_RAMValue(0)
+  : m_ComplexPixelType(ComplexImagePixelType_float),
+    m_DefaultComplexPixelType(ComplexImagePixelType_float),
+    m_RAMValue(0)
 {
   this->SetName("Complex Output Image");
   this->SetKey("cout");
@@ -36,6 +38,26 @@ ComplexOutputImageParameter::~ComplexOutputImageParameter()
 {
 }
 
+std::string
+ComplexOutputImageParameter::ConvertPixelTypeToString(ComplexImagePixelType type)
+{
+  std::string ret;
+  switch(type)
+    {
+    case ComplexImagePixelType_float:
+      {
+      ret = "cfloat";
+      break;
+      }
+    case ComplexImagePixelType_double:
+      {
+      ret = "cdouble";
+      break;
+      }
+    }
+  return ret;
+}
+
 void ComplexOutputImageParameter::InitializeWriters()
 {
   m_ComplexFloatWriter = ComplexFloatWriterType::New();
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx
index 47498fa..ec02594 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx
@@ -25,7 +25,9 @@ namespace Wrapper
 {
 
 OutputImageParameter::OutputImageParameter()
-  : m_PixelType(ImagePixelType_float), m_RAMValue(0)
+  : m_PixelType(ImagePixelType_float),
+    m_DefaultPixelType(ImagePixelType_float),
+    m_RAMValue(0)
 {
   this->SetName("Output Image");
   this->SetKey("out");
@@ -36,6 +38,50 @@ OutputImageParameter::~OutputImageParameter()
 {
 }
 
+std::string OutputImageParameter::ConvertPixelTypeToString(ImagePixelType type)
+{
+  std::string ret;
+  switch(type)
+    {
+    case ImagePixelType_uint8:
+      {
+      ret = "uint8";
+      break;
+      }
+    case ImagePixelType_int16:
+      {
+      ret = "int16";
+      break;
+      }
+    case ImagePixelType_uint16:
+      {
+      ret = "uint16";
+      break;
+      }
+    case ImagePixelType_int32:
+      {
+      ret = "int32";
+      break;
+      }
+    case ImagePixelType_uint32:
+      {
+      ret = "uint32";
+      break;
+      }
+    case ImagePixelType_float:
+      {
+      ret = "float";
+      break;
+      }
+    case ImagePixelType_double:
+      {
+      ret = "double";
+      break;
+      }
+    }
+  return ret;
+}
+
 void OutputImageParameter::InitializeWriters()
 {
   m_UInt8Writer = UInt8WriterType::New();
diff --git a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
index c3cd479..84a9112 100644
--- a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
+++ b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
@@ -844,14 +844,26 @@ std::string CommandLineLauncher::DisplayParameterHelp(const Parameter::Pointer &
 
   if (type == ParameterType_OutputImage)
     {
+    OutputImageParameter* paramDown = dynamic_cast<OutputImageParameter*>(param.GetPointer());
+    std::string defPixType("float");
+    if (paramDown)
+      {
+      defPixType = OutputImageParameter::ConvertPixelTypeToString(paramDown->GetDefaultPixelType());
+      }
     oss << " [pixel=uint8/uint16/int16/uint32/int32/float/double]";
-    oss << " (default value is float)";
+    oss << " (default value is " << defPixType <<")";
     }
 
   if (type == ParameterType_ComplexOutputImage)
     {
+    ComplexOutputImageParameter* paramDown = dynamic_cast<ComplexOutputImageParameter*>(param.GetPointer());
+    std::string defPixType("cfloat");
+    if (paramDown)
+      {
+      defPixType = ComplexOutputImageParameter::ConvertPixelTypeToString(paramDown->GetDefaultComplexPixelType());
+      }
     oss << " [pixel=cfloat/cdouble]";
-    oss << " (default value is cfloat)";
+    oss << " (default value is "<< defPixType <<")";
     }