18 #ifndef __otbStereoSensorModelToElevationMapFilter_txx
19 #define __otbStereoSensorModelToElevationMapFilter_txx
32 template <
class TInputImage,
class TOutputHeight>
37 this->SetNumberOfInputs(2);
38 this->SetNumberOfOutputs(2);
39 this->SetNthOutput(1, OutputImageType::New());
48 m_LowerElevation = -20;
49 m_HigherElevation = 20;
51 m_CorrelationThreshold = 0.7;
52 m_VarianceThreshold = 4;
53 m_SubtractInitialElevation =
false;
59 template <
class TInputImage,
class TOutputHeight>
64 template <
class TInputImage,
class TOutputHeight>
69 this->SetNthInput(0, const_cast<TInputImage *>( image ));
72 template <
class TInputImage,
class TOutputHeight>
77 this->SetNthInput(1, const_cast<TInputImage *>( image ));
80 template <
class TInputImage,
class TOutputHeight>
85 if(this->GetNumberOfInputs() < 1)
92 template <
class TInputImage,
class TOutputHeight>
97 if(this->GetNumberOfInputs()<2)
104 template <
class TInputImage,
class TOutputHeight>
109 if(this->GetNumberOfOutputs()<2)
116 template <
class TInputImage,
class TOutputHeight>
121 Superclass::GenerateInputRequestedRegion();
128 if ( !masterPtr || !slavePtr || !outputPtr )
135 typename InputImageType::RegionType masterRequestedRegion, slaveRequestedRegion;
136 masterRequestedRegion = outputPtr->GetRequestedRegion();
139 masterRequestedRegion.PadByRadius( m_Radius );
142 typename InputImageType::IndexType mul, mur, mll, mlr;
143 mul = masterRequestedRegion.GetIndex();
144 mur = masterRequestedRegion.GetIndex();
145 mur[0] += masterRequestedRegion.GetSize()[0]-1;
146 mll = masterRequestedRegion.GetIndex();
147 mll[1] += masterRequestedRegion.GetSize()[1]-1;
148 mlr = masterRequestedRegion.GetIndex();
149 mlr[0] += masterRequestedRegion.GetSize()[0]-1;
150 mlr[1] += masterRequestedRegion.GetSize()[1]-1;
153 typename InputImageType::PointType mpul, mpur, mpll, mplr;
154 masterPtr->TransformIndexToPhysicalPoint(mul, mpul);
155 masterPtr->TransformIndexToPhysicalPoint(mur, mpur);
156 masterPtr->TransformIndexToPhysicalPoint(mll, mpll);
157 masterPtr->TransformIndexToPhysicalPoint(mlr, mplr);
161 transform->SetInputKeywordList(masterPtr->GetImageKeywordlist());
162 transform->SetOutputKeywordList(slavePtr->GetImageKeywordlist());
164 transform->InstanciateTransform();
170 typename InputImageType::PointType sMinPul, sMinPur, sMinPll, sMinPlr, sMaxPul, sMaxPur, sMaxPll, sMaxPlr;
173 params[0] = m_LowerElevation;
174 transform->SetParameters(params);
176 sMinPul = transform->TransformPoint(mpul);
177 sMinPur = transform->TransformPoint(mpur);
178 sMinPll = transform->TransformPoint(mpll);
179 sMinPlr = transform->TransformPoint(mplr);
182 params[0] = m_HigherElevation;
183 transform->SetParameters(params);
185 sMaxPul = transform->TransformPoint(mpul);
186 sMaxPur = transform->TransformPoint(mpur);
187 sMaxPll = transform->TransformPoint(mpll);
188 sMaxPlr = transform->TransformPoint(mplr);
191 typename InputImageType::IndexType sMinul, sMinur, sMinll, sMinlr, sMaxul, sMaxur, sMaxll, sMaxlr;
193 slavePtr->TransformPhysicalPointToIndex(sMinPul, sMinul);
194 slavePtr->TransformPhysicalPointToIndex(sMaxPul, sMaxul);
195 slavePtr->TransformPhysicalPointToIndex(sMinPur, sMinur);
196 slavePtr->TransformPhysicalPointToIndex(sMaxPur, sMaxur);
197 slavePtr->TransformPhysicalPointToIndex(sMinPll, sMinll);
198 slavePtr->TransformPhysicalPointToIndex(sMaxPll, sMaxll);
199 slavePtr->TransformPhysicalPointToIndex(sMinPlr, sMinlr);
200 slavePtr->TransformPhysicalPointToIndex(sMaxPlr, sMaxlr);
203 typename InputImageType::IndexType sul, slr;
205 sul[0] = std::min(std::min(std::min(sMinul[0], sMaxul[0]), std::min(sMinur[0], sMaxur[0])),
206 std::min(std::min(sMinll[0], sMaxll[0]), std::min(sMinlr[0], sMaxlr[0])));
207 sul[1] = std::min(std::min(std::min(sMinul[1], sMaxul[1]), std::min(sMinur[1], sMaxur[1])),
208 std::min(std::min(sMinll[1], sMaxll[1]), std::min(sMinlr[1], sMaxlr[1])));
209 slr[0] = std::max(std::max(std::max(sMinul[0], sMaxul[0]), std::max(sMinur[0], sMaxur[0])),
210 std::max(std::max(sMinll[0], sMaxll[0]), std::max(sMinlr[0], sMaxlr[0])));
211 slr[1] = std::max(std::max(std::max(sMinul[1], sMaxul[1]), std::max(sMinur[1], sMaxur[1])),
212 std::max(std::max(sMinll[1], sMaxll[1]), std::max(sMinlr[1], sMaxlr[1])));
215 slaveRequestedRegion.SetIndex(sul);
216 typename InputImageType::SizeType ssize;
217 ssize[0] = slr[0] - sul[0]+1;
218 ssize[1] = slr[1] - sul[1]+1;
219 slaveRequestedRegion.SetSize(ssize);
222 if ( masterRequestedRegion.Crop(masterPtr->GetLargestPossibleRegion()))
224 masterPtr->SetRequestedRegion( masterRequestedRegion );
231 masterPtr->SetRequestedRegion( masterRequestedRegion );
235 std::ostringstream msg;
236 msg << this->GetNameOfClass()
237 <<
"::GenerateInputRequestedRegion()";
239 e.
SetDescription(
"Requested region is (at least partially) outside the largest possible region of image 1.");
245 if ( slaveRequestedRegion.Crop(slavePtr->GetLargestPossibleRegion()))
247 slavePtr->SetRequestedRegion( slaveRequestedRegion );
254 typename InputImageType::SizeType slaveSize;
256 slaveRequestedRegion.SetSize(slaveSize);
257 typename InputImageType::IndexType slaveIndex;
259 slaveRequestedRegion.SetIndex(slaveIndex);
262 slavePtr->SetRequestedRegion(slaveRequestedRegion);
267 template <
class TInputImage,
class TOutputHeight>
273 m_Interpolator->SetInputImage(this->GetSlaveInput());
274 this->GetCorrelationOutput()->FillBuffer(0.);
284 rsTransform->SetInputKeywordList(outputPtr->GetImageKeywordlist());
285 rsTransform->InstanciateTransform();
290 for(outputIt.GoToBegin(); !outputIt.IsAtEnd(); ++outputIt)
294 outputPtr->TransformIndexToPhysicalPoint(outputIt.GetIndex(), outputPoint);
297 geoPoint = rsTransform->TransformPoint(outputPoint);
303 template <
class TInputImage,
class TOutputHeight>
316 transform->SetInputKeywordList(masterPtr->GetImageKeywordlist());
317 transform->SetOutputKeywordList(slavePtr->GetImageKeywordlist());
379 transform->InstanciateTransform();
388 std::vector<double> master;
389 master.reserve(inputIt.Size());
390 master = std::vector<double>(inputIt.Size(), 0);
393 std::vector<double> slave;
394 slave.reserve(inputIt.Size());
395 slave = std::vector<double>(inputIt.Size(), 0);
399 while(!outputIt.
IsAtEnd() && !inputIt.IsAtEnd())
402 typename InputImageType::PointType inPoint, outPoint, currentPoint, optimalPoint;
404 typename InputImageType::IndexType index;
407 double initHeight = outputIt.
Get();
408 double optimalHeight = initHeight;
409 double optimalCorrelation = 0;
412 if(initHeight != -32768)
415 double masterSum = 0;
416 double masterVariance = 0;
419 for(
unsigned int i = 0; i < inputIt.Size(); ++i)
422 double value = inputIt.GetPixel(i);
430 masterSum /= inputIt.Size();
433 for(
unsigned int i = 0; i < inputIt.Size(); ++i)
435 masterVariance += (master[i] - masterSum) * (master[i] - masterSum);
437 masterVariance /= (inputIt.Size()-1);
440 if(masterVariance > m_VarianceThreshold)
443 for(
double height = initHeight + m_LowerElevation;
444 height < initHeight + m_HigherElevation;
445 height += m_ElevationStep)
449 for(
unsigned int i = 0; i < inputIt.Size(); ++i)
452 index = inputIt.GetIndex(i);
455 masterPtr->TransformIndexToPhysicalPoint(index, inPoint);
456 in3DPoint[0] = inPoint[0];
457 in3DPoint[1] = inPoint[1];
458 in3DPoint[2] = height;
461 out3DPoint = transform->TransformPoint(in3DPoint);
462 outPoint[0] = out3DPoint[0];
463 outPoint[1] = out3DPoint[1];
466 if(m_Interpolator->IsInsideBuffer(outPoint))
469 slave[i] = m_Interpolator->Evaluate(outPoint);
480 double correlationValue = this->
Correlation(master, slave);
483 if(correlationValue > optimalCorrelation)
486 optimalCorrelation = correlationValue;
487 optimalHeight = height;
495 double finalOffset = 0.;
498 if(m_SubtractInitialElevation)
500 finalOffset = initHeight;
503 if(optimalCorrelation > m_CorrelationThreshold)
505 outputIt.
Set(optimalHeight-finalOffset);
506 correlIt.
Set(optimalCorrelation);
510 outputIt.
Set(initHeight - finalOffset);
515 progress.CompletedPixel();
524 template <
class TInputImage,
class TOutputHeight>
527 ::Correlation(
const std::vector<double>& master,
const std::vector<double>& slave)
const
529 double meanSlave = 0;
530 double meanMaster = 0;
531 double correlationValue = 0;
534 for(
unsigned int i = 0; i < master.size(); ++i)
536 meanSlave += slave[i];
537 meanMaster += master[i];
539 meanSlave /= slave.size();
540 meanMaster /= master.size();
542 double crossProd = 0.;
543 double squareSumMaster = 0.;
544 double squareSumSlave = 0.;
548 for(
unsigned int i = 0; i < master.size(); ++i)
550 crossProd += (slave[i]-meanSlave) * (master[i]-meanMaster);
551 squareSumSlave += (slave[i]-meanSlave) * (slave[i]-meanSlave);
552 squareSumMaster += (master[i]-meanMaster) * (master[i]-meanMaster);
555 correlationValue = vcl_abs(crossProd/(vcl_sqrt(squareSumSlave)*vcl_sqrt(squareSumMaster)));
557 return correlationValue;