diff --git a/Applications/DisparityMap/otbPixelWiseBlockMatching.cxx b/Applications/DisparityMap/otbPixelWiseBlockMatching.cxx
index 6fd1fa60dc78e6a805325456dda092a02be894b3..3a9f47c965f2920a9a8879eda7387ca11afc4762 100644
--- a/Applications/DisparityMap/otbPixelWiseBlockMatching.cxx
+++ b/Applications/DisparityMap/otbPixelWiseBlockMatching.cxx
@@ -40,6 +40,7 @@ public:
 
   typedef otb::Functor::SSDBlockMatching<FloatImageType,FloatImageType> SSDBlockMatchingFunctorType;
   typedef otb::Functor::NCCBlockMatching<FloatImageType,FloatImageType> NCCBlockMatchingFunctorType;
+  typedef otb::Functor::LPBlockMatching<FloatImageType,FloatImageType>  LPBlockMatchingFunctorType;
 
   typedef otb::PixelWiseBlockMatchingImageFilter<FloatImageType,
                                                            FloatImageType,
@@ -53,6 +54,12 @@ public:
                                                            FloatImageType,
                                                            NCCBlockMatchingFunctorType> NCCBlockMatchingFilterType;
 
+  typedef otb::PixelWiseBlockMatchingImageFilter<FloatImageType,
+                                                           FloatImageType,
+                                                           FloatImageType,
+                                                           FloatImageType,
+                                                           LPBlockMatchingFunctorType> LPBlockMatchingFilterType;
+  
   typedef otb::VarianceImageFilter<FloatImageType,FloatImageType> VarianceFilterType;
 
 
@@ -77,6 +84,7 @@ private:
     // Initialize filters
     m_SSDBlockMatcher = SSDBlockMatchingFilterType::New();
     m_NCCBlockMatcher = NCCBlockMatchingFilterType::New();
+    m_LPBlockMatcher  = LPBlockMatchingFilterType::New();
     m_VarianceFilter  = VarianceFilterType::New();
     m_BandMathFilter  = BandMathFilterType::New();
     m_OutputImageList = ImageListType::New();
@@ -154,6 +162,14 @@ private:
     AddChoice("bm.metric.ncc","Normalized Cross-Correlation");
     SetParameterDescription("bm.metric.ncc","Normalized Cross-Correlation between the left and right windows");
     
+    AddChoice("bm.metric.lp","Lp pseudo-norm");
+    SetParameterDescription("bm.metric.lp","Lp pseudo-norm between the left and right windows");
+    
+    AddParameter(ParameterType_Float,"bm.metric.lp.p","p value" );
+    SetParameterDescription("bm.metric.lp.p", "Value of the p parameter in Lp pseudo-norm (must be positive)");
+    SetDefaultParameterFloat("bm.metric.lp.p", 1.0);
+    SetMinimumParameterFloatValue("bm.metric.lp.p", 0.0);
+    
     AddParameter(ParameterType_Int,"bm.radius","Radius of blocks");
     SetParameterDescription("bm.radius","The radius (in pixels) of blocks in Block-Matching");
     SetDefaultParameterInt("bm.radius",3);
@@ -392,7 +408,7 @@ private:
       metricImage = m_SSDBlockMatcher->GetMetricOutput();
       }
     // NCC case
-    else
+    else if (GetParameterInt("bm.metric") == 1)
       {
       m_NCCBlockMatcher->SetLeftInput(leftImage);
       m_NCCBlockMatcher->SetRightInput(rightImage);
@@ -431,6 +447,46 @@ private:
       vdispImage = m_NCCBlockMatcher->GetVerticalDisparityOutput();
       metricImage = m_NCCBlockMatcher->GetMetricOutput();
       }
