21 #ifndef otbSubPixelDisparityImageFilter_hxx
22 #define otbSubPixelDisparityImageFilter_hxx
28 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
31 this->DynamicMultiThreadingOff();
33 this->SetNumberOfRequiredInputs(3);
36 this->SetNumberOfRequiredOutputs(3);
37 this->SetNthOutput(0, TDisparityImage::New());
38 this->SetNthOutput(1, TDisparityImage::New());
39 this->SetNthOutput(2, TOutputMetricImage::New());
48 m_MinimumHorizontalDisparity = -10;
49 m_MaximumHorizontalDisparity = 10;
50 m_MinimumVerticalDisparity = 0;
51 m_MaximumVerticalDisparity = 0;
64 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
69 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
73 this->SetNthInput(0,
const_cast<TInputImage*
>(image));
76 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
80 this->SetNthInput(1,
const_cast<TInputImage*
>(image));
83 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
85 const TDisparityImage* hfield)
88 this->SetNthInput(2,
const_cast<TDisparityImage*
>(hfield));
91 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
93 const TDisparityImage* vfield)
96 this->SetNthInput(3,
const_cast<TDisparityImage*
>(vfield));
99 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
101 const TMaskImage* image)
104 this->SetNthInput(4,
const_cast<TMaskImage*
>(image));
107 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
109 const TMaskImage* image)
112 this->SetNthInput(5,
const_cast<TMaskImage*
>(image));
115 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
117 const TOutputMetricImage* image)
120 this->SetNthInput(6,
const_cast<TOutputMetricImage*
>(image));
123 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
126 if (this->GetNumberOfIndexedInputs() < 1)
130 return static_cast<const TInputImage*
>(this->itk::ProcessObject::GetInput(0));
133 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
136 if (this->GetNumberOfIndexedInputs() < 2)
140 return static_cast<const TInputImage*
>(this->itk::ProcessObject::GetInput(1));
143 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
144 const TDisparityImage*
147 if (this->GetNumberOfIndexedInputs() < 3)
151 return static_cast<const TDisparityImage*
>(this->itk::ProcessObject::GetInput(2));
154 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
155 const TDisparityImage*
158 if (this->GetNumberOfIndexedInputs() < 4)
162 return static_cast<const TDisparityImage*
>(this->itk::ProcessObject::GetInput(3));
165 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
168 if (this->GetNumberOfIndexedInputs() < 5)
172 return static_cast<const TMaskImage*
>(this->itk::ProcessObject::GetInput(4));
175 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
178 if (this->GetNumberOfIndexedInputs() < 6)
182 return static_cast<const TMaskImage*
>(this->itk::ProcessObject::GetInput(5));
185 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
186 const TDisparityImage*
189 if (this->GetNumberOfOutputs() < 1)
193 return static_cast<const TDisparityImage*
>(this->itk::ProcessObject::GetOutput(0));
196 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
200 if (this->GetNumberOfOutputs() < 1)
204 return static_cast<TDisparityImage*
>(this->itk::ProcessObject::GetOutput(0));
207 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
208 const TDisparityImage*
211 if (this->GetNumberOfOutputs() < 2)
215 return static_cast<const TDisparityImage*
>(this->itk::ProcessObject::GetOutput(1));
218 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
221 if (this->GetNumberOfOutputs() < 2)
225 return static_cast<TDisparityImage*
>(this->itk::ProcessObject::GetOutput(1));
228 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
229 const TOutputMetricImage*
232 if (this->GetNumberOfOutputs() < 3)
236 return static_cast<const TOutputMetricImage*
>(this->itk::ProcessObject::GetOutput(2));
239 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
242 if (this->GetNumberOfOutputs() < 3)
246 return static_cast<TOutputMetricImage*
>(this->itk::ProcessObject::GetOutput(2));
249 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
286 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
290 const TInputImage* inLeftPtr = this->GetLeftInput();
291 const TInputImage* inRightPtr = this->GetRightInput();
292 const TMaskImage* inLeftMaskPtr = this->GetLeftMaskInput();
293 const TMaskImage* inRightMaskPtr = this->GetRightMaskInput();
294 const TDisparityImage* inHDispPtr = this->GetHorizontalDisparityInput();
295 const TDisparityImage* inVDispPtr = this->GetVerticalDisparityInput();
298 if (!inLeftPtr || !inRightPtr)
300 itkExceptionMacro(<<
"Missing input, need left and right input images.");
305 itkExceptionMacro(<<
"Input horizontal disparity map is missing");
309 if (inLeftPtr->GetLargestPossibleRegion() != inRightPtr->GetLargestPossibleRegion())
311 itkExceptionMacro(<<
"Left and right images do not have the same size ! Left largest region: " << inLeftPtr->GetLargestPossibleRegion()
312 <<
", right largest region: " << inRightPtr->GetLargestPossibleRegion());
316 if (inLeftMaskPtr && inLeftPtr->GetLargestPossibleRegion() != inLeftMaskPtr->GetLargestPossibleRegion())
318 itkExceptionMacro(<<
"Left and mask images do not have the same size ! Left largest region: " << inLeftPtr->GetLargestPossibleRegion()
319 <<
", mask largest region: " << inLeftMaskPtr->GetLargestPossibleRegion());
323 if (inRightMaskPtr && inRightPtr->GetLargestPossibleRegion() != inRightMaskPtr->GetLargestPossibleRegion())
325 itkExceptionMacro(<<
"Right and mask images do not have the same size ! Right largest region: " << inRightPtr->GetLargestPossibleRegion()
326 <<
", mask largest region: " << inRightMaskPtr->GetLargestPossibleRegion());
330 if (inHDispPtr && inVDispPtr && inHDispPtr->GetLargestPossibleRegion() != inVDispPtr->GetLargestPossibleRegion())
332 itkExceptionMacro(<<
"Initial horizontal and vertical disparity maps don't have the same size ! Horizontal disparity largest region: "
333 << inHDispPtr->GetLargestPossibleRegion() <<
", vertical disparity largest region: " << inVDispPtr->GetLargestPossibleRegion());
337 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
341 const TInputImage* inLeftPtr = this->GetLeftInput();
342 const TDisparityImage* inHDispPtr = this->GetHorizontalDisparityInput();
344 TOutputMetricImage* outMetricPtr = this->GetMetricOutput();
345 TDisparityImage* outHDispPtr = this->GetHorizontalDisparityOutput();
346 TDisparityImage* outVDispPtr = this->GetVerticalDisparityOutput();
348 outMetricPtr->CopyInformation(inHDispPtr);
349 outHDispPtr->CopyInformation(inHDispPtr);
350 outVDispPtr->CopyInformation(inHDispPtr);
353 SpacingType leftSpacing = inLeftPtr->GetSignedSpacing();
354 SpacingType dispSpacing = inHDispPtr->GetSignedSpacing();
355 PointType leftOrigin = inLeftPtr->GetOrigin();
356 PointType dispOrigin = inHDispPtr->GetOrigin();
358 double ratioX = dispSpacing[0] / leftSpacing[0];
359 double ratioY = dispSpacing[1] / leftSpacing[1];
360 int stepX =
static_cast<int>(std::floor(ratioX + 0.5));
361 int stepY =
static_cast<int>(std::floor(ratioY + 0.5));
362 if (stepX < 1 || stepY < 1 || stepX != stepY)
364 itkExceptionMacro(<<
"Incompatible spacing values between disparity map and input image. Left spacing: " << leftSpacing
365 <<
", disparity spacing: " << dispSpacing);
367 this->m_Step =
static_cast<unsigned int>(stepX);
369 double shiftX = (dispOrigin[0] - leftOrigin[0]) / leftSpacing[0];
370 double shiftY = (dispOrigin[1] - leftOrigin[1]) / leftSpacing[1];
371 this->m_GridIndex[0] =
static_cast<typename IndexType::IndexValueType
>(std::floor(shiftX + 0.5));
372 this->m_GridIndex[1] =
static_cast<typename IndexType::IndexValueType
>(std::floor(shiftY + 0.5));
375 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
379 Superclass::GenerateInputRequestedRegion();
382 TInputImage* inLeftPtr =
const_cast<TInputImage*
>(this->GetLeftInput());
383 TInputImage* inRightPtr =
const_cast<TInputImage*
>(this->GetRightInput());
384 TMaskImage* inLeftMaskPtr =
const_cast<TMaskImage*
>(this->GetLeftMaskInput());
385 TMaskImage* inRightMaskPtr =
const_cast<TMaskImage*
>(this->GetRightMaskInput());
386 TDisparityImage* inHDispPtr =
const_cast<TDisparityImage*
>(this->GetHorizontalDisparityInput());
387 TDisparityImage* inVDispPtr =
const_cast<TDisparityImage*
>(this->GetVerticalDisparityInput());
389 TDisparityImage* outHDispPtr = this->GetHorizontalDisparityOutput();
393 RegionType outputRequestedRegion = outHDispPtr->GetRequestedRegion();
394 RegionType fullRequestedRegion = BlockMatchingFilterType::ConvertSubsampledToFullRegion(outputRequestedRegion, this->m_Step, this->m_GridIndex);
397 RegionType inputLeftRegion = fullRequestedRegion;
398 inputLeftRegion.PadByRadius(m_Radius);
401 IndexType rightRequestedRegionIndex = fullRequestedRegion.GetIndex();
402 rightRequestedRegionIndex[0] += m_MinimumHorizontalDisparity;
403 rightRequestedRegionIndex[1] += m_MinimumVerticalDisparity;
405 SizeType rightRequestedRegionSize = fullRequestedRegion.GetSize();
406 rightRequestedRegionSize[0] += m_MaximumHorizontalDisparity - m_MinimumHorizontalDisparity;
407 rightRequestedRegionSize[1] += m_MaximumVerticalDisparity - m_MinimumVerticalDisparity;
410 inputRightRegion.SetIndex(rightRequestedRegionIndex);
411 inputRightRegion.SetSize(rightRequestedRegionSize);
413 RegionType inputRightMaskRegion = inputRightRegion;
415 inputRightRegion.PadByRadius(m_Radius);
418 if (inputLeftRegion.Crop(inLeftPtr->GetLargestPossibleRegion()))
420 inLeftPtr->SetRequestedRegion(inputLeftRegion);
427 inLeftPtr->SetRequestedRegion(inputLeftRegion);
430 itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
431 std::ostringstream msg;
432 msg << this->GetNameOfClass() <<
"::GenerateInputRequestedRegion()";
433 e.SetLocation(msg.str());
434 e.SetDescription(
"Requested region is (at least partially) outside the largest possible region of left image.");
435 e.SetDataObject(inLeftPtr);
441 if (inputRightRegion.Crop(inRightPtr->GetLargestPossibleRegion()))
443 inRightPtr->SetRequestedRegion(inputRightRegion);
444 inputRightMaskRegion.Crop(inRightPtr->GetLargestPossibleRegion());
450 inputRightRegion.SetIndex(inRightPtr->GetLargestPossibleRegion().GetIndex());
451 inputRightRegion.SetSize(0, 0);
452 inputRightRegion.SetSize(1, 0);
453 inRightPtr->SetRequestedRegion(inputRightRegion);
454 inputRightMaskRegion = inputRightRegion;
476 inLeftMaskPtr->SetRequestedRegion(fullRequestedRegion);
481 inRightMaskPtr->SetRequestedRegion(inputRightMaskRegion);
486 inHDispPtr->SetRequestedRegion(outputRequestedRegion);
491 inVDispPtr->SetRequestedRegion(outputRequestedRegion);
495 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
498 TOutputMetricImage* outMetricPtr = this->GetMetricOutput();
499 TDisparityImage* outHDispPtr = this->GetHorizontalDisparityOutput();
500 TDisparityImage* outVDispPtr = this->GetVerticalDisparityOutput();
503 outMetricPtr->FillBuffer(0.);
507 m_WrongExtrema.resize(this->GetNumberOfWorkUnits());
510 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
512 const RegionType& outputRegionForThread, itk::ThreadIdType threadId)
515 switch (m_RefineMethod)
519 ParabolicRefinement(outputRegionForThread, threadId);
524 TriangularRefinement(outputRegionForThread, threadId);
529 DichotomyRefinement(outputRegionForThread, threadId);
536 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
538 const RegionType& outputRegionForThread, itk::ThreadIdType threadId)
541 const TInputImage* inLeftPtr = this->GetLeftInput();
542 const TInputImage* inRightPtr = this->GetRightInput();
543 const TMaskImage* inLeftMaskPtr = this->GetLeftMaskInput();
544 const TMaskImage* inRightMaskPtr = this->GetRightMaskInput();
545 const TDisparityImage* inHDispPtr = this->GetHorizontalDisparityInput();
546 const TDisparityImage* inVDispPtr = this->GetVerticalDisparityInput();
547 TOutputMetricImage* outMetricPtr = this->GetMetricOutput();
548 TDisparityImage* outHDispPtr = this->GetHorizontalDisparityOutput();
549 TDisparityImage* outVDispPtr = this->GetVerticalDisparityOutput();
551 unsigned int nb_WrongExtrema = 0;
555 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels(), 100);
557 RegionType fullRegionForThread = BlockMatchingFilterType::ConvertSubsampledToFullRegion(outputRegionForThread, this->m_Step, this->m_GridIndex);
559 itk::ConstNeighborhoodIterator<TInputImage> leftIt(m_Radius, inLeftPtr, fullRegionForThread);
560 itk::ImageRegionIterator<TDisparityImage> outHDispIt(outHDispPtr, outputRegionForThread);
561 itk::ImageRegionIterator<TDisparityImage> outVDispIt(outVDispPtr, outputRegionForThread);
562 itk::ImageRegionIterator<TOutputMetricImage> outMetricIt(outMetricPtr, outputRegionForThread);
563 itk::ImageRegionConstIterator<TDisparityImage> inHDispIt;
564 itk::ImageRegionConstIterator<TDisparityImage> inVDispIt;
565 itk::ImageRegionConstIterator<TMaskImage> inLeftMaskIt;
566 itk::ImageRegionConstIterator<TMaskImage> inRightMaskIt;
568 bool useHorizontalDisparity =
false;
569 bool useVerticalDisparity =
false;
573 useHorizontalDisparity =
true;
574 inHDispIt = itk::ImageRegionConstIterator<TDisparityImage>(inHDispPtr, outputRegionForThread);
575 inHDispIt.GoToBegin();
579 useVerticalDisparity =
true;
580 inVDispIt = itk::ImageRegionConstIterator<TDisparityImage>(inVDispPtr, outputRegionForThread);
581 inVDispIt.GoToBegin();
586 inLeftMaskIt = itk::ImageRegionConstIterator<TMaskImage>(inLeftMaskPtr, fullRegionForThread);
587 inLeftMaskIt.GoToBegin();
589 RegionType rightBufferedRegion = inRightPtr->GetBufferedRegion();
592 RegionType inRightMaskRegion = inRightMaskPtr->GetBufferedRegion();
593 inRightMaskIt = itk::ImageRegionConstIterator<TMaskImage>(inRightMaskPtr, inRightMaskRegion);
596 itk::ConstantBoundaryCondition<TInputImage> nbc1;
597 leftIt.OverrideBoundaryCondition(&nbc1);
600 outHDispIt.GoToBegin();
601 outVDispIt.GoToBegin();
602 outMetricIt.GoToBegin();
614 bool horizontalInterpolation =
false;
615 bool verticalInterpolation =
false;
617 typename ResamplerFilterType::Pointer resampler;
624 double neighborsMetric[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
626 while (!leftIt.IsAtEnd() || !outHDispIt.IsAtEnd() || !outVDispIt.IsAtEnd() || !outMetricIt.IsAtEnd())
629 curLeftPos = leftIt.GetIndex();
630 if (((curLeftPos[0] - this->m_GridIndex[0] + this->m_Step) % this->m_Step == 0) &&
631 ((curLeftPos[1] - this->m_GridIndex[1] + this->m_Step) % this->m_Step == 0))
633 horizontalInterpolation =
false;
634 verticalInterpolation =
false;
637 if (useHorizontalDisparity)
639 hDisp_f =
static_cast<float>(inHDispIt.Get()) * stepDisparity;
640 hDisp_i =
static_cast<int>(std::floor(hDisp_f + 0.5));
641 curRightPos[0] = curLeftPos[0] + hDisp_i;
646 curRightPos[0] = curLeftPos[0];
650 if (useVerticalDisparity)
652 vDisp_f =
static_cast<float>(inVDispIt.Get()) * stepDisparity;
653 vDisp_i =
static_cast<int>(std::floor(vDisp_f + 0.5));
654 curRightPos[1] = curLeftPos[1] + vDisp_i;
659 curRightPos[1] = curLeftPos[1];
663 if (rightBufferedRegion.IsInside(curRightPos))
668 inRightMaskIt.SetIndex(curRightPos);
671 if (!inLeftMaskPtr || (inLeftMaskIt.Get() > 0))
673 if (!inRightMaskPtr || (inRightMaskIt.Get() > 0))
676 smallRightRegion.SetIndex(0, curRightPos[0] - 1);
677 smallRightRegion.SetIndex(1, curRightPos[1] - 1);
678 smallRightRegion.SetSize(0, 3);
679 smallRightRegion.SetSize(1, 3);
681 itk::ConstNeighborhoodIterator<TInputImage> rightIt(m_Radius, inRightPtr, smallRightRegion);
682 itk::ConstantBoundaryCondition<TInputImage> nbc2;
683 rightIt.OverrideBoundaryCondition(&nbc2);
686 rightIt.SetLocation(curRightPos);
687 neighborsMetric[1][1] = m_Functor(leftIt, rightIt);
689 if (m_MinimumVerticalDisparity < vDisp_i && vDisp_i < m_MaximumVerticalDisparity)
695 if (rightBufferedRegion.IsInside(upIndex) && rightBufferedRegion.IsInside(downIndex))
697 rightIt.SetLocation(upIndex);
698 neighborsMetric[1][0] = m_Functor(leftIt, rightIt);
700 rightIt.SetLocation(downIndex);
701 neighborsMetric[1][2] = m_Functor(leftIt, rightIt);
706 if (neighborsMetric[1][1] < neighborsMetric[1][0] && neighborsMetric[1][1] < neighborsMetric[1][2])
708 verticalInterpolation =
true;
713 if (neighborsMetric[1][1] > neighborsMetric[1][0] && neighborsMetric[1][1] > neighborsMetric[1][2])
715 verticalInterpolation =
true;
721 if (m_MinimumHorizontalDisparity < hDisp_i && hDisp_i < m_MaximumHorizontalDisparity)
724 leftIndex[0] += (-1);
727 if (rightBufferedRegion.IsInside(leftIndex) && rightBufferedRegion.IsInside(rightIndex))
729 rightIt.SetLocation(rightIndex);
730 neighborsMetric[2][1] = m_Functor(leftIt, rightIt);
732 rightIt.SetLocation(leftIndex);
733 neighborsMetric[0][1] = m_Functor(leftIt, rightIt);
738 if (neighborsMetric[1][1] < neighborsMetric[0][1] && neighborsMetric[1][1] < neighborsMetric[2][1])
740 horizontalInterpolation =
true;
745 if (neighborsMetric[1][1] > neighborsMetric[0][1] && neighborsMetric[1][1] > neighborsMetric[2][1])
747 horizontalInterpolation =
true;
754 if (verticalInterpolation && horizontalInterpolation)
757 uprightIndex[0] += 1;
758 uprightIndex[1] += (-1);
759 rightIt.SetLocation(uprightIndex);
760 neighborsMetric[2][0] = m_Functor(leftIt, rightIt);
763 downrightIndex[0] += 1;
764 downrightIndex[1] += 1;
765 rightIt.SetLocation(downrightIndex);
766 neighborsMetric[2][2] = m_Functor(leftIt, rightIt);
769 downleftIndex[0] += (-1);
770 downleftIndex[1] += 1;
771 rightIt.SetLocation(downleftIndex);
772 neighborsMetric[0][2] = m_Functor(leftIt, rightIt);
775 upleftIndex[0] += (-1);
776 upleftIndex[1] += (-1);
777 rightIt.SetLocation(upleftIndex);
778 neighborsMetric[0][0] = m_Functor(leftIt, rightIt);
783 if (neighborsMetric[1][1] > neighborsMetric[2][0] || neighborsMetric[1][1] > neighborsMetric[2][2] ||
784 neighborsMetric[1][1] > neighborsMetric[0][2] || neighborsMetric[1][1] > neighborsMetric[0][0])
786 verticalInterpolation =
false;
787 horizontalInterpolation =
false;
792 if (neighborsMetric[1][1] < neighborsMetric[2][0] || neighborsMetric[1][1] < neighborsMetric[2][2] ||
793 neighborsMetric[1][1] < neighborsMetric[0][2] || neighborsMetric[1][1] < neighborsMetric[0][0])
795 verticalInterpolation =
false;
796 horizontalInterpolation =
false;
805 if (verticalInterpolation && !horizontalInterpolation)
808 double deltaV = 0.5 - (1.0 / (1.0 + (neighborsMetric[1][0] - neighborsMetric[1][1]) / (neighborsMetric[1][2] - neighborsMetric[1][1])));
809 if (deltaV > (-0.5) && deltaV < 0.5)
811 outVDispIt.Set((
static_cast<double>(vDisp_i) + deltaV) * stepDisparityInv);
815 verticalInterpolation =
false;
818 else if (!verticalInterpolation && horizontalInterpolation)
821 double deltaH = 0.5 - (1.0 / (1.0 + (neighborsMetric[0][1] - neighborsMetric[1][1]) / (neighborsMetric[2][1] - neighborsMetric[1][1])));
822 if (deltaH > (-0.5) && deltaH < 0.5)
824 outHDispIt.Set((
static_cast<double>(hDisp_i) + deltaH) * stepDisparityInv);
828 horizontalInterpolation =
false;
831 else if (verticalInterpolation && horizontalInterpolation)
834 double dx = 0.5 * (neighborsMetric[2][1] - neighborsMetric[0][1]);
835 double dy = 0.5 * (neighborsMetric[1][2] - neighborsMetric[1][0]);
836 double dxx = neighborsMetric[2][1] + neighborsMetric[0][1] - 2.0 * neighborsMetric[1][1];
837 double dyy = neighborsMetric[1][2] + neighborsMetric[1][0] - 2.0 * neighborsMetric[1][1];
838 double dxy = 0.25 * (neighborsMetric[2][2] + neighborsMetric[0][0] - neighborsMetric[0][2] - neighborsMetric[2][0]);
839 double det = dxx * dyy - dxy * dxy;
840 if (std::abs(det) < (1e-10))
842 verticalInterpolation =
false;
843 horizontalInterpolation =
false;
847 double deltaH = (-dx * dyy + dy * dxy) / det;
848 double deltaV = (dx * dxy - dy * dxx) / det;
849 if (deltaH > (-1.0) && deltaH < 1.0 && deltaV > (-1.0) && deltaV < 1.0)
851 outHDispIt.Set((
static_cast<double>(hDisp_i) + deltaH) * stepDisparityInv);
852 outVDispIt.Set((
static_cast<double>(vDisp_i) + deltaV) * stepDisparityInv);
856 verticalInterpolation =
false;
857 horizontalInterpolation =
false;
862 if (!verticalInterpolation)
865 outVDispIt.Set(
static_cast<double>(vDisp_i) * stepDisparityInv);
868 if (!horizontalInterpolation)
871 outHDispIt.Set(
static_cast<double>(hDisp_i) * stepDisparityInv);
874 if (!verticalInterpolation && !horizontalInterpolation)
877 outMetricIt.Set(
static_cast<double>(neighborsMetric[1][1]));
882 typename TInputImage::Pointer fakeRightPtr = TInputImage::New();
883 fakeRightPtr->SetRegions(rightBufferedRegion);
884 fakeRightPtr->SetPixelContainer((
const_cast<TInputImage*
>(inRightPtr))->GetPixelContainer());
886 itk::ConstNeighborhoodIterator<TInputImage> shiftedIt;
887 itk::ConstantBoundaryCondition<TInputImage> nbc3;
888 shiftedIt.OverrideBoundaryCondition(&nbc3);
891 windowSize[0] = 2 * m_Radius[0] + 1;
892 windowSize[1] = 2 * m_Radius[1] + 1;
895 upleftCorner[0] = curRightPos[0] - m_Radius[0];
896 upleftCorner[1] = curRightPos[1] - m_Radius[1];
898 TransformationType::Pointer transfo = TransformationType::New();
899 TransformationType::OutputVectorType offsetTransfo(2);
902 tinyShiftedRegion.SetSize(0, 1);
903 tinyShiftedRegion.SetSize(1, 1);
904 tinyShiftedRegion.SetIndex(0, curRightPos[0]);
905 tinyShiftedRegion.SetIndex(1, curRightPos[1]);
907 resampler = ResamplerFilterType::New();
908 resampler->SetInput(fakeRightPtr);
909 resampler->SetSize(windowSize);
910 resampler->SetNumberOfWorkUnits(1);
911 resampler->SetTransform(transfo);
912 resampler->SetOutputStartIndex(upleftCorner);
914 offsetTransfo[0] = outHDispIt.Get() * stepDisparity -
static_cast<double>(hDisp_i);
915 offsetTransfo[1] = outVDispIt.Get() * stepDisparity -
static_cast<double>(vDisp_i);
916 transfo->SetOffset(offsetTransfo);
917 resampler->Modified();
919 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
920 outMetricIt.Set(m_Functor(leftIt, shiftedIt));
922 if ((outMetricIt.Get() > neighborsMetric[1][1] && m_Minimize) || (outMetricIt.Get() < neighborsMetric[1][1] && !m_Minimize))
928 progress.CompletedPixel();
932 if (useHorizontalDisparity)
936 if (useVerticalDisparity)
950 m_WrongExtrema[threadId] =
static_cast<double>(nb_WrongExtrema) /
static_cast<double>(outputRegionForThread.GetNumberOfPixels());
953 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
955 const RegionType& outputRegionForThread, itk::ThreadIdType threadId)
958 const TInputImage* inLeftPtr = this->GetLeftInput();
959 const TInputImage* inRightPtr = this->GetRightInput();
960 const TMaskImage* inLeftMaskPtr = this->GetLeftMaskInput();
961 const TMaskImage* inRightMaskPtr = this->GetRightMaskInput();
962 const TDisparityImage* inHDispPtr = this->GetHorizontalDisparityInput();
963 const TDisparityImage* inVDispPtr = this->GetVerticalDisparityInput();
964 TOutputMetricImage* outMetricPtr = this->GetMetricOutput();
965 TDisparityImage* outHDispPtr = this->GetHorizontalDisparityOutput();
966 TDisparityImage* outVDispPtr = this->GetVerticalDisparityOutput();
968 unsigned int nb_WrongExtrema = 0;
972 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels(), 100);
974 RegionType fullRegionForThread = BlockMatchingFilterType::ConvertSubsampledToFullRegion(outputRegionForThread, this->m_Step, this->m_GridIndex);
976 itk::ConstNeighborhoodIterator<TInputImage> leftIt(m_Radius, inLeftPtr, fullRegionForThread);
977 itk::ImageRegionIterator<TDisparityImage> outHDispIt(outHDispPtr, outputRegionForThread);
978 itk::ImageRegionIterator<TDisparityImage> outVDispIt(outVDispPtr, outputRegionForThread);
979 itk::ImageRegionIterator<TOutputMetricImage> outMetricIt(outMetricPtr, outputRegionForThread);
980 itk::ImageRegionConstIterator<TDisparityImage> inHDispIt;
981 itk::ImageRegionConstIterator<TDisparityImage> inVDispIt;
982 itk::ImageRegionConstIterator<TMaskImage> inLeftMaskIt;
983 itk::ImageRegionConstIterator<TMaskImage> inRightMaskIt;
985 bool useHorizontalDisparity =
false;
986 bool useVerticalDisparity =
false;
990 useHorizontalDisparity =
true;
991 inHDispIt = itk::ImageRegionConstIterator<TDisparityImage>(inHDispPtr, outputRegionForThread);
992 inHDispIt.GoToBegin();
996 useVerticalDisparity =
true;
997 inVDispIt = itk::ImageRegionConstIterator<TDisparityImage>(inVDispPtr, outputRegionForThread);
998 inVDispIt.GoToBegin();
1003 inLeftMaskIt = itk::ImageRegionConstIterator<TMaskImage>(inLeftMaskPtr, fullRegionForThread);
1004 inLeftMaskIt.GoToBegin();
1006 RegionType rightBufferedRegion = inRightPtr->GetBufferedRegion();
1009 RegionType inRightMaskRegion = inRightMaskPtr->GetBufferedRegion();
1010 inRightMaskIt = itk::ImageRegionConstIterator<TMaskImage>(inRightMaskPtr, inRightMaskRegion);
1013 itk::ConstantBoundaryCondition<TInputImage> nbc1;
1014 leftIt.OverrideBoundaryCondition(&nbc1);
1017 outHDispIt.GoToBegin();
1018 outVDispIt.GoToBegin();
1019 outMetricIt.GoToBegin();
1031 bool horizontalInterpolation =
false;
1032 bool verticalInterpolation =
false;
1034 typename ResamplerFilterType::Pointer resampler;
1042 double neighborsMetric[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
1044 while (!leftIt.IsAtEnd() || !outHDispIt.IsAtEnd() || !outVDispIt.IsAtEnd() || !outMetricIt.IsAtEnd())
1047 curLeftPos = leftIt.GetIndex();
1048 if (((curLeftPos[0] - this->m_GridIndex[0] + this->m_Step) % this->m_Step == 0) &&
1049 ((curLeftPos[1] - this->m_GridIndex[1] + this->m_Step) % this->m_Step == 0))
1051 horizontalInterpolation =
false;
1052 verticalInterpolation =
false;
1055 if (useHorizontalDisparity)
1057 hDisp_f =
static_cast<float>(inHDispIt.Get()) * stepDisparity;
1058 hDisp_i =
static_cast<int>(std::floor(hDisp_f + 0.5));
1059 curRightPos[0] = curLeftPos[0] + hDisp_i;
1064 curRightPos[0] = curLeftPos[0];
1068 if (useVerticalDisparity)
1070 vDisp_f =
static_cast<float>(inVDispIt.Get()) * stepDisparity;
1071 vDisp_i =
static_cast<int>(std::floor(vDisp_f + 0.5));
1072 curRightPos[1] = curLeftPos[1] + vDisp_i;
1077 curRightPos[1] = curLeftPos[1];
1081 if (rightBufferedRegion.IsInside(curRightPos))
1086 inRightMaskIt.SetIndex(curRightPos);
1089 if (!inLeftMaskPtr || (inLeftMaskIt.Get() > 0))
1091 if (!inRightMaskPtr || (inRightMaskIt.Get() > 0))
1094 smallRightRegion.SetIndex(0, curRightPos[0] - 1);
1095 smallRightRegion.SetIndex(1, curRightPos[1] - 1);
1096 smallRightRegion.SetSize(0, 3);
1097 smallRightRegion.SetSize(1, 3);
1099 itk::ConstNeighborhoodIterator<TInputImage> rightIt(m_Radius, inRightPtr, smallRightRegion);
1100 itk::ConstantBoundaryCondition<TInputImage> nbc2;
1101 rightIt.OverrideBoundaryCondition(&nbc2);
1104 rightIt.SetLocation(curRightPos);
1105 neighborsMetric[1][1] = m_Functor(leftIt, rightIt);
1107 if (m_MinimumVerticalDisparity < vDisp_i && vDisp_i < m_MaximumVerticalDisparity)
1113 if (rightBufferedRegion.IsInside(upIndex) && rightBufferedRegion.IsInside(downIndex))
1115 rightIt.SetLocation(upIndex);
1116 neighborsMetric[1][0] = m_Functor(leftIt, rightIt);
1118 rightIt.SetLocation(downIndex);
1119 neighborsMetric[1][2] = m_Functor(leftIt, rightIt);
1124 if (neighborsMetric[1][1] < neighborsMetric[1][0] && neighborsMetric[1][1] < neighborsMetric[1][2])
1126 verticalInterpolation =
true;
1131 if (neighborsMetric[1][1] > neighborsMetric[1][0] && neighborsMetric[1][1] > neighborsMetric[1][2])
1133 verticalInterpolation =
true;
1139 if (m_MinimumHorizontalDisparity < hDisp_i && hDisp_i < m_MaximumHorizontalDisparity)
1142 leftIndex[0] += (-1);
1145 if (rightBufferedRegion.IsInside(leftIndex) && rightBufferedRegion.IsInside(rightIndex))
1147 rightIt.SetLocation(rightIndex);
1148 neighborsMetric[2][1] = m_Functor(leftIt, rightIt);
1150 rightIt.SetLocation(leftIndex);
1151 neighborsMetric[0][1] = m_Functor(leftIt, rightIt);
1156 if (neighborsMetric[1][1] < neighborsMetric[0][1] && neighborsMetric[1][1] < neighborsMetric[2][1])
1158 horizontalInterpolation =
true;
1163 if (neighborsMetric[1][1] > neighborsMetric[0][1] && neighborsMetric[1][1] > neighborsMetric[2][1])
1165 horizontalInterpolation =
true;
1172 if (verticalInterpolation && horizontalInterpolation)
1175 uprightIndex[0] += 1;
1176 uprightIndex[1] += (-1);
1177 rightIt.SetLocation(uprightIndex);
1178 neighborsMetric[2][0] = m_Functor(leftIt, rightIt);
1181 downrightIndex[0] += 1;
1182 downrightIndex[1] += 1;
1183 rightIt.SetLocation(downrightIndex);
1184 neighborsMetric[2][2] = m_Functor(leftIt, rightIt);
1187 downleftIndex[0] += (-1);
1188 downleftIndex[1] += 1;
1189 rightIt.SetLocation(downleftIndex);
1190 neighborsMetric[0][2] = m_Functor(leftIt, rightIt);
1193 upleftIndex[0] += (-1);
1194 upleftIndex[1] += (-1);
1195 rightIt.SetLocation(upleftIndex);
1196 neighborsMetric[0][0] = m_Functor(leftIt, rightIt);
1201 if (neighborsMetric[1][1] > neighborsMetric[2][0] || neighborsMetric[1][1] > neighborsMetric[2][2] ||
1202 neighborsMetric[1][1] > neighborsMetric[0][2] || neighborsMetric[1][1] > neighborsMetric[0][0])
1204 verticalInterpolation =
false;
1205 horizontalInterpolation =
false;
1210 if (neighborsMetric[1][1] < neighborsMetric[2][0] || neighborsMetric[1][1] < neighborsMetric[2][2] ||
1211 neighborsMetric[1][1] < neighborsMetric[0][2] || neighborsMetric[1][1] < neighborsMetric[0][0])
1213 verticalInterpolation =
false;
1214 horizontalInterpolation =
false;
1223 if (verticalInterpolation && !horizontalInterpolation)
1227 if ((neighborsMetric[1][0] < neighborsMetric[1][2] && m_Minimize) || (neighborsMetric[1][0] > neighborsMetric[1][2] && !m_Minimize))
1229 deltaV = 0.5 * ((neighborsMetric[1][0] - neighborsMetric[1][2]) / (neighborsMetric[1][2] - neighborsMetric[1][1]));
1233 deltaV = 0.5 * ((neighborsMetric[1][0] - neighborsMetric[1][2]) / (neighborsMetric[1][0] - neighborsMetric[1][1]));
1235 if (deltaV > (-0.5) && deltaV < 0.5)
1237 outVDispIt.Set((
static_cast<double>(vDisp_i) + deltaV) * stepDisparityInv);
1241 verticalInterpolation =
false;
1244 else if (!verticalInterpolation && horizontalInterpolation)
1248 if ((neighborsMetric[0][1] < neighborsMetric[2][1] && m_Minimize) || (neighborsMetric[0][1] > neighborsMetric[2][1] && !m_Minimize))
1250 deltaH = 0.5 * ((neighborsMetric[0][1] - neighborsMetric[2][1]) / (neighborsMetric[2][1] - neighborsMetric[1][1]));
1254 deltaH = 0.5 * ((neighborsMetric[0][1] - neighborsMetric[2][1]) / (neighborsMetric[0][1] - neighborsMetric[1][1]));
1256 if (deltaH > (-0.5) && deltaH < 0.5)
1258 outHDispIt.Set((
static_cast<double>(hDisp_i) + deltaH) * stepDisparityInv);
1262 horizontalInterpolation =
false;
1265 else if (verticalInterpolation && horizontalInterpolation)
1270 if ((neighborsMetric[1][0] < neighborsMetric[1][2] && m_Minimize) || (neighborsMetric[1][0] > neighborsMetric[1][2] && !m_Minimize))
1272 deltaV = 0.5 * ((neighborsMetric[1][0] - neighborsMetric[1][2]) / (neighborsMetric[1][2] - neighborsMetric[1][1]));
1276 deltaV = 0.5 * ((neighborsMetric[1][0] - neighborsMetric[1][2]) / (neighborsMetric[1][0] - neighborsMetric[1][1]));
1279 if ((neighborsMetric[0][1] < neighborsMetric[2][1] && m_Minimize) || (neighborsMetric[0][1] > neighborsMetric[2][1] && !m_Minimize))
1281 deltaH = 0.5 * ((neighborsMetric[0][1] - neighborsMetric[2][1]) / (neighborsMetric[2][1] - neighborsMetric[1][1]));
1285 deltaH = 0.5 * ((neighborsMetric[0][1] - neighborsMetric[2][1]) / (neighborsMetric[0][1] - neighborsMetric[1][1]));
1288 if (deltaV > (-1.0) && deltaV < 1.0 && deltaH > (-1.0) && deltaH < 1.0)
1290 outVDispIt.Set((
static_cast<double>(vDisp_i) + deltaV) * stepDisparityInv);
1291 outHDispIt.Set((
static_cast<double>(hDisp_i) + deltaH) * stepDisparityInv);
1295 verticalInterpolation =
false;
1296 horizontalInterpolation =
false;
1300 if (!verticalInterpolation)
1303 outVDispIt.Set(
static_cast<double>(vDisp_i) * stepDisparityInv);
1306 if (!horizontalInterpolation)
1309 outHDispIt.Set(
static_cast<double>(hDisp_i) * stepDisparityInv);
1312 if (!verticalInterpolation && !horizontalInterpolation)
1315 outMetricIt.Set(
static_cast<double>(neighborsMetric[1][1]));
1320 typename TInputImage::Pointer fakeRightPtr = TInputImage::New();
1321 fakeRightPtr->SetRegions(rightBufferedRegion);
1322 fakeRightPtr->SetPixelContainer((
const_cast<TInputImage*
>(inRightPtr))->GetPixelContainer());
1324 itk::ConstNeighborhoodIterator<TInputImage> shiftedIt;
1325 itk::ConstantBoundaryCondition<TInputImage> nbc3;
1326 shiftedIt.OverrideBoundaryCondition(&nbc3);
1329 windowSize[0] = 2 * m_Radius[0] + 1;
1330 windowSize[1] = 2 * m_Radius[1] + 1;
1333 upleftCorner[0] = curRightPos[0] - m_Radius[0];
1334 upleftCorner[1] = curRightPos[1] - m_Radius[1];
1336 TransformationType::Pointer transfo = TransformationType::New();
1337 TransformationType::OutputVectorType offsetTransfo(2);
1340 tinyShiftedRegion.SetSize(0, 1);
1341 tinyShiftedRegion.SetSize(1, 1);
1342 tinyShiftedRegion.SetIndex(0, curRightPos[0]);
1343 tinyShiftedRegion.SetIndex(1, curRightPos[1]);
1345 resampler = ResamplerFilterType::New();
1346 resampler->SetInput(fakeRightPtr);
1347 resampler->SetSize(windowSize);
1348 resampler->SetNumberOfWorkUnits(1);
1349 resampler->SetTransform(transfo);
1350 resampler->SetOutputStartIndex(upleftCorner);
1352 offsetTransfo[0] = outHDispIt.Get() * stepDisparity -
static_cast<double>(hDisp_i);
1353 offsetTransfo[1] = outVDispIt.Get() * stepDisparity -
static_cast<double>(vDisp_i);
1354 transfo->SetOffset(offsetTransfo);
1355 resampler->Modified();
1356 resampler->Update();
1357 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
1358 outMetricIt.Set(m_Functor(leftIt, shiftedIt));
1360 if ((outMetricIt.Get() > neighborsMetric[1][1] && m_Minimize) || (outMetricIt.Get() < neighborsMetric[1][1] && !m_Minimize))
1366 progress.CompletedPixel();
1372 if (useHorizontalDisparity)
1376 if (useVerticalDisparity)
1389 m_WrongExtrema[threadId] =
static_cast<double>(nb_WrongExtrema) /
static_cast<double>(outputRegionForThread.GetNumberOfPixels());
1392 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
1394 const RegionType& outputRegionForThread, itk::ThreadIdType threadId)
1397 const TInputImage* inLeftPtr = this->GetLeftInput();
1398 const TInputImage* inRightPtr = this->GetRightInput();
1399 const TMaskImage* inLeftMaskPtr = this->GetLeftMaskInput();
1400 const TMaskImage* inRightMaskPtr = this->GetRightMaskInput();
1401 const TDisparityImage* inHDispPtr = this->GetHorizontalDisparityInput();
1402 const TDisparityImage* inVDispPtr = this->GetVerticalDisparityInput();
1403 TOutputMetricImage* outMetricPtr = this->GetMetricOutput();
1404 TDisparityImage* outHDispPtr = this->GetHorizontalDisparityOutput();
1405 TDisparityImage* outVDispPtr = this->GetVerticalDisparityOutput();
1407 unsigned int nb_WrongExtrema = 0;
1411 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels(), 100);
1413 RegionType fullRegionForThread = BlockMatchingFilterType::ConvertSubsampledToFullRegion(outputRegionForThread, this->m_Step, this->m_GridIndex);
1415 itk::ConstNeighborhoodIterator<TInputImage> leftIt(m_Radius, inLeftPtr, fullRegionForThread);
1416 itk::ImageRegionIterator<TDisparityImage> outHDispIt(outHDispPtr, outputRegionForThread);
1417 itk::ImageRegionIterator<TDisparityImage> outVDispIt(outVDispPtr, outputRegionForThread);
1418 itk::ImageRegionIterator<TOutputMetricImage> outMetricIt(outMetricPtr, outputRegionForThread);
1419 itk::ImageRegionConstIterator<TDisparityImage> inHDispIt;
1420 itk::ImageRegionConstIterator<TDisparityImage> inVDispIt;
1421 itk::ImageRegionConstIterator<TMaskImage> inLeftMaskIt;
1422 itk::ImageRegionConstIterator<TMaskImage> inRightMaskIt;
1424 bool useHorizontalDisparity =
false;
1425 bool useVerticalDisparity =
false;
1429 useHorizontalDisparity =
true;
1430 inHDispIt = itk::ImageRegionConstIterator<TDisparityImage>(inHDispPtr, outputRegionForThread);
1431 inHDispIt.GoToBegin();
1435 useVerticalDisparity =
true;
1436 inVDispIt = itk::ImageRegionConstIterator<TDisparityImage>(inVDispPtr, outputRegionForThread);
1437 inVDispIt.GoToBegin();
1442 inLeftMaskIt = itk::ImageRegionConstIterator<TMaskImage>(inLeftMaskPtr, fullRegionForThread);
1443 inLeftMaskIt.GoToBegin();
1445 RegionType rightBufferedRegion = inRightPtr->GetBufferedRegion();
1448 RegionType inRightMaskRegion = inRightMaskPtr->GetBufferedRegion();
1449 inRightMaskIt = itk::ImageRegionConstIterator<TMaskImage>(inRightMaskPtr, inRightMaskRegion);
1452 itk::ConstantBoundaryCondition<TInputImage> nbc1;
1453 leftIt.OverrideBoundaryCondition(&nbc1);
1456 outHDispIt.GoToBegin();
1457 outVDispIt.GoToBegin();
1458 outMetricIt.GoToBegin();
1469 typename TInputImage::Pointer fakeRightPtr = TInputImage::New();
1470 fakeRightPtr->SetRegions(rightBufferedRegion);
1471 fakeRightPtr->SetPixelContainer((
const_cast<TInputImage*
>(inRightPtr))->GetPixelContainer());
1474 bool horizontalInterpolation =
false;
1475 bool verticalInterpolation =
false;
1478 double neighborsMetric[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
1479 unsigned int nbIterMax = 10;
1485 windowSize[0] = 2 * m_Radius[0] + 1;
1486 windowSize[1] = 2 * m_Radius[1] + 1;
1488 TransformationType::Pointer transfo = TransformationType::New();
1489 TransformationType::OutputVectorType offsetTransfo(2);
1490 offsetTransfo[0] = 0.0;
1491 offsetTransfo[1] = 0.0;
1493 typename ResamplerFilterType::Pointer resampler;
1500 tinyShiftedRegion.SetIndex(0, m_Radius[0]);
1501 tinyShiftedRegion.SetIndex(1, m_Radius[1]);
1502 tinyShiftedRegion.SetSize(0, 1);
1503 tinyShiftedRegion.SetSize(1, 1);
1506 itk::ConstNeighborhoodIterator<TInputImage> rightIt;
1507 itk::ConstNeighborhoodIterator<TInputImage> shiftedIt;
1508 itk::ConstantBoundaryCondition<TInputImage> nbc2;
1509 itk::ConstantBoundaryCondition<TInputImage> nbc3;
1510 rightIt.OverrideBoundaryCondition(&nbc2);
1511 shiftedIt.OverrideBoundaryCondition(&nbc3);
1512 bool centreHasMoved;
1514 while (!leftIt.IsAtEnd() || !outHDispIt.IsAtEnd() || !outVDispIt.IsAtEnd() || !outMetricIt.IsAtEnd())
1517 curLeftPos = leftIt.GetIndex();
1518 if (((curLeftPos[0] - this->m_GridIndex[0] + this->m_Step) % this->m_Step == 0) &&
1519 ((curLeftPos[1] - this->m_GridIndex[1] + this->m_Step) % this->m_Step == 0))
1521 horizontalInterpolation =
false;
1522 verticalInterpolation =
false;
1525 if (useHorizontalDisparity)
1527 hDisp_f =
static_cast<float>(inHDispIt.Get()) * stepDisparity;
1528 hDisp_i =
static_cast<int>(std::floor(hDisp_f + 0.5));
1529 curRightPos[0] = curLeftPos[0] + hDisp_i;
1534 curRightPos[0] = curLeftPos[0];
1538 if (useVerticalDisparity)
1540 vDisp_f =
static_cast<float>(inVDispIt.Get()) * stepDisparity;
1541 vDisp_i =
static_cast<int>(std::floor(vDisp_f + 0.5));
1542 curRightPos[1] = curLeftPos[1] + vDisp_i;
1547 curRightPos[1] = curLeftPos[1];
1551 upleftCorner[0] = curRightPos[0] - m_Radius[0];
1552 upleftCorner[1] = curRightPos[1] - m_Radius[1];
1555 resampler = ResamplerFilterType::New();
1556 resampler->SetInput(fakeRightPtr);
1557 resampler->SetSize(windowSize);
1558 resampler->SetNumberOfWorkUnits(1);
1559 resampler->SetTransform(transfo);
1560 resampler->SetOutputStartIndex(upleftCorner);
1562 tinyShiftedRegion.SetIndex(0, curRightPos[0]);
1563 tinyShiftedRegion.SetIndex(1, curRightPos[1]);
1566 if (rightBufferedRegion.IsInside(curRightPos))
1571 inRightMaskIt.SetIndex(curRightPos);
1574 if (!inLeftMaskPtr || (inLeftMaskIt.Get() > 0))
1576 if (!inRightMaskPtr || (inRightMaskIt.Get() > 0))
1579 smallRightRegion.SetIndex(0, curRightPos[0] - 1);
1580 smallRightRegion.SetIndex(1, curRightPos[1] - 1);
1581 smallRightRegion.SetSize(0, 3);
1582 smallRightRegion.SetSize(1, 3);
1584 rightIt.Initialize(m_Radius, inRightPtr, smallRightRegion);
1587 rightIt.SetLocation(curRightPos);
1588 neighborsMetric[1][1] = m_Functor(leftIt, rightIt);
1590 if (m_MinimumVerticalDisparity < vDisp_i && vDisp_i < m_MaximumVerticalDisparity)
1596 if (rightBufferedRegion.IsInside(upIndex) && rightBufferedRegion.IsInside(downIndex))
1598 rightIt.SetLocation(upIndex);
1599 neighborsMetric[1][0] = m_Functor(leftIt, rightIt);
1601 rightIt.SetLocation(downIndex);
1602 neighborsMetric[1][2] = m_Functor(leftIt, rightIt);
1607 if (neighborsMetric[1][1] < neighborsMetric[1][0] && neighborsMetric[1][1] < neighborsMetric[1][2])
1609 verticalInterpolation =
true;
1614 if (neighborsMetric[1][1] > neighborsMetric[1][0] && neighborsMetric[1][1] > neighborsMetric[1][2])
1616 verticalInterpolation =
true;
1622 if (m_MinimumHorizontalDisparity < hDisp_i && hDisp_i < m_MaximumHorizontalDisparity)
1625 leftIndex[0] += (-1);
1628 if (rightBufferedRegion.IsInside(leftIndex) && rightBufferedRegion.IsInside(rightIndex))
1630 rightIt.SetLocation(rightIndex);
1631 neighborsMetric[2][1] = m_Functor(leftIt, rightIt);
1633 rightIt.SetLocation(leftIndex);
1634 neighborsMetric[0][1] = m_Functor(leftIt, rightIt);
1639 if (neighborsMetric[1][1] < neighborsMetric[0][1] && neighborsMetric[1][1] < neighborsMetric[2][1])
1641 horizontalInterpolation =
true;
1646 if (neighborsMetric[1][1] > neighborsMetric[0][1] && neighborsMetric[1][1] > neighborsMetric[2][1])
1648 horizontalInterpolation =
true;
1655 if (verticalInterpolation && horizontalInterpolation)
1658 uprightIndex[0] += 1;
1659 uprightIndex[1] += (-1);
1660 rightIt.SetLocation(uprightIndex);
1661 neighborsMetric[2][0] = m_Functor(leftIt, rightIt);
1664 downrightIndex[0] += 1;
1665 downrightIndex[1] += 1;
1666 rightIt.SetLocation(downrightIndex);
1667 neighborsMetric[2][2] = m_Functor(leftIt, rightIt);
1670 downleftIndex[0] += (-1);
1671 downleftIndex[1] += 1;
1672 rightIt.SetLocation(downleftIndex);
1673 neighborsMetric[0][2] = m_Functor(leftIt, rightIt);
1676 upleftIndex[0] += (-1);
1677 upleftIndex[1] += (-1);
1678 rightIt.SetLocation(upleftIndex);
1679 neighborsMetric[0][0] = m_Functor(leftIt, rightIt);
1684 if (neighborsMetric[1][1] > neighborsMetric[2][0] || neighborsMetric[1][1] > neighborsMetric[2][2] ||
1685 neighborsMetric[1][1] > neighborsMetric[0][2] || neighborsMetric[1][1] > neighborsMetric[0][0])
1687 verticalInterpolation =
false;
1688 horizontalInterpolation =
false;
1693 if (neighborsMetric[1][1] < neighborsMetric[2][0] || neighborsMetric[1][1] < neighborsMetric[2][2] ||
1694 neighborsMetric[1][1] < neighborsMetric[0][2] || neighborsMetric[1][1] < neighborsMetric[0][0])
1696 verticalInterpolation =
false;
1697 horizontalInterpolation =
false;
1706 if (verticalInterpolation && !horizontalInterpolation)
1708 double ya =
static_cast<double>(vDisp_i - 1);
1709 double yb =
static_cast<double>(vDisp_i);
1710 double yc =
static_cast<double>(vDisp_i + 1);
1711 double s_yb = neighborsMetric[1][1];
1716 offsetTransfo[0] = 0.0;
1718 for (
unsigned int k = 0; k < nbIterMax; k++)
1720 if ((yb - ya) < (yc - yb))
1722 yd = 0.5 * (yc + yb);
1723 offsetTransfo[1] = yd -
static_cast<double>(vDisp_i);
1724 transfo->SetOffset(offsetTransfo);
1725 resampler->Modified();
1726 resampler->Update();
1727 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
1728 s_yd = m_Functor(leftIt, shiftedIt);
1730 if ((s_yd < s_yb && m_Minimize) || (s_yd > s_yb && !m_Minimize))
1744 yd = 0.5 * (ya + yb);
1745 offsetTransfo[1] = yd -
static_cast<double>(vDisp_i);
1746 transfo->SetOffset(offsetTransfo);
1747 resampler->Modified();
1748 resampler->Update();
1749 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
1750 s_yd = m_Functor(leftIt, shiftedIt);
1752 if ((s_yd < s_yb && m_Minimize) || (s_yd > s_yb && !m_Minimize))
1766 outVDispIt.Set(yb * stepDisparityInv);
1767 outMetricIt.Set(s_yb);
1769 else if (!verticalInterpolation && horizontalInterpolation)
1771 double xa =
static_cast<double>(hDisp_i - 1);
1772 double xb =
static_cast<double>(hDisp_i);
1773 double xc =
static_cast<double>(hDisp_i + 1);
1774 double s_xb = neighborsMetric[1][1];
1779 offsetTransfo[1] = 0.0;
1781 for (
unsigned int k = 0; k < nbIterMax; k++)
1783 if ((xb - xa) < (xc - xb))
1785 xd = 0.5 * (xc + xb);
1786 offsetTransfo[0] = xd -
static_cast<double>(hDisp_i);
1787 transfo->SetOffset(offsetTransfo);
1788 resampler->Modified();
1789 resampler->Update();
1790 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
1791 s_xd = m_Functor(leftIt, shiftedIt);
1793 if ((s_xd < s_xb && m_Minimize) || (s_xd > s_xb && !m_Minimize))
1807 xd = 0.5 * (xa + xb);
1808 offsetTransfo[0] = xd -
static_cast<double>(hDisp_i);
1809 transfo->SetOffset(offsetTransfo);
1810 resampler->Modified();
1811 resampler->Update();
1812 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
1813 s_xd = m_Functor(leftIt, shiftedIt);
1815 if ((s_xd < s_xb && m_Minimize) || (s_xd > s_xb && !m_Minimize))
1829 outHDispIt.Set(xb * stepDisparityInv);
1830 outMetricIt.Set(s_xb);
1832 else if (verticalInterpolation && horizontalInterpolation)
1834 double xa =
static_cast<double>(hDisp_i);
1835 double ya =
static_cast<double>(vDisp_i - 1);
1836 double xb =
static_cast<double>(hDisp_i);
1837 double yb =
static_cast<double>(vDisp_i);
1838 double yc =
static_cast<double>(vDisp_i + 1);
1839 double xe =
static_cast<double>(hDisp_i - 1);
1840 double ye =
static_cast<double>(vDisp_i);
1841 double xf =
static_cast<double>(hDisp_i + 1);
1843 double s_b = neighborsMetric[1][1];
1849 for (
unsigned int k = 0; k < nbIterMax; k++)
1852 centreHasMoved =
false;
1853 if ((yb - ya) < (yc - yb))
1855 yd = 0.5 * (yc + yb);
1856 offsetTransfo[0] = xd -
static_cast<double>(hDisp_i);
1857 offsetTransfo[1] = yd -
static_cast<double>(vDisp_i);
1858 transfo->SetOffset(offsetTransfo);
1859 resampler->Modified();
1860 resampler->Update();
1861 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
1862 s_d = m_Functor(leftIt, shiftedIt);
1864 if ((s_d < s_b && m_Minimize) || (s_d > s_b && !m_Minimize))
1866 centreHasMoved =
true;
1880 yd = 0.5 * (ya + yb);
1881 offsetTransfo[0] = xd -
static_cast<double>(hDisp_i);
1882 offsetTransfo[1] = yd -
static_cast<double>(vDisp_i);
1883 transfo->SetOffset(offsetTransfo);
1884 resampler->Modified();
1885 resampler->Update();
1886 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
1887 s_d = m_Functor(leftIt, shiftedIt);
1889 if ((s_d < s_b && m_Minimize) || (s_d > s_b && !m_Minimize))
1891 centreHasMoved =
true;
1908 offsetTransfo[0] = xe -
static_cast<double>(hDisp_i);
1909 offsetTransfo[1] = ye -
static_cast<double>(vDisp_i);
1910 transfo->SetOffset(offsetTransfo);
1911 resampler->Modified();
1912 resampler->Update();
1913 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
1916 offsetTransfo[0] = xf -
static_cast<double>(hDisp_i);
1917 transfo->SetOffset(offsetTransfo);
1918 resampler->Modified();
1919 resampler->Update();
1920 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
1924 centreHasMoved =
false;
1925 if ((xb - xe) < (xf - xb))
1927 xd = 0.5 * (xf + xb);
1928 offsetTransfo[0] = xd -
static_cast<double>(hDisp_i);
1929 offsetTransfo[1] = yd -
static_cast<double>(vDisp_i);
1930 transfo->SetOffset(offsetTransfo);
1931 resampler->Modified();
1932 resampler->Update();
1933 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
1934 s_d = m_Functor(leftIt, shiftedIt);
1936 if ((s_d < s_b && m_Minimize) || (s_d > s_b && !m_Minimize))
1938 centreHasMoved =
true;
1952 xd = 0.5 * (xe + xb);
1953 offsetTransfo[0] = xd -
static_cast<double>(hDisp_i);
1954 offsetTransfo[1] = yd -
static_cast<double>(vDisp_i);
1955 transfo->SetOffset(offsetTransfo);
1956 resampler->Modified();
1957 resampler->Update();
1958 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
1959 s_d = m_Functor(leftIt, shiftedIt);
1961 if ((s_d < s_b && m_Minimize) || (s_d > s_b && !m_Minimize))
1963 centreHasMoved =
true;
1980 offsetTransfo[0] = xa -
static_cast<double>(hDisp_i);
1981 offsetTransfo[1] = ya -
static_cast<double>(vDisp_i);
1982 transfo->SetOffset(offsetTransfo);
1983 resampler->Modified();
1984 resampler->Update();
1985 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
1987 offsetTransfo[1] = yc -
static_cast<double>(vDisp_i);
1988 transfo->SetOffset(offsetTransfo);
1989 resampler->Modified();
1990 resampler->Update();
1991 shiftedIt.Initialize(m_Radius, resampler->GetOutput(), tinyShiftedRegion);
1995 outHDispIt.Set(xb * stepDisparityInv);
1996 outVDispIt.Set(yb * stepDisparityInv);
1997 outMetricIt.Set(s_b);
2000 if (!verticalInterpolation)
2003 outVDispIt.Set(
static_cast<double>(vDisp_i) * stepDisparityInv);
2006 if (!horizontalInterpolation)
2009 outHDispIt.Set(
static_cast<double>(hDisp_i) * stepDisparityInv);
2012 if (!verticalInterpolation && !horizontalInterpolation)
2014 outMetricIt.Set(
static_cast<double>(neighborsMetric[1][1]));
2018 if ((outMetricIt.Get() > neighborsMetric[1][1] && m_Minimize) || (outMetricIt.Get() < neighborsMetric[1][1] && !m_Minimize))
2024 progress.CompletedPixel();
2030 if (useHorizontalDisparity)
2034 if (useVerticalDisparity)
2047 m_WrongExtrema[threadId] =
static_cast<double>(nb_WrongExtrema) /
static_cast<double>(outputRegionForThread.GetNumberOfPixels());
2050 template <
class TInputImage,
class TOutputMetricImage,
class TDisparityImage,
class TMaskImage,
class TBlockMatchingFunctor>
2053 double wrongExtremaPercent = 0;
2054 for (
unsigned int i = 0; i < m_WrongExtrema.size(); i++)
2056 wrongExtremaPercent += m_WrongExtrema[i];
2058 wrongExtremaPercent /= m_WrongExtrema.size();
Perform 2D block matching between two images.
virtual const int & GetMinimumVerticalDisparity() const
const TInputImage * GetRightInput() const
const TInputImage * GetLeftInput() const
const TMaskImage * GetLeftMaskInput() const
virtual const SizeType & GetRadius() const
const TMaskImage * GetRightMaskInput() const
const TOutputMetricImage * GetMetricOutput() const
const TOutputDisparityImage * GetHorizontalDisparityOutput() const
virtual const bool & GetMinimize() const
virtual const int & GetMinimumHorizontalDisparity() const
const TOutputDisparityImage * GetVerticalDisparityOutput() const
virtual const int & GetMaximumHorizontalDisparity() const
virtual const int & GetMaximumVerticalDisparity() const
void BeforeThreadedGenerateData() override
void ThreadedGenerateData(const RegionType &outputRegionForThread, itk::ThreadIdType threadId) override
const TInputImage * GetLeftInput() const
void TriangularRefinement(const RegionType &outputRegionForThread, itk::ThreadIdType threadId)
void DichotomyRefinement(const RegionType &outputRegionForThread, itk::ThreadIdType threadId)
InputImageType::SpacingType SpacingType
void SetRightMaskInput(const TMaskImage *image)
const TDisparityImage * GetVerticalDisparityOutput() const
const TDisparityImage * GetVerticalDisparityInput() const
void AfterThreadedGenerateData() override
void SetLeftMaskInput(const TMaskImage *image)
void SetInputsFromBlockMatchingFilter(const BlockMatchingFilterType *filter)
void GenerateOutputInformation() override
void SetLeftInput(const TInputImage *image)
const TOutputMetricImage * GetMetricOutput() const
SubPixelDisparityImageFilter()
void SetMetricInput(const TOutputMetricImage *image)
void SetVerticalDisparityInput(const TDisparityImage *vfield)
InputImageType::SizeType SizeType
InputImageType::IndexType IndexType
const TMaskImage * GetLeftMaskInput() const
OutputDisparityImageType::PixelType DisparityPixelType
const TDisparityImage * GetHorizontalDisparityInput() const
void ParabolicRefinement(const RegionType &outputRegionForThread, itk::ThreadIdType threadId)
const TMaskImage * GetRightMaskInput() const
const TDisparityImage * GetHorizontalDisparityOutput() const
InputImageType::RegionType RegionType
void GenerateInputRequestedRegion() override
void SetHorizontalDisparityInput(const TDisparityImage *hfield)
~SubPixelDisparityImageFilter() override
InputImageType::PointType PointType
const TInputImage * GetRightInput() const
void VerifyInputInformation() const override
Verify that the input images are compatible.
void SetRightInput(const TInputImage *image)
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.