diff --git a/Modules/Applications/AppClassification/app/otbComputeConfusionMatrix.cxx b/Modules/Applications/AppClassification/app/otbComputeConfusionMatrix.cxx
index f9ac0883b784ffe569542485c080cf9fc372dc50..ab24b34016151ad1a4de84fd4db363ccd097f373 100644
--- a/Modules/Applications/AppClassification/app/otbComputeConfusionMatrix.cxx
+++ b/Modules/Applications/AppClassification/app/otbComputeConfusionMatrix.cxx
@@ -91,7 +91,10 @@ private:
 
   struct StreamingInitializationData
   {
-    int nodata;
+    bool refhasnodata;
+    bool prodhasnodata;
+    int  prodnodata;
+    int  refnodata;
     unsigned long numberOfStreamDivisions;
   };
 
@@ -143,12 +146,17 @@ private:
   SetParameterDescription("ref.vector.field","Field name containing the label values");
   SetListViewSingleSelectionMode("ref.vector.field",true);
   
-  AddParameter(ParameterType_Int,"nodatalabel","Value for nodata pixels");
-  SetParameterDescription("nodatalabel", "Label for the NoData class. Such input pixels will be discarded from the "
-      "ground truth and from the input classification map. By default, 'nodatalabel = 0'.");
-  SetDefaultParameterInt("nodatalabel",0);
-  MandatoryOff("nodatalabel");
-  DisableParameter("nodatalabel");
+  AddParameter(ParameterType_Int,"refnodatalabel","Value for nodata pixels in ref");
+  SetDefaultParameterInt("refnodatalabel",0);
+  SetParameterDescription("refnodatalabel","Label to be treated as no data in ref. Please note that this value is always used in vector mode, to generate default values. Please set it to a value that does not correspond to a class label.");
+  MandatoryOff("refnodatalabel");
+  DisableParameter("refnodatalabel");
+  AddParameter(ParameterType_Int,"prodnodatalabel","Value for nodata pixels in input image");
+  SetParameterDescription("prodnodatalabel","Label to be treated as no data in input image");
+  SetDefaultParameterInt("prodnodatalabel",0);
+  
+  MandatoryOff("prodnodatalabel");
+  DisableParameter("prodnodatalabel");
 
   AddRAMParameter();
 
@@ -158,7 +166,7 @@ private:
   SetDocExampleParameterValue("ref", "vector");
   SetDocExampleParameterValue("ref.vector.in","VectorData_QB1_bis.shp");
   SetDocExampleParameterValue("ref.vector.field","Class");
-  SetDocExampleParameterValue("nodatalabel","255");
+  SetDocExampleParameterValue("refnodatalabel","255");
   }
 
   void DoUpdateParameters() ITK_OVERRIDE
@@ -193,7 +201,7 @@ private:
 
   void LogContingencyTable(const ContingencyTableType& contingencyTable)
   {
-    otbAppLogINFO("Contingency table : :\n" << contingencyTable);
+    otbAppLogINFO("Contingency table: reference labels (rows) vs. produced labels (cols)\n" << contingencyTable);
   }
 
   void writeContingencyTable(const ContingencyTableType& contingencyTable)
@@ -286,14 +294,22 @@ private:
     std::string field;
 
     rasterizeReference = RasterizeFilterType::New();
-    sid.nodata = this->GetParameterInt("nodatalabel");
+    sid.refnodata = this->GetParameterInt("refnodatalabel");
+    sid.refhasnodata = this->IsParameterEnabled("refnodatalabel");
+    sid.prodnodata = this->GetParameterInt("prodnodatalabel");
+    sid.prodhasnodata = this->IsParameterEnabled("prodnodatalabel");
+
 
