21 #ifndef otbDisparityTranslateFilter_hxx
22 #define otbDisparityTranslateFilter_hxx
26 #include "itkImageRegionIteratorWithIndex.h"
27 #include "itkImageRegionIterator.h"
33 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
35 : m_NoDataValue(-32768)
37 this->DynamicMultiThreadingOn();
39 this->SetNumberOfRequiredInputs(6);
40 this->SetNumberOfRequiredInputs(1);
43 this->SetNumberOfRequiredOutputs(2);
44 this->SetNthOutput(0, TDisparityImage::New());
45 this->SetNthOutput(1, TDisparityImage::New());
48 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
52 this->SetNthInput(0,
const_cast<TDisparityImage*
>(hmap));
55 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
59 this->SetNthInput(1,
const_cast<TDisparityImage*
>(vmap));
62 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
66 this->SetNthInput(2,
const_cast<TGridImage*
>(lgrid));
69 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
73 this->SetNthInput(3,
const_cast<TGridImage*
>(rgrid));
76 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
80 this->SetNthInput(4,
const_cast<TMaskImage*
>(mask));
83 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
87 this->SetNthInput(5,
const_cast<TSensorImage*
>(left));
90 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
93 if (this->GetNumberOfInputs() < 1)
97 return static_cast<const TDisparityImage*
>(this->itk::ProcessObject::GetInput(0));
100 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
103 if (this->GetNumberOfInputs() < 2)
107 return static_cast<const TDisparityImage*
>(this->itk::ProcessObject::GetInput(1));
110 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
113 if (this->GetNumberOfInputs() < 3)
117 return static_cast<const TGridImage*
>(this->itk::ProcessObject::GetInput(2));
120 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
123 if (this->GetNumberOfInputs() < 4)
127 return static_cast<const TGridImage*
>(this->itk::ProcessObject::GetInput(3));
130 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
133 if (this->GetNumberOfInputs() < 5)
137 return static_cast<const TMaskImage*
>(this->itk::ProcessObject::GetInput(4));
140 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
143 if (this->GetNumberOfInputs() < 6)
147 return static_cast<const TSensorImage*
>(this->itk::ProcessObject::GetInput(5));
150 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
153 if (this->GetNumberOfOutputs() < 1)
157 return static_cast<TDisparityImage*
>(this->itk::ProcessObject::GetOutput(0));
160 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
163 if (this->GetNumberOfOutputs() < 2)
167 return static_cast<TDisparityImage*
>(this->itk::ProcessObject::GetOutput(1));
170 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
175 TDisparityImage* horizOut = this->GetHorizontalDisparityMapOutput();
176 TDisparityImage* vertiOut = this->GetVerticalDisparityMapOutput();
178 const TSensorImage* leftIn = this->GetLeftSensorImageInput();
180 horizOut->CopyInformation(leftIn);
181 vertiOut->CopyInformation(leftIn);
184 std::vector<bool> noDataValueAvailable = {
true};
185 std::vector<double> noDataValue = {m_NoDataValue};
187 WriteNoDataFlags(noDataValueAvailable, noDataValue, horizOut->GetImageMetadata());
188 WriteNoDataFlags(noDataValueAvailable, noDataValue, vertiOut->GetImageMetadata());
191 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
194 this->Superclass::GenerateInputRequestedRegion();
196 TGridImage* leftGrid =
const_cast<TGridImage*
>(this->GetInverseEpipolarLeftGrid());
197 TGridImage* rightGrid =
const_cast<TGridImage*
>(this->GetDirectEpipolarRightGrid());
199 leftGrid->SetRequestedRegionToLargestPossibleRegion();
200 rightGrid->SetRequestedRegionToLargestPossibleRegion();
202 leftGrid->UpdateOutputData();
203 rightGrid->UpdateOutputData();
205 TSensorImage* leftIn =
const_cast<TSensorImage*
>(this->GetLeftSensorImageInput());
206 RegionType emptyRegion = leftIn->GetLargestPossibleRegion();
207 emptyRegion.SetSize(0, 0);
208 emptyRegion.SetSize(1, 0);
209 leftIn->SetRequestedRegion(emptyRegion);
211 TDisparityImage* horizOut = this->GetHorizontalDisparityMapOutput();
213 TDisparityImage* horizIn =
const_cast<TDisparityImage*
>(this->GetHorizontalDisparityMapInput());
214 TDisparityImage* vertiIn =
const_cast<TDisparityImage*
>(this->GetVerticalDisparityMapInput());
216 TMaskImage* maskIn =
const_cast<TMaskImage*
>(this->GetDisparityMaskInput());
218 RegionType requested = this->GetHorizontalDisparityMapOutput()->GetRequestedRegion();
219 RegionType inputlargest = this->GetHorizontalDisparityMapInput()->GetLargestPossibleRegion();
221 GridRegionType gridLargest = leftGrid->GetLargestPossibleRegion();
225 minIndex.Fill(itk::NumericTraits<IndexValueType>::Zero);
226 maxIndex.Fill(itk::NumericTraits<IndexValueType>::Zero);
229 for (
int i = 0; i < 4; i++)
230 corners[i].Fill(itk::NumericTraits<IndexValueType>::Zero);
232 corners[0] = requested.GetIndex();
233 corners[1] = requested.GetIndex();
234 corners[1][0] +=
static_cast<IndexValueType>(requested.GetSize()[0]) - 1;
235 corners[2] = requested.GetIndex();
236 corners[2][1] +=
static_cast<IndexValueType>(requested.GetSize()[1]) - 1;
237 corners[3] = requested.GetIndex();
238 corners[3][0] +=
static_cast<IndexValueType>(requested.GetSize()[0]) - 1;
239 corners[3][1] +=
static_cast<IndexValueType>(requested.GetSize()[1]) - 1;
240 for (
unsigned int k = 0; k < 4; ++k)
243 horizOut->TransformIndexToPhysicalPoint(corners[k], pointSensor);
244 itk::ContinuousIndex<double, 2> indexGrid;
245 leftGrid->TransformPhysicalPointToContinuousIndex(pointSensor, indexGrid);
247 ul[0] =
static_cast<long>(std::floor(indexGrid[0]));
248 ul[1] =
static_cast<long>(std::floor(indexGrid[1]));
249 if (ul[0] < gridLargest.GetIndex()[0])
250 ul[0] = gridLargest.GetIndex()[0];
251 if (ul[1] < gridLargest.GetIndex()[1])
252 ul[1] = gridLargest.GetIndex()[1];
253 if (ul[0] >
static_cast<IndexValueType>(gridLargest.GetIndex()[0] + gridLargest.GetSize()[0] - 2))
254 ul[0] = (gridLargest.GetIndex()[0] + gridLargest.GetSize()[0] - 2);
255 if (ul[1] >
static_cast<IndexValueType>(gridLargest.GetIndex()[1] + gridLargest.GetSize()[1] - 2))
256 ul[1] = (gridLargest.GetIndex()[1] + gridLargest.GetSize()[1] - 2);
266 double rx = indexGrid[0] -
static_cast<double>(ul[0]);
267 double ry = indexGrid[1] -
static_cast<double>(ul[1]);
270 pointEpi[0] += (1. - ry) * ((1. - rx) * leftGrid->GetPixel(ul)[0] + rx * leftGrid->GetPixel(ur)[0]) +
271 ry * ((1. - rx) * leftGrid->GetPixel(ll)[0] + rx * leftGrid->GetPixel(lr)[0]);
272 pointEpi[1] += (1. - ry) * ((1. - rx) * leftGrid->GetPixel(ul)[1] + rx * leftGrid->GetPixel(ur)[1]) +
273 ry * ((1. - rx) * leftGrid->GetPixel(ll)[1] + rx * leftGrid->GetPixel(lr)[1]);
274 itk::ContinuousIndex<double, 2> indexEpi;
276 horizIn->TransformPhysicalPointToContinuousIndex(pointEpi, indexEpi);
279 minIndex[0] =
static_cast<long>(std::floor(indexEpi[0]));
280 minIndex[1] =
static_cast<long>(std::floor(indexEpi[1]));
281 maxIndex[0] =
static_cast<long>(std::ceil(indexEpi[0]));
282 maxIndex[1] =
static_cast<long>(std::ceil(indexEpi[1]));
286 if (minIndex[0] >
static_cast<long>(std::floor(indexEpi[0])))
287 minIndex[0] =
static_cast<long>(std::floor(indexEpi[0]));
288 if (minIndex[1] >
static_cast<long>(std::floor(indexEpi[1])))
289 minIndex[1] =
static_cast<long>(std::floor(indexEpi[1]));
290 if (maxIndex[0] <
static_cast<long>(std::ceil(indexEpi[0])))
291 maxIndex[0] =
static_cast<long>(std::ceil(indexEpi[0]));
292 if (maxIndex[1] <
static_cast<long>(std::ceil(indexEpi[1])))
293 maxIndex[1] =
static_cast<long>(std::ceil(indexEpi[1]));
297 inputRequested.SetIndex(minIndex);
298 inputRequested.SetSize(0,
static_cast<unsigned long>(maxIndex[0] - minIndex[0]));
299 inputRequested.SetSize(1,
static_cast<unsigned long>(maxIndex[1] - minIndex[1]));
301 if (!inputRequested.Crop(inputlargest))
303 inputRequested.SetSize(0, 0);
304 inputRequested.SetSize(1, 0);
305 inputRequested.SetIndex(inputlargest.GetIndex());
308 horizIn->SetRequestedRegion(inputRequested);
310 vertiIn->SetRequestedRegion(inputRequested);
312 maskIn->SetRequestedRegion(inputRequested);
315 template <
class TDisparityImage,
class TGr
idImage,
class TSensorImage,
class TMaskImage>
318 const TGridImage* leftGrid = this->GetInverseEpipolarLeftGrid();
319 const TGridImage* rightGrid = this->GetDirectEpipolarRightGrid();
321 TDisparityImage* horizOut = this->GetHorizontalDisparityMapOutput();
322 TDisparityImage* vertiOut = this->GetVerticalDisparityMapOutput();
324 const TDisparityImage* horizIn = this->GetHorizontalDisparityMapInput();
325 const TDisparityImage* vertiIn = this->GetVerticalDisparityMapInput();
327 const TMaskImage* maskIn = this->GetDisparityMaskInput();
329 GridRegionType leftLargest = leftGrid->GetLargestPossibleRegion();
330 GridRegionType rightLargest = rightGrid->GetLargestPossibleRegion();
331 RegionType buffered = horizIn->GetBufferedRegion();
333 const bool emptyInputRegion = buffered.GetNumberOfPixels() == 0;
335 typedef itk::ImageRegionIteratorWithIndex<TDisparityImage> DispIterator;
336 DispIterator horizIter(horizOut, outputRegionForThread);
337 DispIterator vertiIter(vertiOut, outputRegionForThread);
339 horizIter.GoToBegin();
340 vertiIter.GoToBegin();
342 while (!horizIter.IsAtEnd() && !vertiIter.IsAtEnd())
345 if (!emptyInputRegion)
348 horizOut->TransformIndexToPhysicalPoint(horizIter.GetIndex(), pointSensor);
350 itk::ContinuousIndex<double, 2> indexGrid;
351 leftGrid->TransformPhysicalPointToContinuousIndex(pointSensor, indexGrid);
355 ul[0] =
static_cast<long>(std::floor(indexGrid[0]));
356 ul[1] =
static_cast<long>(std::floor(indexGrid[1]));
357 if (ul[0] < leftLargest.GetIndex()[0])
358 ul[0] = leftLargest.GetIndex()[0];
359 if (ul[1] < leftLargest.GetIndex()[1])
360 ul[1] = leftLargest.GetIndex()[1];
361 if (ul[0] >
static_cast<IndexValueType>(leftLargest.GetIndex()[0] + leftLargest.GetSize()[0] - 2))
362 ul[0] = (leftLargest.GetIndex()[0] + leftLargest.GetSize()[0] - 2);
363 if (ul[1] >
static_cast<IndexValueType>(leftLargest.GetIndex()[1] + leftLargest.GetSize()[1] - 2))
364 ul[1] = (leftLargest.GetIndex()[1] + leftLargest.GetSize()[1] - 2);
374 double rx = indexGrid[0] -
static_cast<double>(ul[0]);
375 double ry = indexGrid[1] -
static_cast<double>(ul[1]);
378 pointEpi[0] += (1. - ry) * ((1. - rx) * leftGrid->GetPixel(ul)[0] + rx * leftGrid->GetPixel(ur)[0]) +
379 ry * ((1. - rx) * leftGrid->GetPixel(ll)[0] + rx * leftGrid->GetPixel(lr)[0]);
380 pointEpi[1] += (1. - ry) * ((1. - rx) * leftGrid->GetPixel(ul)[1] + rx * leftGrid->GetPixel(ur)[1]) +
381 ry * ((1. - rx) * leftGrid->GetPixel(ll)[1] + rx * leftGrid->GetPixel(lr)[1]);
383 itk::ContinuousIndex<double, 2> indexEpi;
384 horizIn->TransformPhysicalPointToContinuousIndex(pointEpi, indexEpi);
387 ul[0] =
static_cast<long>(std::floor(indexEpi[0]));
388 ul[1] =
static_cast<long>(std::floor(indexEpi[1]));
389 if (ul[0] < buffered.GetIndex()[0])
390 ul[0] = buffered.GetIndex()[0];
391 if (ul[1] < buffered.GetIndex()[1])
392 ul[1] = buffered.GetIndex()[1];
393 if (ul[0] >
static_cast<IndexValueType>(buffered.GetIndex()[0] + buffered.GetSize()[0] - 2))
394 ul[0] = (buffered.GetIndex()[0] + buffered.GetSize()[0] - 2);
395 if (ul[1] >
static_cast<IndexValueType>(buffered.GetIndex()[1] + buffered.GetSize()[1] - 2))
396 ul[1] = (buffered.GetIndex()[1] + buffered.GetSize()[1] - 2);
407 if (!maskIn || (maskIn && maskIn->GetPixel(ul) > 0 && maskIn->GetPixel(ur) > 0 && maskIn->GetPixel(ll) > 0 && maskIn->GetPixel(lr) > 0))
409 rx = indexEpi[0] -
static_cast<double>(ul[0]);
410 ry = indexEpi[1] -
static_cast<double>(ul[1]);
412 itk::ContinuousIndex<double, 2> indexRight(indexEpi);
414 indexRight[0] += (1. - ry) * ((1. - rx) * horizIn->GetPixel(ul) + rx * horizIn->GetPixel(ur)) +
415 ry * ((1. - rx) * horizIn->GetPixel(ll) + rx * horizIn->GetPixel(lr));
418 indexRight[1] += (1. - ry) * ((1. - rx) * vertiIn->GetPixel(ul) + rx * vertiIn->GetPixel(ur)) +
419 ry * ((1. - rx) * vertiIn->GetPixel(ll) + rx * vertiIn->GetPixel(lr));
423 horizIn->TransformContinuousIndexToPhysicalPoint(indexRight, pointRight);
425 itk::ContinuousIndex<double, 2> indexGridRight;
426 rightGrid->TransformPhysicalPointToContinuousIndex(pointRight, indexGridRight);
429 ul[0] =
static_cast<long>(std::floor(indexGridRight[0]));
430 ul[1] =
static_cast<long>(std::floor(indexGridRight[1]));
431 if (ul[0] < rightLargest.GetIndex()[0])
432 ul[0] = rightLargest.GetIndex()[0];
433 if (ul[1] < rightLargest.GetIndex()[1])
434 ul[1] = rightLargest.GetIndex()[1];
435 if (ul[0] >
static_cast<IndexValueType>(rightLargest.GetIndex()[0] + rightLargest.GetSize()[0] - 2))
436 ul[0] = (rightLargest.GetIndex()[0] + rightLargest.GetSize()[0] - 2);
437 if (ul[1] >
static_cast<IndexValueType>(rightLargest.GetIndex()[1] + rightLargest.GetSize()[1] - 2))
438 ul[1] = (rightLargest.GetIndex()[1] + rightLargest.GetSize()[1] - 2);
448 rx = indexGridRight[0] -
static_cast<double>(ul[0]);
449 ry = indexGridRight[1] -
static_cast<double>(ul[1]);
453 pointSensorRight[0] += (1. - ry) * ((1. - rx) * rightGrid->GetPixel(ul)[0] + rx * rightGrid->GetPixel(ur)[0]) +
454 ry * ((1. - rx) * rightGrid->GetPixel(ll)[0] + rx * rightGrid->GetPixel(lr)[0]);
455 pointSensorRight[1] += (1. - ry) * ((1. - rx) * rightGrid->GetPixel(ul)[1] + rx * rightGrid->GetPixel(ur)[1]) +
456 ry * ((1. - rx) * rightGrid->GetPixel(ll)[1] + rx * rightGrid->GetPixel(lr)[1]);
458 horizIter.Set(pointSensorRight[0] - pointSensor[0]);
459 vertiIter.Set(pointSensorRight[1] - pointSensor[1]);
463 horizIter.Set(m_NoDataValue);
464 vertiIter.Set(m_NoDataValue);
469 horizIter.Set(m_NoDataValue);
470 vertiIter.Set(m_NoDataValue);
GridType::RegionType GridRegionType
DispMapType::IndexType IndexType
DispMapType::RegionType RegionType
void SetVerticalDisparityMapInput(const TDisparityImage *vmap)
const TDisparityImage * GetVerticalDisparityMapInput() const
void DynamicThreadedGenerateData(const RegionType &outputRegionForThread) override
const TDisparityImage * GetHorizontalDisparityMapInput() const
void SetLeftSensorImageInput(const TSensorImage *left)
const TGridImage * GetInverseEpipolarLeftGrid() const
const TMaskImage * GetDisparityMaskInput() const
void SetInverseEpipolarLeftGrid(const TGridImage *lgrid)
void SetHorizontalDisparityMapInput(const TDisparityImage *hmap)
TDisparityImage * GetVerticalDisparityMapOutput()
DisparityTranslateFilter()
const TSensorImage * GetLeftSensorImageInput() const
void GenerateOutputInformation() override
DispMapType::PointType PointType
void SetDirectEpipolarRightGrid(const TGridImage *rgrid)
void SetDisparityMaskInput(const TMaskImage *mask)
void GenerateInputRequestedRegion() override
TDisparityImage * GetHorizontalDisparityMapOutput()
const TGridImage * GetDirectEpipolarRightGrid() const
DispMapType::IndexValueType IndexValueType
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
void OTBMetadata_EXPORT WriteNoDataFlags(const std::vector< bool > &flags, const std::vector< double > &values, ImageMetadata &imd)