18 #ifndef __otbStereoSensorModelToElevationMapFilter_txx
19 #define __otbStereoSensorModelToElevationMapFilter_txx
33 template <
class TInputImage,
class TOutputImage>
36 m_ElevationOffset(50),
41 m_LeftToRightTransform(),
42 m_RightToLeftTransform(),
43 m_OutputOriginInLeftImage(),
44 m_MeanBaselineRatio(0),
49 this->SetNumberOfOutputs(2);
52 this->SetNthOutput(0, OutputImageType::New());
53 this->SetNthOutput(1, OutputImageType::New());
56 m_LeftToRightTransform = RSTransformType::New();
57 m_RightToLeftTransform = RSTransformType::New();
60 template <
class TInputImage,
class TOutputImage>
66 if (this->GetNumberOfOutputs() < 1)
73 template <
class TInputImage,
class TOutputImage>
79 if (this->GetNumberOfOutputs() < 1)
86 template <
class TInputImage,
class TOutputImage>
92 if (this->GetNumberOfOutputs() < 2)
99 template <
class TInputImage,
class TOutputImage>
105 if (this->GetNumberOfOutputs() < 2)
112 template <
class TInputImage,
class TOutputImage>
120 if(m_LeftImage.IsNull() || m_RightImage.IsNull())
122 itkExceptionMacro(<<
"Either left image or right image pointer is null, can not perform stereo-rectification.");
126 m_LeftImage->UpdateOutputInformation();
127 m_RightImage->UpdateOutputInformation();
134 RSTransform2DType::Pointer leftToGroundTransform = RSTransform2DType::New();
135 leftToGroundTransform->SetInputKeywordList(m_LeftImage->GetImageKeywordlist());
137 leftToGroundTransform->InstanciateTransform();
144 m_LeftToRightTransform->SetInputKeywordList(m_LeftImage->GetImageKeywordlist());
145 m_LeftToRightTransform->SetOutputKeywordList(m_RightImage->GetImageKeywordlist());
146 m_LeftToRightTransform->InstanciateTransform();
148 m_RightToLeftTransform->SetInputKeywordList(m_RightImage->GetImageKeywordlist());
149 m_RightToLeftTransform->SetOutputKeywordList(m_LeftImage->GetImageKeywordlist());
150 m_RightToLeftTransform->InstanciateTransform();
158 outputSpacing.Fill(m_Scale * m_GridStep);
159 double mean_spacing=0.5*(vcl_abs(m_LeftImage->GetSpacing()[0])+vcl_abs(m_LeftImage->GetSpacing()[1]));
163 outputSpacing[0]*=mean_spacing;
164 outputSpacing[1]*=mean_spacing;
171 RSTransform2DType::InputPointType tmpPoint;
172 localElevation = demHandler->GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(m_LeftImage->GetOrigin()));
176 leftInputOrigin[0] = m_LeftImage->GetOrigin()[0];
177 leftInputOrigin[1] = m_LeftImage->GetOrigin()[1];
178 leftInputOrigin[2] = localElevation;
182 TDPointType rightEpiPoint, leftEpiLineStart, leftEpiLineEnd;
186 rightEpiPoint = m_LeftToRightTransform->TransformPoint(leftInputOrigin);
190 rightEpiPoint[2] = localElevation - m_ElevationOffset;
191 leftEpiLineStart = m_RightToLeftTransform->TransformPoint(rightEpiPoint);
195 rightEpiPoint[2] = localElevation + m_ElevationOffset;
196 leftEpiLineEnd = m_RightToLeftTransform->TransformPoint(rightEpiPoint);
201 if (leftEpiLineEnd[0] == leftEpiLineStart[0])
203 if (leftEpiLineEnd[1] > leftEpiLineStart[1])
214 double a = (leftEpiLineEnd[1] - leftEpiLineStart[1])
215 / (leftEpiLineEnd[0] - leftEpiLineStart[0]);
216 double b = leftEpiLineStart[1] - a * leftEpiLineStart[0];
217 if (leftEpiLineEnd[0] > leftEpiLineStart[0])
231 double ux = vcl_cos(alpha);
232 double uy = vcl_sin(alpha);
233 double vx = - vcl_sin(alpha);
234 double vy = vcl_cos(alpha);
241 double urx = ux * m_LeftImage->GetLargestPossibleRegion().GetSize()[0] * m_LeftImage->GetSpacing()[0];
242 double ury = vx * m_LeftImage->GetLargestPossibleRegion().GetSize()[0] * m_LeftImage->GetSpacing()[0];
243 double llx = uy * m_LeftImage->GetLargestPossibleRegion().GetSize()[1] * m_LeftImage->GetSpacing()[1];
244 double lly = vy * m_LeftImage->GetLargestPossibleRegion().GetSize()[1] * m_LeftImage->GetSpacing()[1];
245 double lrx = ux * m_LeftImage->GetLargestPossibleRegion().GetSize()[0] * m_LeftImage->GetSpacing()[0]
246 + uy * m_LeftImage->GetLargestPossibleRegion().GetSize()[1] * m_LeftImage->GetSpacing()[1];
247 double lry = vx * m_LeftImage->GetLargestPossibleRegion().GetSize()[0] * m_LeftImage->GetSpacing()[0]
248 + vy * m_LeftImage->GetLargestPossibleRegion().GetSize()[1] * m_LeftImage->GetSpacing()[1];
251 double minx = std::min(std::min(std::min(urx,llx),lrx),0.);
252 double miny = std::min(std::min(std::min(ury,lly),lry),0.);
253 double maxx = std::max(std::max(std::max(urx,llx),lrx),0.);
254 double maxy = std::max(std::max(std::max(ury,lly),lry),0.);
258 m_RectifiedImageSize[0] =
static_cast<unsigned int>((maxx-minx)/(mean_spacing*m_Scale));
259 m_RectifiedImageSize[1] =
static_cast<unsigned int>((maxy-miny)/(mean_spacing*m_Scale));
263 m_OutputOriginInLeftImage[0] = leftInputOrigin[0] + (ux * minx + vx * miny);
264 m_OutputOriginInLeftImage[1] = leftInputOrigin[1] + (uy * minx + vy * miny);
265 m_OutputOriginInLeftImage[2] = localElevation;
269 outputSize[0] = (m_RectifiedImageSize[0] / m_GridStep + 2 );
270 outputSize[1] = (m_RectifiedImageSize[1] / m_GridStep + 2);
274 outputLargestRegion.SetSize(outputSize);
277 leftDFPtr->SetLargestPossibleRegion(outputLargestRegion);
278 rightDFPtr->SetLargestPossibleRegion(outputLargestRegion);
280 leftDFPtr->SetSpacing(outputSpacing);
281 rightDFPtr->SetSpacing(outputSpacing);
283 leftDFPtr->SetNumberOfComponentsPerPixel(2);
284 rightDFPtr->SetNumberOfComponentsPerPixel(2);
287 template <
class TInputImage,
class TOutputImage>
293 Superclass::EnlargeOutputRequestedRegion(output);
300 leftDFPtr->SetRequestedRegionToLargestPossibleRegion();
301 rightDFPtr->SetRequestedRegionToLargestPossibleRegion();
304 template <
class TInputImage,
class TOutputImage>
310 this->AllocateOutputs();
317 RSTransform2DType::Pointer leftToGroundTransform = RSTransform2DType::New();
319 leftToGroundTransform->SetInputKeywordList(m_LeftImage->GetImageKeywordlist());
321 leftToGroundTransform->InstanciateTransform();
328 TDPointType currentPoint1, currentPoint2,nextLineStart1,nextLineStart2, startLine1, endLine1, startLine2, endLine2, epiPoint1, epiPoint2;
334 double mean_spacing=0.5*(vcl_abs(m_LeftImage->GetSpacing()[0])+vcl_abs(m_LeftImage->GetSpacing()[1]));
337 currentPoint1 = m_OutputOriginInLeftImage;
340 RSTransform2DType::InputPointType tmpPoint;
341 tmpPoint[0] = currentPoint1[0];
342 tmpPoint[1] = currentPoint1[1];
343 localElevation = demHandler->GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(tmpPoint));
345 currentPoint1[2] = localElevation;
346 currentPoint2 = m_LeftToRightTransform->TransformPoint(currentPoint1);
347 currentPoint2[2] = currentPoint1[2];
350 nextLineStart1 = currentPoint1;
351 nextLineStart2 = currentPoint2;
356 IteratorType it1(leftDFPtr,leftDFPtr->GetLargestPossibleRegion());
357 IteratorType it2(rightDFPtr,rightDFPtr->GetLargestPossibleRegion());
363 m_MeanBaselineRatio = 0;
370 while(!it1.IsAtEnd() && !it2.IsAtEnd())
374 if(it1.GetIndex()[0] == 0 || it2.GetIndex()[0] == 0)
377 currentPoint1 = nextLineStart1;
378 currentPoint2 = nextLineStart2;
382 typename OutputImageType::PixelType dFValue1 = it1.Get();
383 typename OutputImageType::PixelType dFValue2 = it2.Get();
386 PointType currentDFPoint1, currentDFPoint2;
387 leftDFPtr->TransformIndexToPhysicalPoint(it1.GetIndex(), currentDFPoint1);
388 rightDFPtr->TransformIndexToPhysicalPoint(it2.GetIndex(), currentDFPoint2);
391 dFValue1[0] = currentPoint1[0] - currentDFPoint1[0];
392 dFValue1[1] = currentPoint1[1] - currentDFPoint1[1];
393 dFValue2[0] = currentPoint2[0] - currentDFPoint2[0];
394 dFValue2[1] = currentPoint2[1] - currentDFPoint2[1];
408 epiPoint2 = m_LeftToRightTransform->TransformPoint(currentPoint1);
412 epiPoint2[2] = localElevation - m_ElevationOffset;
413 startLine1 = m_RightToLeftTransform->TransformPoint(epiPoint2);
417 epiPoint2[2] = localElevation + m_ElevationOffset;
418 endLine1 = m_RightToLeftTransform->TransformPoint(epiPoint2);
421 double localBaselineRatio = vcl_sqrt((endLine1[0] - startLine1[0])
422 * (endLine1[0] - startLine1[0])
423 + (endLine1[1] - startLine1[1])
424 * (endLine1[1] - startLine1[1]))
425 / (2 * m_ElevationOffset);
427 m_MeanBaselineRatio+=localBaselineRatio;
432 if (endLine1[0] == startLine1[0])
434 if (endLine1[1] > startLine1[1])
445 a1 = (endLine1[1] - startLine1[1]) / (endLine1[0] - startLine1[0]);
446 if (endLine1[0] > startLine1[0])
448 alpha1 = vcl_atan(a1);
457 currentPoint2[2] = localElevation;
458 epiPoint1 = m_RightToLeftTransform->TransformPoint(currentPoint2);
460 epiPoint1[2] = localElevation - m_ElevationOffset;
461 startLine2 = m_LeftToRightTransform->TransformPoint(epiPoint1);
463 epiPoint1[2] = localElevation + m_ElevationOffset;
464 endLine2 = m_LeftToRightTransform->TransformPoint(epiPoint1);
472 double deltax1 = m_Scale * m_GridStep * mean_spacing * vcl_cos(alpha1);
473 double deltay1 = m_Scale * m_GridStep * mean_spacing * vcl_sin(alpha1);
476 currentPoint1[0]+=deltax1;
477 currentPoint1[1]+=deltay1;
480 RSTransform2DType::InputPointType tmpPoint;
481 tmpPoint[0] = currentPoint1[0];
482 tmpPoint[1] = currentPoint1[1];
483 localElevation = demHandler->GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(tmpPoint));
485 currentPoint1[2] = localElevation;
488 currentPoint2 = m_LeftToRightTransform->TransformPoint(currentPoint1);
493 if(it1.GetIndex()[0] == 0 || it2.GetIndex()[0] == 0)
497 double nextdeltax1 = -m_Scale * mean_spacing * m_GridStep * vcl_sin(alpha1);
498 double nextdeltay1 = m_Scale * mean_spacing * m_GridStep * vcl_cos(alpha1);
501 nextLineStart1[0] = currentPoint1[0] - deltax1 + nextdeltax1;
502 nextLineStart1[1] = currentPoint1[1] - deltay1 + nextdeltay1;
503 nextLineStart1[2] = localElevation;
506 RSTransform2DType::InputPointType tmpPoint;
507 tmpPoint[0] = nextLineStart1[0];
508 tmpPoint[1] = nextLineStart1[1];
509 nextLineStart1[2] = demHandler->GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(tmpPoint));
515 nextLineStart2 = m_LeftToRightTransform->TransformPoint(nextLineStart1);
523 progress.CompletedPixel();
527 m_MeanBaselineRatio /= leftDFPtr->GetBufferedRegion().GetNumberOfPixels();
530 template <
class TInputImage,
class TOutputImage>
536 Superclass::PrintSelf(os,indent);