+    
     if (GetParameterString("ref") == "raster")
       {
       reference = this->GetParameterInt32Image("ref.raster.in");
       }
     else
       {
+      // Force nodata to true since it will be generated during rasterization
+      sid.refhasnodata = true;
+      
       ogrRef = otb::ogr::DataSource::New(GetParameterString("ref.vector.in"), otb::ogr::DataSource::Modes::Read);
 
       // Get field name
@@ -309,7 +325,7 @@ private:
 
       rasterizeReference->AddOGRDataSource(ogrRef);
       rasterizeReference->SetOutputParametersFromImage(input);
-      rasterizeReference->SetBackgroundValue(sid.nodata);
+      rasterizeReference->SetBackgroundValue(sid.refnodata);
       rasterizeReference->SetBurnAttribute(field.c_str());
 
       reference = rasterizeReference->GetOutput();
@@ -371,7 +387,7 @@ private:
       ImageIteratorType itRef( reference, streamRegion );
       itRef.GoToBegin();
 
-      calculator->Compute( itRef, itInput );
+      calculator->Compute( itRef, itInput,sid.refhasnodata,sid.refnodata,sid.prodhasnodata,sid.prodnodata);
       }
 
     ContingencyTableType contingencyTable = calculator->GetContingencyTable();
@@ -412,7 +428,7 @@ private:
         labelProd = static_cast<ClassLabelType> (itInput.Get());
 
         // Extraction of the reference/produced class labels
-        if ((labelRef != sid.nodata) && (labelProd != sid.nodata))
+        if ((!sid.refhasnodata || labelRef != sid.refnodata) && (!sid.prodhasnodata || labelProd != sid.prodnodata))
           {
           // If the current labels have not been added to their respective mapOfClasses yet
           if (mapOfClassesRef.insert(MapOfClassesType::value_type(labelRef, itLabelRef)).second)
diff --git a/Modules/Learning/Unsupervised/include/otbContingencyTableCalculator.h b/Modules/Learning/Unsupervised/include/otbContingencyTableCalculator.h
index e3d8e9355a3efdc7bb300486fd60ac8c306884bd..e9834d88ae36d8e7d225f960ae6f5f3be9cf9143 100644
--- a/Modules/Learning/Unsupervised/include/otbContingencyTableCalculator.h
+++ b/Modules/Learning/Unsupervised/include/otbContingencyTableCalculator.h
@@ -60,7 +60,8 @@ public:
 
   /** Populate the confusion Matrix for a image iteration */
   template<class TRefIterator, class TProdIterator>
-  void Compute(TRefIterator itRef, TProdIterator itProd);
+    void Compute(TRefIterator itRef, TProdIterator itProd, bool refHasNoData = false, typename TRefIterator::InternalPixelType refNoData = 0,
+                 bool prodHasNoData = false, typename TProdIterator::InternalPixelType prodNoData = 0);
 
   /** Populate the confusion Matrix with input which provide GetMeasurementVector()[0] access */
   template<class TRefIterator, class TProdIterator>
@@ -86,8 +87,6 @@ private:
   unsigned long m_NumberOfRefClasses;
   unsigned long m_NumberOfProdClasses;
   unsigned long m_NumberOfSamples;
-
-
 };
 }
 
diff --git a/Modules/Learning/Unsupervised/include/otbContingencyTableCalculator.txx b/Modules/Learning/Unsupervised/include/otbContingencyTableCalculator.txx
index b9583c0e6d359655bd5043387d2e2b7086e63fad..49fdbc9df8ad0c9734e8e1105e402b6bc5d9af47 100644
--- a/Modules/Learning/Unsupervised/include/otbContingencyTableCalculator.txx
+++ b/Modules/Learning/Unsupervised/include/otbContingencyTableCalculator.txx
@@ -65,14 +65,19 @@ template<class TClassLabel>
 template<class TRefIterator, class TProdIterator>
 void
 ContingencyTableCalculator<TClassLabel>
-::Compute(TRefIterator itRef, TProdIterator itProd)
+::Compute(TRefIterator itRef, TProdIterator itProd, bool refHasNoData, typename TRefIterator::InternalPixelType refNoData,
+                 bool prodHasNoData, typename TProdIterator::InternalPixelType prodNoData)
 {
   while( !itRef.IsAtEnd() && !itProd.IsAtEnd() )
     {
-    ++m_LabelCount[itRef.Get()][itProd.Get()];
-    ++itRef;
+    if((!prodHasNoData || itProd.Get()!=prodNoData)
+       &&(!refHasNoData || itRef.Get()!=refNoData))
+      {
+      ++m_LabelCount[itRef.Get()][itProd.Get()];
+      ++m_NumberOfSamples;
+      }
+      ++itRef;
     ++itProd;
-    ++m_NumberOfSamples;
     }
 }