21 #ifndef otbMultiDisparityMapTo3DFilter_hxx
22 #define otbMultiDisparityMapTo3DFilter_hxx
25 #include "itkImageRegionConstIteratorWithIndex.h"
26 #include "itkImageRegionIterator.h"
31 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
35 this->SetNumberOfRequiredInputs(3);
36 this->SetNumberOfRequiredInputs(1);
37 this->m_MovingImageMetadatas.resize(1);
40 this->SetNumberOfRequiredOutputs(2);
41 this->SetNthOutput(0, TOutputImage::New());
42 this->SetNthOutput(1, TResidueImage::New());
45 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
50 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
55 this->SetNumberOfRequiredInputs(3 * nb);
56 this->m_MovingImageMetadatas.resize(nb);
60 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
63 return this->m_MovingImageMetadatas.size();
66 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
68 const TDisparityImage* hmap)
70 if ((3 * (index + 1)) > this->GetNumberOfRequiredInputs())
72 itkExceptionMacro(<<
"Index is greater than the number of moving images");
75 this->SetNthInput(3 * index,
const_cast<TDisparityImage*
>(hmap));
78 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
80 const TDisparityImage* vmap)
82 if ((3 * (index + 1)) > this->GetNumberOfRequiredInputs())
84 itkExceptionMacro(<<
"Index is greater than the number of moving images");
87 this->SetNthInput(3 * index + 1,
const_cast<TDisparityImage*
>(vmap));
90 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
93 if ((3 * (index + 1)) > this->GetNumberOfRequiredInputs())
95 itkExceptionMacro(<<
"Index is greater than the number of moving images");
98 this->SetNthInput(3 * index + 2,
const_cast<TMaskImage*
>(mask));
101 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
102 const TDisparityImage*
105 if ((3 * (index + 1)) > this->GetNumberOfRequiredInputs())
109 return static_cast<const TDisparityImage*
>(this->itk::ProcessObject::GetInput(3 * index));
112 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
113 const TDisparityImage*
116 if ((3 * (index + 1)) > this->GetNumberOfRequiredInputs())
120 return static_cast<const TDisparityImage*
>(this->itk::ProcessObject::GetInput(3 * index + 1));
123 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
126 if ((3 * (index + 1)) > this->GetNumberOfRequiredInputs())
130 return static_cast<const TMaskImage*
>(this->itk::ProcessObject::GetInput(3 * index + 2));
133 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
136 return static_cast<const TResidueImage*
>(this->itk::ProcessObject::GetOutput(1));
139 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
142 return static_cast<TResidueImage*
>(this->itk::ProcessObject::GetOutput(1));
145 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
149 if (this->m_MovingImageMetadatas.size() > index)
151 this->m_MovingImageMetadatas[index] = imd;
155 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
159 if (this->m_MovingImageMetadatas.size() <= index)
161 itkExceptionMacro(<<
"ImageMetadata index is outside the container");
163 return this->m_MovingImageMetadatas[index];
166 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
169 const TDisparityImage* horizDisp = this->GetHorizontalDisparityMapInput(0);
170 TOutputImage* outputPtr = this->GetOutput();
171 TResidueImage* residuePtr = this->GetResidueOutput();
175 outputPtr->SetLargestPossibleRegion(horizDisp->GetLargestPossibleRegion());
176 outputPtr->SetNumberOfComponentsPerPixel(3);
178 residuePtr->SetLargestPossibleRegion(horizDisp->GetLargestPossibleRegion());
179 residuePtr->SetNumberOfComponentsPerPixel(1);
182 outputPtr->SetOrigin(horizDisp->GetOrigin());
183 outputPtr->SetSignedSpacing(horizDisp->GetSignedSpacing());
185 residuePtr->SetOrigin(horizDisp->GetOrigin());
186 residuePtr->SetSignedSpacing(horizDisp->GetSignedSpacing());
188 if (this->m_ReferenceImageMetadata)
190 auto outputmetadata = *m_ReferenceImageMetadata;
192 outputmetadata.Bands.clear();
193 outputPtr->SetImageMetadata(outputmetadata);
194 residuePtr->SetImageMetadata(outputmetadata);
198 itkExceptionMacro(<<
"Reference ImageMetadata is missing");
203 itkExceptionMacro(<<
"First horizontal disparity map is missing");
207 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
210 RegionType requested = this->GetOutput()->GetRequestedRegion();
211 RegionType largest = this->GetHorizontalDisparityMapInput(0)->GetLargestPossibleRegion();
213 for (
unsigned int i = 0; i < this->GetNumberOfRequiredInputs(); ++i)
215 unsigned int index = i % 3;
216 unsigned int pos = i / 3;
222 TDisparityImage* horizDisp =
const_cast<TDisparityImage*
>(this->GetHorizontalDisparityMapInput(pos));
225 if (horizDisp->GetLargestPossibleRegion() != largest)
227 itkExceptionMacro(<<
"Horizontal disparity map at position " << pos <<
" has a different largest region");
229 horizDisp->SetRequestedRegion(requested);
233 itkExceptionMacro(<<
"Horizontal disparity map at position " << pos <<
" is missing");
240 TDisparityImage* vertiDisp =
const_cast<TDisparityImage*
>(this->GetVerticalDisparityMapInput(pos));
243 if (vertiDisp->GetLargestPossibleRegion() != largest)
245 itkExceptionMacro(<<
"Vertical disparity map at position " << pos <<
" has a different largest region");
247 vertiDisp->SetRequestedRegion(requested);
254 TMaskImage* maskDisp =
const_cast<TMaskImage*
>(this->GetDisparityMaskInput(pos));
257 if (maskDisp->GetLargestPossibleRegion() != largest)
259 itkExceptionMacro(<<
"Disparity mask at position " << pos <<
" has a different largest region");
261 maskDisp->SetRequestedRegion(requested);
266 itkExceptionMacro(<<
"Unexpected value for (i%3) ");
271 for (
unsigned int k = 0; k < this->m_MovingImageMetadatas.size(); ++k)
273 if (!this->m_MovingImageMetadatas[k])
275 itkExceptionMacro(<<
"ImageMetadata of moving image at position " << k <<
" is empty");
280 template <
class TDisparityImage,
class TOutputImage,
class TMaskImage,
class TRes
idueImage>
282 itk::ThreadIdType itkNotUsed(threadId))
284 auto referenceToGroundTransform = RSTransformType::New();
286 referenceToGroundTransform->SetInputImageMetadata(this->m_ReferenceImageMetadata);
287 referenceToGroundTransform->InstantiateTransform();
290 std::vector<RSTransformType::Pointer> movingToGroundTransform;
292 for (
unsigned int k = 0; k < this->m_MovingImageMetadatas.size(); ++k)
295 transfo->SetInputImageMetadata(this->m_MovingImageMetadatas[k]);
296 transfo->InstantiateTransform();
297 movingToGroundTransform.push_back(transfo);
301 TOutputImage* outputPtr = this->GetOutput();
302 TResidueImage* residuePtr = this->GetResidueOutput();
304 itk::ImageRegionIteratorWithIndex<OutputImageType> outIt(outputPtr, outputRegionForThread);
305 itk::ImageRegionIterator<ResidueImageType> resIt(residuePtr, outputRegionForThread);
313 for (
unsigned int k = 0; k < this->m_MovingImageMetadatas.size(); ++k)
316 hDispIts[k] = itk::ImageRegionConstIterator<DisparityMapType>(this->GetHorizontalDisparityMapInput(k), outputRegionForThread);
317 hDispIts[k].GoToBegin();
319 if (this->GetVerticalDisparityMapInput(k))
321 vDispIts[k] = itk::ImageRegionConstIterator<DisparityMapType>(this->GetVerticalDisparityMapInput(k), outputRegionForThread);
322 vDispIts[k].GoToBegin();
325 if (this->GetDisparityMaskInput(k))
327 maskIts[k] = itk::ImageRegionConstIterator<MaskImageType>(this->GetDisparityMaskInput(k), outputRegionForThread);
328 maskIts[k].GoToBegin();
338 typename OutputImageType::PointType pointRef;
341 typename OutputImageType::PixelType outPixel(3);
344 typename PointSetType::Pointer pointSetA = PointSetType::New();
345 typename PointSetType::Pointer pointSetB = PointSetType::New();
347 while (!outIt.IsAtEnd())
349 pointSetA->Initialize();
350 pointSetB->Initialize();
355 outputPtr->TransformIndexToPhysicalPoint(outIt.GetIndex(), pointRef);
357 currentPoint[0] = pointRef[0];
358 currentPoint[1] = pointRef[1];
359 currentPoint[2] = altiMax;
361 pointA = referenceToGroundTransform->TransformPoint(currentPoint);
363 currentPoint[2] = altiMin;
364 pointB = referenceToGroundTransform->TransformPoint(currentPoint);
366 pointSetA->SetPoint(0, pointA);
367 pointSetB->SetPoint(0, pointB);
368 pointSetA->SetPointData(0, 0);
369 pointSetB->SetPointData(0, 0);
371 unsigned int nbPoints = 1;
373 for (
unsigned int k = 0; k < this->m_MovingImageMetadatas.size(); ++k)
378 if (maskIts.count(k) && !(maskIts[k].Get() > 0))
383 currentPoint[0] = pointRef[0] + hDispIts[k].Get();
384 currentPoint[1] = pointRef[1];
385 if (vDispIts.count(k))
387 currentPoint[1] += vDispIts[k].Get();
390 currentPoint[2] = altiMax;
391 pointAi = movingToGroundTransform[k]->TransformPoint(currentPoint);
392 currentPoint[2] = altiMin;
393 pointBi = movingToGroundTransform[k]->TransformPoint(currentPoint);
394 pointSetA->SetPoint(nbPoints, pointAi);
395 pointSetB->SetPoint(nbPoints, pointBi);
396 pointSetA->SetPointData(nbPoints, k + 1);
397 pointSetB->SetPointData(nbPoints, k + 1);
404 TDPointType intersection = optimizer->Compute(pointSetA, pointSetB);
405 outPixel[0] = intersection[0];
406 outPixel[1] = intersection[1];
407 outPixel[2] = intersection[2];
408 globalResidue = optimizer->GetGlobalResidue();
417 resIt.Set(globalResidue);
420 for (
typename DispMapIteratorList::iterator hIt = hDispIts.begin(); hIt != hDispIts.end(); ++hIt)
424 for (
typename DispMapIteratorList::iterator vIt = vDispIts.begin(); vIt != vDispIts.end(); ++vIt)
428 for (
typename MaskIteratorList::iterator mIt = maskIts.begin(); mIt != maskIts.end(); ++mIt)