Skip to content
Snippets Groups Projects
Commit 7b18aced authored by Guillaume Pasero's avatar Guillaume Pasero
Browse files

ENH: in PixelWiseBlockMatching : add Lp pseudo-norm

parent bb68fa30
No related branches found
No related tags found
No related merge requests found
......@@ -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;
......
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment