21 #ifndef otbDisparityMapToDEMFilter_hxx
22 #define otbDisparityMapToDEMFilter_hxx
25 #include "itkImageRegionConstIteratorWithIndex.h"
26 #include "itkImageRegionIterator.h"
31 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
34 this->DynamicMultiThreadingOff();
36 this->SetNumberOfRequiredInputs(7);
37 this->SetNumberOfRequiredInputs(1);
40 this->SetNumberOfRequiredOutputs(1);
41 this->SetNthOutput(0, TOutputDEMImage::New());
45 m_ElevationMax = 100.0;
48 m_InputSplitter = SplitterType::New();
49 m_UsedInputSplits = 1;
52 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
57 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
59 const TDisparityImage* hmap)
62 this->SetNthInput(0,
const_cast<TDisparityImage*
>(hmap));
65 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
67 const TDisparityImage* vmap)
70 this->SetNthInput(1,
const_cast<TDisparityImage*
>(vmap));
73 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
77 this->SetNthInput(2,
const_cast<TInputImage*
>(image));
80 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
84 this->SetNthInput(3,
const_cast<TInputImage*
>(image));
87 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
89 const TEpipolarGridImage* grid)
92 this->SetNthInput(4,
const_cast<TEpipolarGridImage*
>(grid));
95 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
97 const TEpipolarGridImage* grid)
100 this->SetNthInput(5,
const_cast<TEpipolarGridImage*
>(grid));
103 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
107 this->SetNthInput(6,
const_cast<TMaskImage*
>(mask));
110 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
111 const TDisparityImage*
114 if (this->GetNumberOfInputs() < 1)
118 return static_cast<const TDisparityImage*
>(this->itk::ProcessObject::GetInput(0));
121 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
122 const TDisparityImage*
125 if (this->GetNumberOfInputs() < 2)
129 return static_cast<const TDisparityImage*
>(this->itk::ProcessObject::GetInput(1));
132 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
135 if (this->GetNumberOfInputs() < 3)
139 return static_cast<const TInputImage*
>(this->itk::ProcessObject::GetInput(2));
142 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
145 if (this->GetNumberOfInputs() < 4)
149 return static_cast<const TInputImage*
>(this->itk::ProcessObject::GetInput(3));
152 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
153 const TEpipolarGridImage*
156 if (this->GetNumberOfInputs() < 5)
160 return static_cast<const TEpipolarGridImage*
>(this->itk::ProcessObject::GetInput(4));
163 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
164 const TEpipolarGridImage*
167 if (this->GetNumberOfInputs() < 6)
171 return static_cast<const TEpipolarGridImage*
>(this->itk::ProcessObject::GetInput(5));
174 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
177 if (this->GetNumberOfInputs() < 7)
181 return static_cast<const TMaskImage*
>(this->itk::ProcessObject::GetInput(6));
184 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
187 if (this->GetNumberOfOutputs() < 1)
191 return static_cast<const TOutputDEMImage*
>(this->itk::ProcessObject::GetOutput(0));
194 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
197 if (this->GetNumberOfOutputs() < 1)
201 return static_cast<TOutputDEMImage*
>(this->itk::ProcessObject::GetOutput(0));
204 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
208 const TInputImage* leftImgPtr = this->GetLeftInput();
209 const TInputImage* rightImgPtr = this->GetRightInput();
210 TOutputDEMImage* outputPtr = this->GetDEMOutput();
214 RSTransform2DType::Pointer leftToGroundTransform = RSTransform2DType::New();
215 leftToGroundTransform->SetInputImageMetadata(&(leftImgPtr->GetImageMetadata()));
216 leftToGroundTransform->InstantiateTransform();
218 RSTransform2DType::Pointer rightToGroundTransform = RSTransform2DType::New();
219 rightToGroundTransform->SetInputImageMetadata(&(rightImgPtr->GetImageMetadata()));
220 rightToGroundTransform->InstantiateTransform();
223 typename SensorImageType::SizeType inputSize = leftImgPtr->GetLargestPossibleRegion().GetSize();
224 typename SensorImageType::PointType ulp, urp, llp, lrp;
225 itk::ContinuousIndex<double, 2> ul(leftImgPtr->GetLargestPossibleRegion().GetIndex());
229 itk::ContinuousIndex<double, 2> ur(ul);
230 itk::ContinuousIndex<double, 2> lr(ul);
231 itk::ContinuousIndex<double, 2> ll(ul);
232 ur[0] +=
static_cast<double>(inputSize[0]);
233 lr[0] +=
static_cast<double>(inputSize[0]);
234 lr[1] +=
static_cast<double>(inputSize[1]);
235 ll[1] +=
static_cast<double>(inputSize[1]);
237 leftImgPtr->TransformContinuousIndexToPhysicalPoint(ul, ulp);
238 leftImgPtr->TransformContinuousIndexToPhysicalPoint(ur, urp);
239 leftImgPtr->TransformContinuousIndexToPhysicalPoint(ll, llp);
240 leftImgPtr->TransformContinuousIndexToPhysicalPoint(lr, lrp);
242 RSTransform2DType::OutputPointType left_ul, left_ur, left_ll, left_lr;
243 left_ul = leftToGroundTransform->TransformPoint(ulp);
244 left_ur = leftToGroundTransform->TransformPoint(urp);
245 left_ll = leftToGroundTransform->TransformPoint(llp);
246 left_lr = leftToGroundTransform->TransformPoint(lrp);
249 inputSize = rightImgPtr->GetLargestPossibleRegion().GetSize();
250 ul = rightImgPtr->GetLargestPossibleRegion().GetIndex();
256 ur[0] +=
static_cast<double>(inputSize[0]);
257 lr[0] +=
static_cast<double>(inputSize[0]);
258 lr[1] +=
static_cast<double>(inputSize[1]);
259 ll[1] +=
static_cast<double>(inputSize[1]);
261 rightImgPtr->TransformContinuousIndexToPhysicalPoint(ul, ulp);
262 rightImgPtr->TransformContinuousIndexToPhysicalPoint(ur, urp);
263 rightImgPtr->TransformContinuousIndexToPhysicalPoint(ll, llp);
264 rightImgPtr->TransformContinuousIndexToPhysicalPoint(lr, lrp);
266 RSTransform2DType::OutputPointType right_ul, right_ur, right_lr, right_ll;
267 right_ul = rightToGroundTransform->TransformPoint(ulp);
268 right_ur = rightToGroundTransform->TransformPoint(urp);
269 right_ll = rightToGroundTransform->TransformPoint(llp);
270 right_lr = rightToGroundTransform->TransformPoint(lrp);
272 double left_xmin = std::min(std::min(std::min(left_ul[0], left_ur[0]), left_lr[0]), left_ll[0]);
273 double left_xmax = std::max(std::max(std::max(left_ul[0], left_ur[0]), left_lr[0]), left_ll[0]);
274 double left_ymin = std::min(std::min(std::min(left_ul[1], left_ur[1]), left_lr[1]), left_ll[1]);
275 double left_ymax = std::max(std::max(std::max(left_ul[1], left_ur[1]), left_lr[1]), left_ll[1]);
277 double right_xmin = std::min(std::min(std::min(right_ul[0], right_ur[0]), right_lr[0]), right_ll[0]);
278 double right_xmax = std::max(std::max(std::max(right_ul[0], right_ur[0]), right_lr[0]), right_ll[0]);
279 double right_ymin = std::min(std::min(std::min(right_ul[1], right_ur[1]), right_lr[1]), right_ll[1]);
280 double right_ymax = std::max(std::max(std::max(right_ul[1], right_ur[1]), right_lr[1]), right_ll[1]);
282 double box_xmin = std::max(left_xmin, right_xmin);
283 double box_xmax = std::min(left_xmax, right_xmax);
284 double box_ymin = std::max(left_ymin, right_ymin);
285 double box_ymax = std::min(left_ymax, right_ymax);
287 if (box_xmin >= box_xmax || box_ymin >= box_ymax)
289 itkExceptionMacro(<<
"Wrong reconstruction area, images don't overlap, check image corners");
294 typename TOutputDEMImage::SpacingType outSpacing;
295 outSpacing[0] = 57.295779513 * m_DEMGridStep / (6378137.0 * std::cos((box_ymin + box_ymax) * 0.5 * 0.01745329251));
296 outSpacing[1] = -57.295779513 * m_DEMGridStep / 6378137.0;
297 outputPtr->SetSignedSpacing(outSpacing);
300 typename TOutputDEMImage::PointType outOrigin;
301 outOrigin[0] = box_xmin + 0.5 * outSpacing[0];
302 outOrigin[1] = box_ymax + 0.5 * outSpacing[1];
303 outputPtr->SetOrigin(outOrigin);
306 typename DEMImageType::RegionType outRegion;
307 outRegion.SetIndex(0, 0);
308 outRegion.SetIndex(1, 0);
309 outRegion.SetSize(0,
static_cast<unsigned int>((box_xmax - box_xmin) / std::abs(outSpacing[0])));
310 outRegion.SetSize(1,
static_cast<unsigned int>((box_ymax - box_ymin) / std::abs(outSpacing[1])));
312 outputPtr->SetLargestPossibleRegion(outRegion);
313 outputPtr->SetNumberOfComponentsPerPixel(1);
316 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
320 TEpipolarGridImage* leftGrid =
const_cast<TEpipolarGridImage*
>(this->GetLeftEpipolarGridInput());
321 TEpipolarGridImage* rightGrid =
const_cast<TEpipolarGridImage*
>(this->GetRightEpipolarGridInput());
323 leftGrid->SetRequestedRegionToLargestPossibleRegion();
324 rightGrid->SetRequestedRegionToLargestPossibleRegion();
326 leftGrid->UpdateOutputData();
327 rightGrid->UpdateOutputData();
331 const TInputImage* leftSensor = this->GetLeftInput();
332 TOutputDEMImage* outputDEM = this->GetDEMOutput();
334 typename DEMImageType::RegionType outRegion = outputDEM->GetRequestedRegion();
335 typename DEMImageType::PointType outOrigin = outputDEM->GetOrigin();
336 typename DEMImageType::SpacingType outSpacing = outputDEM->GetSignedSpacing();
339 groundToLeftTransform->SetOutputImageMetadata(&(leftSensor->GetImageMetadata()));
340 groundToLeftTransform->InstantiateTransform();
344 TDisparityImage* horizDisp =
const_cast<TDisparityImage*
>(this->GetHorizontalDisparityMapInput());
345 TDisparityImage* vertiDisp =
const_cast<TDisparityImage*
>(this->GetVerticalDisparityMapInput());
346 TMaskImage* maskDisp =
const_cast<TMaskImage*
>(this->GetDisparityMaskInput());
349 if (horizDisp->GetLargestPossibleRegion() != vertiDisp->GetLargestPossibleRegion())
351 itkExceptionMacro(<<
"Horizontal and vertical disparity maps do not have the same size ! Horizontal largest region: "
352 << horizDisp->GetLargestPossibleRegion() <<
", vertical largest region: " << vertiDisp->GetLargestPossibleRegion());
355 if (maskDisp && horizDisp->GetLargestPossibleRegion() != maskDisp->GetLargestPossibleRegion())
357 itkExceptionMacro(<<
"Disparity map and mask do not have the same size ! Map region : " << horizDisp->GetLargestPossibleRegion()
358 <<
", mask region : " << maskDisp->GetLargestPossibleRegion());
363 corners[0][0] = outOrigin[0] + outSpacing[0] * (-0.5 +
static_cast<double>(outRegion.GetIndex(0)));
364 corners[0][1] = outOrigin[1] + outSpacing[1] * (-0.5 +
static_cast<double>(outRegion.GetIndex(1)));
365 corners[0][2] = m_ElevationMin;
367 corners[1][0] = corners[0][0];
368 corners[1][1] = corners[0][1];
369 corners[1][2] = m_ElevationMax;
371 corners[2][0] = corners[0][0] + outSpacing[0] *
static_cast<double>(outRegion.GetSize(0));
372 corners[2][1] = corners[0][1];
373 corners[2][2] = m_ElevationMin;
375 corners[3][0] = corners[2][0];
376 corners[3][1] = corners[2][1];
377 corners[3][2] = m_ElevationMax;
379 corners[4][0] = corners[0][0] + outSpacing[0] *
static_cast<double>(outRegion.GetSize(0));
380 corners[4][1] = corners[0][1] + outSpacing[1] *
static_cast<double>(outRegion.GetSize(1));
381 corners[4][2] = m_ElevationMin;
383 corners[5][0] = corners[4][0];
384 corners[5][1] = corners[4][1];
385 corners[5][2] = m_ElevationMax;
387 corners[6][0] = corners[0][0];
388 corners[6][1] = corners[0][1] + outSpacing[1] *
static_cast<double>(outRegion.GetSize(1));
389 corners[6][2] = m_ElevationMin;
391 corners[7][0] = corners[6][0];
392 corners[7][1] = corners[6][1];
393 corners[7][2] = m_ElevationMax;
396 double a_grid, b_grid;
400 typename GridImageType::IndexType gridIndex;
401 typename GridImageType::IndexType gridIndexU;
402 typename GridImageType::IndexType gridIndexV;
403 typename GridImageType::PointType gridPoint;
404 typename GridImageType::PointType gridPointU;
405 typename GridImageType::PointType gridPointV;
406 typename GridImageType::PixelType origLoc(2);
407 typename GridImageType::PixelType uUnitLoc(2);
408 typename GridImageType::PixelType vUnitLoc(2);
410 typename GridImageType::RegionType gridRegion = leftGrid->GetLargestPossibleRegion();
411 itk::ContinuousIndex<double, 2> gridContiIndex;
412 typename DisparityMapType::PointType epiPosition;
413 itk::ContinuousIndex<double, 2> epiContiIndex;
414 double epiIndexMin[2];
415 double epiIndexMax[2];
419 epiIndexMin[0] = itk::NumericTraits<double>::Zero;
420 epiIndexMin[1] = itk::NumericTraits<double>::Zero;
422 epiIndexMax[0] = itk::NumericTraits<double>::Zero;
423 epiIndexMax[1] = itk::NumericTraits<double>::Zero;
425 maxGridIndex[0] =
static_cast<int>(gridRegion.GetIndex(0) + gridRegion.GetSize(0)) - 2;
426 maxGridIndex[1] =
static_cast<int>(gridRegion.GetIndex(1) + gridRegion.GetSize(1)) - 2;
427 minGridIndex[0] =
static_cast<int>(gridRegion.GetIndex(0));
428 minGridIndex[1] =
static_cast<int>(gridRegion.GetIndex(1));
430 for (
unsigned int k = 0; k < 8; k++)
433 TDPointType tmpSensor = groundToLeftTransform->TransformPoint(corners[k]);
436 gridIndex[0] = minGridIndex[0];
437 gridIndex[1] = minGridIndex[1];
440 for (
unsigned int s = 0; s < 3; s++)
442 gridIndexU[0] = gridIndex[0] + 1;
443 gridIndexU[1] = gridIndex[1];
445 gridIndexV[0] = gridIndex[0];
446 gridIndexV[1] = gridIndex[1] + 1;
448 leftGrid->TransformIndexToPhysicalPoint(gridIndex, gridPoint);
449 leftGrid->TransformIndexToPhysicalPoint(gridIndexU, gridPointU);
450 leftGrid->TransformIndexToPhysicalPoint(gridIndexV, gridPointV);
452 origLoc[0] = (leftGrid->GetPixel(gridIndex))[0] + gridPoint[0];
453 origLoc[1] = (leftGrid->GetPixel(gridIndex))[1] + gridPoint[1];
454 uUnitLoc[0] = (leftGrid->GetPixel(gridIndexU))[0] + gridPointU[0];
455 uUnitLoc[1] = (leftGrid->GetPixel(gridIndexU))[1] + gridPointU[1];
456 vUnitLoc[0] = (leftGrid->GetPixel(gridIndexV))[0] + gridPointV[0];
457 vUnitLoc[1] = (leftGrid->GetPixel(gridIndexV))[1] + gridPointV[1];
459 u_loc[0] =
static_cast<double>(uUnitLoc[0] - origLoc[0]);
460 u_loc[1] =
static_cast<double>(uUnitLoc[1] - origLoc[1]);
462 v_loc[0] =
static_cast<double>(vUnitLoc[0] - origLoc[0]);
463 v_loc[1] =
static_cast<double>(vUnitLoc[1] - origLoc[1]);
465 det = u_loc[0] * v_loc[1] - v_loc[0] * u_loc[1];
467 x_loc =
static_cast<double>(tmpSensor[0]) -
static_cast<double>(origLoc[0]);
468 y_loc =
static_cast<double>(tmpSensor[1]) -
static_cast<double>(origLoc[1]);
470 a_grid = (x_loc * v_loc[1] - y_loc * v_loc[0]) / det;
471 b_grid = (y_loc * u_loc[0] - x_loc * u_loc[1]) / det;
473 gridContiIndex[0] =
static_cast<double>(gridIndex[0]) + a_grid;
474 gridContiIndex[1] =
static_cast<double>(gridIndex[1]) + b_grid;
476 leftGrid->TransformContinuousIndexToPhysicalPoint(gridContiIndex, epiPosition);
478 horizDisp->TransformPhysicalPointToContinuousIndex(epiPosition, epiContiIndex);
480 if (0.0 < a_grid && a_grid < 1.0 && 0.0 < b_grid && b_grid < 1.0)
488 int a_grid_int =
static_cast<int>(gridIndex[0]) +
static_cast<int>(std::floor(a_grid));
489 int b_grid_int =
static_cast<int>(gridIndex[1]) +
static_cast<int>(std::floor(b_grid));
491 if (a_grid_int < minGridIndex[0])
492 a_grid_int = minGridIndex[0];
493 if (a_grid_int > maxGridIndex[0])
494 a_grid_int = maxGridIndex[0];
495 if (b_grid_int < minGridIndex[1])
496 b_grid_int = minGridIndex[1];
497 if (b_grid_int > maxGridIndex[1])
498 b_grid_int = maxGridIndex[1];
500 gridIndex[0] = a_grid_int;
501 gridIndex[1] = b_grid_int;
507 epiIndexMin[0] = epiContiIndex[0];
508 epiIndexMin[1] = epiContiIndex[1];
509 epiIndexMax[0] = epiContiIndex[0];
510 epiIndexMax[1] = epiContiIndex[1];
514 if (epiContiIndex[0] < epiIndexMin[0])
515 epiIndexMin[0] = epiContiIndex[0];
516 if (epiContiIndex[1] < epiIndexMin[1])
517 epiIndexMin[1] = epiContiIndex[1];
518 if (epiIndexMax[0] < epiContiIndex[0])
519 epiIndexMax[0] = epiContiIndex[0];
520 if (epiIndexMax[1] < epiContiIndex[1])
521 epiIndexMax[1] = epiContiIndex[1];
525 typename DisparityMapType::RegionType inputDisparityRegion;
526 inputDisparityRegion.SetIndex(0,
static_cast<int>(std::floor(epiIndexMin[0] + 0.5)));
527 inputDisparityRegion.SetIndex(1,
static_cast<int>(std::floor(epiIndexMin[1] + 0.5)));
528 inputDisparityRegion.SetSize(0, 1 +
static_cast<unsigned int>(std::floor(epiIndexMax[0] - epiIndexMin[0] + 0.5)));
529 inputDisparityRegion.SetSize(1, 1 +
static_cast<unsigned int>(std::floor(epiIndexMax[1] - epiIndexMin[1] + 0.5)));
532 if (inputDisparityRegion.Crop(horizDisp->GetLargestPossibleRegion()))
534 horizDisp->SetRequestedRegion(inputDisparityRegion);
535 vertiDisp->SetRequestedRegion(inputDisparityRegion);
539 maskDisp->SetRequestedRegion(inputDisparityRegion);
545 typename DisparityMapType::RegionType emptyRegion;
547 emptyRegion.SetIndex(horizDisp->GetLargestPossibleRegion().GetIndex());
548 emptyRegion.SetSize(0, 0);
549 emptyRegion.SetSize(1, 0);
551 horizDisp->SetRequestedRegion(emptyRegion);
552 vertiDisp->SetRequestedRegion(emptyRegion);
555 maskDisp->SetRequestedRegion(emptyRegion);
564 horizDisp->SetRequestedRegion(inputDisparityRegion);
565 vertiDisp->SetRequestedRegion(inputDisparityRegion);
568 itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
569 std::ostringstream msg;
570 msg << this->GetNameOfClass() <<
"::GenerateInputRequestedRegion()";
571 e.SetLocation(msg.str());
572 e.SetDescription(
"Requested region is (at least partially) outside the largest possible region of disparity map.");
573 e.SetDataObject(horizDisp);
579 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
582 const TDisparityImage* horizDisp = this->GetHorizontalDisparityMapInput();
583 const TInputImage* leftSensor = this->GetLeftInput();
584 const TInputImage* rightSensor = this->GetRightInput();
586 const TOutputDEMImage* outputDEM = this->GetDEMOutput();
588 typename DisparityMapType::RegionType requestedRegion = horizDisp->GetRequestedRegion();
590 m_UsedInputSplits = m_InputSplitter->GetNumberOfSplits(requestedRegion, this->GetNumberOfWorkUnits());
592 m_LeftToGroundTransform = RSTransformType::New();
593 m_RightToGroundTransform = RSTransformType::New();
595 m_LeftToGroundTransform->SetInputImageMetadata(&(leftSensor->GetImageMetadata()));
596 m_RightToGroundTransform->SetInputImageMetadata(&(rightSensor->GetImageMetadata()));
598 m_LeftToGroundTransform->InstantiateTransform();
599 m_RightToGroundTransform->InstantiateTransform();
602 if (requestedRegion.GetSize(0) == 0 && requestedRegion.GetSize(1) == 0)
604 m_UsedInputSplits = 0;
607 if (m_UsedInputSplits <=
static_cast<unsigned int>(this->GetNumberOfWorkUnits()))
609 m_TempDEMRegions.clear();
611 for (
unsigned int i = 0; i < m_UsedInputSplits; i++)
613 typename DEMImageType::Pointer tmpImg = TOutputDEMImage::New();
614 tmpImg->SetNumberOfComponentsPerPixel(1);
615 tmpImg->SetRegions(outputDEM->GetRequestedRegion());
618 typename DEMImageType::PixelType minElevation =
static_cast<typename DEMImageType::PixelType
>(m_ElevationMin);
619 tmpImg->FillBuffer(minElevation);
621 m_TempDEMRegions.push_back(tmpImg);
626 itkExceptionMacro(<<
"Wrong number of splits for input multithreading : " << m_UsedInputSplits);
630 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
632 const RegionType& itkNotUsed(outputRegionForThread), itk::ThreadIdType threadId)
634 const TDisparityImage* horizDisp = this->GetHorizontalDisparityMapInput();
635 const TDisparityImage* vertiDisp = this->GetVerticalDisparityMapInput();
637 const TMaskImage* disparityMask = this->GetDisparityMaskInput();
639 const TOutputDEMImage* outputDEM = this->GetDEMOutput();
641 const TEpipolarGridImage* leftGrid = this->GetLeftEpipolarGridInput();
642 const TEpipolarGridImage* rightGrid = this->GetRightEpipolarGridInput();
644 typename TEpipolarGridImage::RegionType gridRegion = leftGrid->GetLargestPossibleRegion();
646 TOutputDEMImage* tmpDEM =
nullptr;
647 typename TOutputDEMImage::RegionType outputRequestedRegion = outputDEM->GetRequestedRegion();
649 typename TDisparityImage::RegionType disparityRegion;
650 if (
static_cast<unsigned int>(threadId) < m_UsedInputSplits)
652 disparityRegion = m_InputSplitter->GetSplit(threadId, m_UsedInputSplits, horizDisp->GetRequestedRegion());
653 tmpDEM = m_TempDEMRegions[threadId];
660 itk::ImageRegionConstIteratorWithIndex<DisparityMapType> horizIt(horizDisp, disparityRegion);
661 itk::ImageRegionConstIteratorWithIndex<DisparityMapType> vertiIt(vertiDisp, disparityRegion);
666 bool useMask =
false;
667 itk::ImageRegionConstIterator<MaskImageType> maskIt;
671 maskIt = itk::ImageRegionConstIterator<MaskImageType>(disparityMask, disparityRegion);
675 typename TDisparityImage::PointType epiPoint;
676 itk::ContinuousIndex<double, 2> gridIndexConti;
677 double subPixIndex[2];
678 typename GridImageType::IndexType ulIndex, urIndex, lrIndex, llIndex;
679 typename GridImageType::PixelType ulPixel(2);
680 typename GridImageType::PixelType urPixel(2);
681 typename GridImageType::PixelType lrPixel(2);
682 typename GridImageType::PixelType llPixel(2);
683 typename GridImageType::PixelType cPixel(2);
685 typename GridImageType::PointType ulPoint;
686 typename GridImageType::PointType urPoint;
687 typename GridImageType::PointType lrPoint;
688 typename GridImageType::PointType llPoint;
696 while (!horizIt.IsAtEnd() && !vertiIt.IsAtEnd())
701 if (!(maskIt.Get() > 0))
711 horizDisp->TransformIndexToPhysicalPoint(horizIt.GetIndex(), epiPoint);
712 leftGrid->TransformPhysicalPointToContinuousIndex(epiPoint, gridIndexConti);
714 ulIndex[0] =
static_cast<int>(std::floor(gridIndexConti[0]));
715 ulIndex[1] =
static_cast<int>(std::floor(gridIndexConti[1]));
716 if (ulIndex[0] < gridRegion.GetIndex(0))
717 ulIndex[0] = gridRegion.GetIndex(0);
718 if (ulIndex[1] < gridRegion.GetIndex(1))
719 ulIndex[1] = gridRegion.GetIndex(1);
720 if (ulIndex[0] > (gridRegion.GetIndex(0) +
static_cast<int>(gridRegion.GetSize(0)) - 2))
722 ulIndex[0] = gridRegion.GetIndex(0) + gridRegion.GetSize(0) - 2;
724 if (ulIndex[1] > (gridRegion.GetIndex(1) +
static_cast<int>(gridRegion.GetSize(1)) - 2))
726 ulIndex[1] = gridRegion.GetIndex(1) + gridRegion.GetSize(1) - 2;
728 urIndex[0] = ulIndex[0] + 1;
729 urIndex[1] = ulIndex[1];
730 lrIndex[0] = ulIndex[0] + 1;
731 lrIndex[1] = ulIndex[1] + 1;
732 llIndex[0] = ulIndex[0];
733 llIndex[1] = ulIndex[1] + 1;
734 subPixIndex[0] = gridIndexConti[0] -
static_cast<double>(ulIndex[0]);
735 subPixIndex[1] = gridIndexConti[1] -
static_cast<double>(ulIndex[1]);
737 leftGrid->TransformIndexToPhysicalPoint(ulIndex, ulPoint);
738 leftGrid->TransformIndexToPhysicalPoint(urIndex, urPoint);
739 leftGrid->TransformIndexToPhysicalPoint(lrIndex, lrPoint);
740 leftGrid->TransformIndexToPhysicalPoint(llIndex, llPoint);
742 ulPixel[0] = (leftGrid->GetPixel(ulIndex))[0] + ulPoint[0];
743 ulPixel[1] = (leftGrid->GetPixel(ulIndex))[1] + ulPoint[1];
744 urPixel[0] = (leftGrid->GetPixel(urIndex))[0] + urPoint[0];
745 urPixel[1] = (leftGrid->GetPixel(urIndex))[1] + urPoint[1];
746 lrPixel[0] = (leftGrid->GetPixel(lrIndex))[0] + lrPoint[0];
747 lrPixel[1] = (leftGrid->GetPixel(lrIndex))[1] + lrPoint[1];
748 llPixel[0] = (leftGrid->GetPixel(llIndex))[0] + llPoint[0];
749 llPixel[1] = (leftGrid->GetPixel(llIndex))[1] + llPoint[1];
750 cPixel = (ulPixel * (1.0 - subPixIndex[0]) + urPixel * subPixIndex[0]) * (1.0 - subPixIndex[1]) +
751 (llPixel * (1.0 - subPixIndex[0]) + lrPixel * subPixIndex[0]) * subPixIndex[1];
753 sensorPoint[0] = cPixel[0];
754 sensorPoint[1] = cPixel[1];
755 sensorPoint[2] = m_ElevationMin;
756 leftGroundHmin = m_LeftToGroundTransform->TransformPoint(sensorPoint);
758 sensorPoint[2] = m_ElevationMax;
759 leftGroundHmax = m_LeftToGroundTransform->TransformPoint(sensorPoint);
762 itk::ContinuousIndex<double, 2> rightIndexEstimate;
763 rightIndexEstimate[0] =
static_cast<double>((horizIt.GetIndex())[0]) +
static_cast<double>(horizIt.Get());
764 rightIndexEstimate[1] =
static_cast<double>((horizIt.GetIndex())[1]) +
static_cast<double>(vertiIt.Get());
766 horizDisp->TransformContinuousIndexToPhysicalPoint(rightIndexEstimate, epiPoint);
767 rightGrid->TransformPhysicalPointToContinuousIndex(epiPoint, gridIndexConti);
769 ulIndex[0] =
static_cast<int>(std::floor(gridIndexConti[0]));
770 ulIndex[1] =
static_cast<int>(std::floor(gridIndexConti[1]));
771 if (ulIndex[0] < gridRegion.GetIndex(0))
772 ulIndex[0] = gridRegion.GetIndex(0);
773 if (ulIndex[1] < gridRegion.GetIndex(1))
774 ulIndex[1] = gridRegion.GetIndex(1);
775 if (ulIndex[0] > (gridRegion.GetIndex(0) +
static_cast<int>(gridRegion.GetSize(0)) - 2))
777 ulIndex[0] = gridRegion.GetIndex(0) + gridRegion.GetSize(0) - 2;
779 if (ulIndex[1] > (gridRegion.GetIndex(1) +
static_cast<int>(gridRegion.GetSize(1)) - 2))
781 ulIndex[1] = gridRegion.GetIndex(1) + gridRegion.GetSize(1) - 2;
783 urIndex[0] = ulIndex[0] + 1;
784 urIndex[1] = ulIndex[1];
785 lrIndex[0] = ulIndex[0] + 1;
786 lrIndex[1] = ulIndex[1] + 1;
787 llIndex[0] = ulIndex[0];
788 llIndex[1] = ulIndex[1] + 1;
789 subPixIndex[0] = gridIndexConti[0] -
static_cast<double>(ulIndex[0]);
790 subPixIndex[1] = gridIndexConti[1] -
static_cast<double>(ulIndex[1]);
792 rightGrid->TransformIndexToPhysicalPoint(ulIndex, ulPoint);
793 rightGrid->TransformIndexToPhysicalPoint(urIndex, urPoint);
794 rightGrid->TransformIndexToPhysicalPoint(lrIndex, lrPoint);
795 rightGrid->TransformIndexToPhysicalPoint(llIndex, llPoint);
797 ulPixel[0] = (rightGrid->GetPixel(ulIndex))[0] + ulPoint[0];
798 ulPixel[1] = (rightGrid->GetPixel(ulIndex))[1] + ulPoint[1];
799 urPixel[0] = (rightGrid->GetPixel(urIndex))[0] + urPoint[0];
800 urPixel[1] = (rightGrid->GetPixel(urIndex))[1] + urPoint[1];
801 lrPixel[0] = (rightGrid->GetPixel(lrIndex))[0] + lrPoint[0];
802 lrPixel[1] = (rightGrid->GetPixel(lrIndex))[1] + lrPoint[1];
803 llPixel[0] = (rightGrid->GetPixel(llIndex))[0] + llPoint[0];
804 llPixel[1] = (rightGrid->GetPixel(llIndex))[1] + llPoint[1];
805 cPixel = (ulPixel * (1.0 - subPixIndex[0]) + urPixel * subPixIndex[0]) * (1.0 - subPixIndex[1]) +
806 (llPixel * (1.0 - subPixIndex[0]) + lrPixel * subPixIndex[0]) * subPixIndex[1];
808 sensorPoint[0] = cPixel[0];
809 sensorPoint[1] = cPixel[1];
810 sensorPoint[2] = m_ElevationMin;
811 rightGroundHmin = m_RightToGroundTransform->TransformPoint(sensorPoint);
813 sensorPoint[2] = m_ElevationMax;
814 rightGroundHmax = m_RightToGroundTransform->TransformPoint(sensorPoint);
817 double a = (leftGroundHmax[0] - leftGroundHmin[0]) * (leftGroundHmax[0] - leftGroundHmin[0]) +
818 (leftGroundHmax[1] - leftGroundHmin[1]) * (leftGroundHmax[1] - leftGroundHmin[1]) +
819 (leftGroundHmax[2] - leftGroundHmin[2]) * (leftGroundHmax[2] - leftGroundHmin[2]);
820 double b = (rightGroundHmax[0] - rightGroundHmin[0]) * (rightGroundHmax[0] - rightGroundHmin[0]) +
821 (rightGroundHmax[1] - rightGroundHmin[1]) * (rightGroundHmax[1] - rightGroundHmin[1]) +
822 (rightGroundHmax[2] - rightGroundHmin[2]) * (rightGroundHmax[2] - rightGroundHmin[2]);
823 double c = -(leftGroundHmax[0] - leftGroundHmin[0]) * (rightGroundHmax[0] - rightGroundHmin[0]) -
824 (leftGroundHmax[1] - leftGroundHmin[1]) * (rightGroundHmax[1] - rightGroundHmin[1]) -
825 (leftGroundHmax[2] - leftGroundHmin[2]) * (rightGroundHmax[2] - rightGroundHmin[2]);
826 double g = (leftGroundHmax[0] - leftGroundHmin[0]) * (rightGroundHmin[0] - leftGroundHmin[0]) +
827 (leftGroundHmax[1] - leftGroundHmin[1]) * (rightGroundHmin[1] - leftGroundHmin[1]) +
828 (leftGroundHmax[2] - leftGroundHmin[2]) * (rightGroundHmin[2] - leftGroundHmin[2]);
829 double h = -(rightGroundHmax[0] - rightGroundHmin[0]) * (rightGroundHmin[0] - leftGroundHmin[0]) -
830 (rightGroundHmax[1] - rightGroundHmin[1]) * (rightGroundHmin[1] - leftGroundHmin[1]) -
831 (rightGroundHmax[2] - rightGroundHmin[2]) * (rightGroundHmin[2] - leftGroundHmin[2]);
833 double rLeft = (b * g - c * h) / (a * b - c * c);
834 double rRight = (a * h - c * g) / (a * b - c * c);
837 leftFoot.SetToBarycentricCombination(leftGroundHmax, leftGroundHmin, rLeft);
840 rightFoot.SetToBarycentricCombination(rightGroundHmax, rightGroundHmin, rRight);
843 midPoint3D.SetToMidPoint(leftFoot, rightFoot);
846 typename DEMImageType::PointType midPoint2D;
847 midPoint2D[0] = midPoint3D[0];
848 midPoint2D[1] = midPoint3D[1];
849 itk::ContinuousIndex<double, 2> midIndex;
850 outputDEM->TransformPhysicalPointToContinuousIndex(midPoint2D, midIndex);
851 typename DEMImageType::IndexType cellIndex;
856 cellIndex[0] =
static_cast<int>(std::floor(midIndex[0] + 0.5));
857 cellIndex[1] =
static_cast<int>(std::floor(midIndex[1] + 0.5));
859 if (outputRequestedRegion.IsInside(cellIndex))
866 if (cellHeight > tmpDEM->GetPixel(cellIndex) && cellHeight < static_cast<DEMPixelType>(m_ElevationMax))
868 tmpDEM->SetPixel(cellIndex, cellHeight);
880 template <
class TDisparityImage,
class TInputImage,
class TOutputDEMImage,
class TEpipolarGr
idImage,
class TMaskImage>
883 TOutputDEMImage* outputDEM = this->GetDEMOutput();
885 if (m_TempDEMRegions.size() < 1)
887 outputDEM->FillBuffer(m_ElevationMin);
891 itk::ImageRegionIterator<DEMImageType> outputDEMIt(outputDEM, outputDEM->GetRequestedRegion());
892 itk::ImageRegionIterator<DEMImageType> firstDEMIt(m_TempDEMRegions[0], outputDEM->GetRequestedRegion());
894 outputDEMIt.GoToBegin();
895 firstDEMIt.GoToBegin();
898 while (!outputDEMIt.IsAtEnd() && !firstDEMIt.IsAtEnd())
900 outputDEMIt.Set(firstDEMIt.Get());
906 for (
unsigned int i = 1; i < m_TempDEMRegions.size(); i++)
908 itk::ImageRegionIterator<DEMImageType> tmpDEMIt(m_TempDEMRegions[i], outputDEM->GetRequestedRegion());
910 outputDEMIt.GoToBegin();
911 tmpDEMIt.GoToBegin();
913 while (!outputDEMIt.IsAtEnd() && !tmpDEMIt.IsAtEnd())
915 if (tmpDEMIt.Get() > outputDEMIt.Get())
917 outputDEMIt.Set(tmpDEMIt.Get());
void GenerateInputRequestedRegion() override
void BeforeThreadedGenerateData() override
const TMaskImage * GetDisparityMaskInput() const
DEMImageType::RegionType RegionType
void SetLeftEpipolarGridInput(const TEpipolarGridImage *grid)
const TDisparityImage * GetHorizontalDisparityMapInput() const
void SetRightEpipolarGridInput(const TEpipolarGridImage *grid)
RSTransformType::InputPointType TDPointType
DEMImageType::PixelType DEMPixelType
const TInputImage * GetLeftInput() const
void SetLeftInput(const TInputImage *image)
void SetVerticalDisparityMapInput(const TDisparityImage *vmap)
void ThreadedGenerateData(const RegionType &outputRegionForThread, itk::ThreadIdType threadId) override
const TEpipolarGridImage * GetLeftEpipolarGridInput() const
const TEpipolarGridImage * GetRightEpipolarGridInput() const
DisparityMapToDEMFilter()
void GenerateOutputInformation() override
const TInputImage * GetRightInput() const
void SetDisparityMaskInput(const TMaskImage *mask)
const TDisparityImage * GetVerticalDisparityMapInput() const
void AfterThreadedGenerateData() override
~DisparityMapToDEMFilter() override
const TOutputDEMImage * GetDEMOutput() const
void SetHorizontalDisparityMapInput(const TDisparityImage *hmap)
void SetRightInput(const TInputImage *image)
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.