+    // Lp case
+    else
+      {
+      m_LPBlockMatcher->SetLeftInput(leftImage);
+      m_LPBlockMatcher->SetRightInput(rightImage);
+      m_LPBlockMatcher->SetRadius(radius);
+      m_LPBlockMatcher->GetFunctor().SetP(static_cast<double>(GetParameterFloat("bm.metric.lp.p")));
+      m_LPBlockMatcher->SetMinimumHorizontalDisparity(minhdisp);
+      m_LPBlockMatcher->SetMaximumHorizontalDisparity(maxhdisp);
+      m_LPBlockMatcher->SetMinimumVerticalDisparity(minvdisp);
+      m_LPBlockMatcher->SetMaximumVerticalDisparity(maxvdisp);
+      AddProcess(m_LPBlockMatcher,"Lp block matching");
+
+      if(masking)
+        {
+        m_LPBlockMatcher->SetLeftMaskInput(m_BandMathFilter->GetOutput());
+        }
+      if(useInitialDispUniform)
+        {
+        FloatImageType::SizeType expRadius;
+        expRadius[0] = GetParameterInt("bm.initdisp.uniform.hrad");
+        expRadius[1] = GetParameterInt("bm.initdisp.uniform.vrad");
+        m_LPBlockMatcher->SetExplorationRadius(expRadius);
+        m_LPBlockMatcher->SetInitHorizontalDisparity(GetParameterInt("bm.initdisp.uniform.hdisp"));
+        m_LPBlockMatcher->SetInitVerticalDisparity(GetParameterInt("bm.initdisp.uniform.vdisp"));
+        }
+      if(useInitialDispMap)
+        {
+        FloatImageType::SizeType expRadius;
+        expRadius[0] = GetParameterInt("bm.initdisp.maps.hrad");
+        expRadius[1] = GetParameterInt("bm.initdisp.maps.vrad");
+        m_LPBlockMatcher->SetExplorationRadius(expRadius);
+        m_LPBlockMatcher->SetHorizontalDisparityInput(GetParameterFloatImage("bm.initdisp.maps.hmap"));
+        m_LPBlockMatcher->SetVerticalDisparityInput(GetParameterFloatImage("bm.initdisp.maps.vmap"));
+        }
+
+      hdispImage = m_LPBlockMatcher->GetHorizontalDisparityOutput();
+      vdispImage = m_LPBlockMatcher->GetVerticalDisparityOutput();
+      metricImage = m_LPBlockMatcher->GetMetricOutput();
+      }
     
 
     m_OutputImageList->Clear();
@@ -453,12 +509,15 @@ private:
       }
   }
 
-  // SSD Block matching functor
+  // SSD Block matching filter
   SSDBlockMatchingFilterType::Pointer m_SSDBlockMatcher;
   
-  // NCC Block matching functor
+  // NCC Block matching filter
   NCCBlockMatchingFilterType::Pointer m_NCCBlockMatcher;
   
+  // Lp Block matching filter
+  LPBlockMatchingFilterType::Pointer  m_LPBlockMatcher;
+  
   // Variance filter
   VarianceFilterType::Pointer         m_VarianceFilter;
   
diff --git a/Code/DisparityMap/otbPixelWiseBlockMatchingImageFilter.h b/Code/DisparityMap/otbPixelWiseBlockMatchingImageFilter.h
index 14eb653bde1564c73017c5ba48e123d6d3a91395..315fd2c52808b7117f2155694567a109b1b60ba5 100644
--- a/Code/DisparityMap/otbPixelWiseBlockMatchingImageFilter.h
+++ b/Code/DisparityMap/otbPixelWiseBlockMatchingImageFilter.h
@@ -116,6 +116,57 @@ public:
   }
 };
 
+/** \class LPBlockMatching
+ *  \brief Functor to perform block-matching based on the L^p pseudo-norm
+ *
+ *  This functor is designed to work with the
+ *  PixelWiseBlockMatchingImageFilter. It performs a distance computation between
+ *  two windows based on the L^p pseudo norm (p greater than 0). The functor is
+ *  templated by the type of inputs images and output metric image,
+ *  and is using two neighborhood iterators as inputs.
+ */
+template <class TInputImage, class TOutputMetricImage>
+ITK_EXPORT class LPBlockMatching
+{
+public:
+  typedef itk::ConstNeighborhoodIterator<TInputImage> ConstNeigghborhoodIteratorType;
+  typedef typename TOutputMetricImage::ValueType      MetricValueType;
+  
+  LPBlockMatching(): m_P(0)
+    {
+    }
+  
+  void SetP(double p)
+    {
+    if (p > 0.0)
+      {
+      m_P = p;
+      }
+    else
+      {
+      m_P = 1.0;
+      }
+    }
+  
+  // Implement the Lp metric
+  inline MetricValueType operator()(ConstNeigghborhoodIteratorType & a, ConstNeigghborhoodIteratorType & b) const
+  {
+    MetricValueType score(0); 
+    
+    // For some reason, iterators do not work on neighborhoods
+    for(unsigned int i = 0; i<a.Size(); ++i)
+      {
+      score += vcl_pow( vcl_abs(static_cast<double>(a.GetPixel(i)-b.GetPixel(i))) , m_P);
+      }
+    
+    return score;
+  }
+  
+private:
+  
+  double m_P;
+};
+
 } // End Namespace Functor
 
 /** \class PixelWiseBlockMatchingImageFilter