21 #ifndef otbDisparityMapMedianFilter_hxx
22 #define otbDisparityMapMedianFilter_hxx
24 #ifdef ITK_USE_CONSOLIDATED_MORPHOLOGY
28 #include "itkConstNeighborhoodIterator.h"
29 #include "itkImageRegionIterator.h"
30 #include "itkImageRegionIteratorWithIndex.h"
31 #include "itkNeighborhoodAlgorithm.h"
32 #include "itkProgressReporter.h"
37 template <
class TInputImage,
class TOutputImage,
class TMask>
40 this->SetNumberOfRequiredInputs(1);
41 this->SetNumberOfRequiredOutputs(4);
42 this->SetNthOutput(1, TMask::New());
43 this->SetNthOutput(2, TOutputImage::New());
44 this->SetNthOutput(3, TMask::New());
46 m_IncoherenceThreshold = 1.0;
49 template <
class TInputImage,
class TOutputImage,
class TMask>
53 this->SetNthInput(1,
const_cast<TMask*
>(inputmask));
57 template <
class TInputImage,
class TOutputImage,
class TMask>
60 if (this->GetNumberOfInputs() < 2)
64 return static_cast<const TMask*
>(this->itk::ProcessObject::GetInput(1));
67 template <
class TInputImage,
class TOutputImage,
class TMask>
70 if (this->GetNumberOfOutputs() < 2)
74 return static_cast<TMask*
>(this->itk::ProcessObject::GetOutput(1));
78 template <
class TInputImage,
class TOutputImage,
class TMask>
81 if (this->GetNumberOfOutputs() < 3)
85 return static_cast<TOutputImage*
>(this->itk::ProcessObject::GetOutput(2));
88 template <
class TInputImage,
class TOutputImage,
class TMask>
91 if (this->GetNumberOfOutputs() < 4)
95 return static_cast<TMask*
>(this->itk::ProcessObject::GetOutput(3));
99 template <
class TInputImage,
class TOutputImage,
class TMask>
103 Superclass::GenerateOutputInformation();
106 typename Superclass::InputImagePointer inputPtr =
const_cast<TInputImage*
>(this->GetInput());
107 typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
108 TMask* outputmaskPtr = this->GetOutputMask();
109 typename Superclass::OutputImagePointer outputdisparitymapPtr = this->GetOutputDisparityMap();
110 TMask* outputdisparitymaskPtr = this->GetOutputDisparityMask();
114 SizeType outputSize = largestRegion.GetSize();
117 largestRegion.SetSize(outputSize);
118 outputPtr->SetLargestPossibleRegion(largestRegion);
119 outputmaskPtr->SetLargestPossibleRegion(largestRegion);
120 outputdisparitymapPtr->SetLargestPossibleRegion(largestRegion);
121 outputdisparitymaskPtr->SetLargestPossibleRegion(largestRegion);
125 template <
class TInputImage,
class TOutputImage,
class TMask>
129 Superclass::GenerateInputRequestedRegion();
132 typename Superclass::InputImagePointer inputPtr =
const_cast<TInputImage*
>(this->GetInput());
133 TMask* inputmaskPtr =
const_cast<TMask*
>(this->GetMaskInput());
134 typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
135 TMask* outputmaskPtr = this->GetOutputMask();
136 typename Superclass::OutputImagePointer outputdisparitymapPtr = this->GetOutputDisparityMap();
137 TMask* outputdisparitymaskPtr = this->GetOutputDisparityMask();
139 if (!inputPtr || !outputPtr || !outputmaskPtr || !outputdisparitymapPtr || !outputdisparitymaskPtr)
147 if (inputmaskPtr->GetLargestPossibleRegion() != inputPtr->GetLargestPossibleRegion())
149 itkExceptionMacro(<<
"Input image and mask image don't have the same size ! Input image :" << inputPtr->GetLargestPossibleRegion()
150 <<
"; Mask image :" << inputmaskPtr->GetLargestPossibleRegion());
156 typename TInputImage::RegionType inputRequestedRegion;
157 inputRequestedRegion = inputPtr->GetRequestedRegion();
160 inputRequestedRegion.PadByRadius(m_Radius);
163 if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
165 inputPtr->SetRequestedRegion(inputRequestedRegion);
168 inputmaskPtr->SetRequestedRegion(inputRequestedRegion);
179 inputPtr->SetRequestedRegion(inputRequestedRegion);
182 itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
183 e.SetLocation(ITK_LOCATION);
184 e.SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
185 e.SetDataObject(inputPtr);
191 template <
class TInputImage,
class TOutputImage,
class TMask>
195 this->AllocateOutputs();
198 typename OutputImageType::Pointer output = this->GetOutput();
199 typename InputImageType::ConstPointer input = this->GetInput();
200 typename MaskImageType::ConstPointer inputmaskPtr = this->GetMaskInput();
201 TMask* outputmaskPtr = this->GetOutputMask();
202 TOutputImage* outputdisparitymapPtr = this->GetOutputDisparityMap();
203 TMask* outputdisparitymaskPtr = this->GetOutputDisparityMask();
205 SizeType imgSize = output->GetLargestPossibleRegion().GetSize();
208 itk::ConstNeighborhoodIterator<InputImageType> InputIt(m_Radius, input, input->GetRequestedRegion());
209 itk::ConstNeighborhoodIterator<TMask> MaskInputIt;
212 MaskInputIt.Initialize(m_Radius, inputmaskPtr, inputmaskPtr->GetRequestedRegion());
217 itk::ImageRegionIteratorWithIndex<OutputImageType> outputIt(output, output->GetRequestedRegion());
218 itk::ImageRegionIterator<TMask> outputMaskIt(outputmaskPtr, output->GetRequestedRegion());
219 itk::ImageRegionIterator<OutputImageType> outputDisparityMapIt(outputdisparitymapPtr, output->GetRequestedRegion());
220 itk::ImageRegionIterator<TMask> outputDisparityMaskIt(outputdisparitymaskPtr, output->GetRequestedRegion());
221 outputIt.GoToBegin();
222 outputMaskIt.GoToBegin();
223 outputDisparityMapIt.GoToBegin();
224 outputDisparityMaskIt.GoToBegin();
227 std::vector<InputPixelType> pixels;
228 while (!outputIt.IsAtEnd() && !outputMaskIt.IsAtEnd() && !outputDisparityMapIt.IsAtEnd() && !outputDisparityMapIt.IsAtEnd())
230 if (outputIt.GetIndex()[0] >=
static_cast<IndexValueType>(m_Radius[0]) &&
232 outputIt.GetIndex()[1] >=
static_cast<IndexValueType>(m_Radius[1]) &&
240 MaskInputIt.SetLocation(outputIt.GetIndex());
242 InputIt.SetLocation(outputIt.GetIndex());
243 for (
unsigned int i = 0; i < InputIt.Size(); i++)
245 if (!inputmaskPtr || (MaskInputIt.GetPixel(i) != 0))
248 pixels.push_back(InputIt.GetPixel(i));
258 const unsigned int medianPosition_low = p / 2 - 1;
259 const unsigned int medianPosition_high = p / 2;
260 const typename std::vector<InputPixelType>::iterator medianIterator_low = pixels.begin() + medianPosition_low;
261 const typename std::vector<InputPixelType>::iterator medianIterator_high = pixels.begin() + medianPosition_high;
262 std::nth_element(pixels.begin(), medianIterator_low, pixels.end());
263 std::nth_element(pixels.begin(), medianIterator_high, pixels.end());
264 outputIt.Set(
static_cast<typename OutputImageType::PixelType
>((*medianIterator_low + *medianIterator_high) / 2));
268 const unsigned int medianPosition = p / 2;
269 const typename std::vector<InputPixelType>::iterator medianIterator = pixels.begin() + medianPosition;
270 std::nth_element(pixels.begin(), medianIterator, pixels.end());
271 outputIt.Set(
static_cast<typename OutputImageType::PixelType
>(*medianIterator));
286 outputDisparityMapIt.Set(
static_cast<typename OutputImageType::PixelType
>(InputIt.GetCenterPixel()));
290 outputDisparityMaskIt.Set(MaskInputIt.GetCenterPixel());
294 outputDisparityMaskIt.Set(1);
299 ++outputDisparityMapIt;
300 ++outputDisparityMaskIt;
306 image_aux->SetRegions(input->GetRequestedRegion());
307 image_aux->Allocate();
308 image_aux->FillBuffer(0);
309 itk::NeighborhoodIterator<TMask> image_aux_It(m_Radius, image_aux, input->GetRequestedRegion());
310 outputIt.GoToBegin();
311 outputMaskIt.GoToBegin();
313 itk::ImageRegionConstIterator<OutputImageType> MedianIt(output, output->GetRequestedRegion());
315 while (!outputIt.IsAtEnd() && !outputMaskIt.IsAtEnd())
317 if (outputIt.GetIndex()[0] >=
static_cast<IndexValueType>(m_Radius[0]) &&
319 outputIt.GetIndex()[1] >=
static_cast<IndexValueType>(m_Radius[1]) &&
322 InputIt.SetLocation(outputIt.GetIndex());
323 MedianIt.SetIndex(outputIt.GetIndex());
324 outputDisparityMapIt.SetIndex(outputIt.GetIndex());
325 outputDisparityMaskIt.SetIndex(outputIt.GetIndex());
326 image_aux_It.SetLocation(outputIt.GetIndex());
329 MaskInputIt.SetLocation(outputIt.GetIndex());
332 if ((!inputmaskPtr || (MaskInputIt.GetCenterPixel() != 0)) && std::fabs(InputIt.GetCenterPixel() - MedianIt.Get()) > m_IncoherenceThreshold)
334 outputDisparityMapIt.Set(0.0);
335 outputDisparityMaskIt.Set(0);
336 for (
unsigned int i = 0; i < image_aux_It.Size(); i++)
338 image_aux_It.SetPixel(i, 1);
348 itk::ConstNeighborhoodIterator<OutputImageType> updatedDisparityMapIt(m_Radius, outputdisparitymapPtr, output->GetRequestedRegion());
349 itk::ConstNeighborhoodIterator<TMask> updatedDisparityMaskIt(m_Radius, outputdisparitymaskPtr, output->GetRequestedRegion());
351 outputIt.GoToBegin();
352 outputMaskIt.GoToBegin();
353 updatedDisparityMapIt.GoToBegin();
354 updatedDisparityMaskIt.GoToBegin();
356 while (!updatedDisparityMapIt.IsAtEnd() && !updatedDisparityMaskIt.IsAtEnd() && !outputIt.IsAtEnd() && !outputMaskIt.IsAtEnd())
358 if (outputIt.GetIndex()[0] >=
static_cast<IndexValueType>(m_Radius[0]) &&
360 outputIt.GetIndex()[1] >=
static_cast<IndexValueType>(m_Radius[1]) &&
363 image_aux_It.SetLocation(outputIt.GetIndex());
364 if (image_aux_It.GetCenterPixel() != 0)
369 for (
unsigned int i = 0; i < updatedDisparityMaskIt.Size(); i++)
371 if (updatedDisparityMaskIt.GetPixel(i) != 0)
374 pixels.push_back(updatedDisparityMapIt.GetPixel(i));
384 const unsigned int medianPosition_low = p / 2 - 1;
385 const unsigned int medianPosition_high = p / 2;
386 const typename std::vector<InputPixelType>::iterator medianIterator_low = pixels.begin() + medianPosition_low;
387 const typename std::vector<InputPixelType>::iterator medianIterator_high = pixels.begin() + medianPosition_high;
388 std::nth_element(pixels.begin(), medianIterator_low, pixels.end());
389 std::nth_element(pixels.begin(), medianIterator_high, pixels.end());
390 outputIt.Set(
static_cast<typename OutputImageType::PixelType
>((*medianIterator_low + *medianIterator_high) / 2));
394 const unsigned int medianPosition = p / 2;
395 const typename std::vector<InputPixelType>::iterator medianIterator = pixels.begin() + medianPosition;
396 std::nth_element(pixels.begin(), medianIterator, pixels.end());
397 outputIt.Set(
static_cast<typename OutputImageType::PixelType
>(*medianIterator));
409 ++updatedDisparityMapIt;
410 ++updatedDisparityMaskIt;
418 template <
class TInputImage,
class TOutput,
class TMask>
421 Superclass::PrintSelf(os, indent);
422 os << indent <<
"Radius: " << m_Radius << std::endl;