OTB  9.0.0
Orfeo Toolbox
otbKeyPointSetsMatchingFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbKeyPointSetsMatchingFilter_hxx
22 #define otbKeyPointSetsMatchingFilter_hxx
23 
25 
26 namespace otb
27 {
28 
29 template <class TPointSet, class TDistance>
31 {
32  this->SetNumberOfRequiredInputs(2);
33  m_UseBackMatching = false;
34  m_DistanceThreshold = 0.6;
35  // Object used to measure distance
36  m_DistanceCalculator = DistanceType::New();
37 }
38 
39 template <class TPointSet, class TDistance>
41 {
42  return static_cast<const PointSetType*>(this->itk::ProcessObject::GetInput(0));
43 }
44 
45 template <class TPointSet, class TDistance>
47 {
48  this->itk::ProcessObject::SetNthInput(0, const_cast<PointSetType*>(pointset));
49 }
50 
51 template <class TPointSet, class TDistance>
53 {
54  return static_cast<const PointSetType*>(this->itk::ProcessObject::GetInput(1));
55 }
56 
57 template <class TPointSet, class TDistance>
59 {
60  this->itk::ProcessObject::SetNthInput(1, const_cast<PointSetType*>(pointset));
61 }
62 
63 template <class TPointSet, class TDistance>
65 {
66  // std::cout<<"GenerateData()"<<std::endl;
67 
68  // Get the input pointers
69  const PointSetType* ps1 = this->GetInput1();
70  const PointSetType* ps2 = this->GetInput2();
71 
72  // Check if one of the pointsets is empty
73  if (ps1->GetNumberOfPoints() == 0 || ps2->GetNumberOfPoints() == 0)
74  {
75  itkExceptionMacro(<< "Empty input pointset !");
76  }
77 
78  // Get the output pointer
79  LandmarkListPointerType landmarks = this->GetOutput();
80 
81  // Define iterators on points and point data.
82  PointsIteratorType pIt = ps1->GetPoints()->Begin();
83  PointDataIteratorType pdIt = ps1->GetPointData()->Begin();
84 
85  // iterate on pointset 1
86  while (pdIt != ps1->GetPointData()->End() && pIt != ps1->GetPoints()->End())
87  {
88  // Get point and point data at current location
89  bool matchFound = false;
90  unsigned int currentIndex = pIt.Index();
91  PointDataType data = pdIt.Value();
92  PointType point = pIt.Value();
93 
94  // These variables will hold the matched point and point data
95  PointDataType dataMatch;
96  PointType pointMatch;
97 
98  // call to the matching routine
99  NeighborSearchResultType searchResult1 = NearestNeighbor(data, ps2);
100 
101  // Check if the neighbor distance is lower than the threshold
102  if (searchResult1.second < m_DistanceThreshold)
103  {
104  // Get the matched point and point data
105  dataMatch = ps2->GetPointData()->GetElement(searchResult1.first);
106  pointMatch = ps2->GetPoints()->GetElement(searchResult1.first);
107 
108  // If the back matching option is on
109  if (m_UseBackMatching)
110  {
111  // Perform the back search
112  NeighborSearchResultType searchResult2 = NearestNeighbor(dataMatch, ps1);
113 
114  // Test if back search finds the same match
115  if (currentIndex == searchResult2.first)
116  {
117  matchFound = true;
118  }
119  }
120  else // else back matching
121  {
122  matchFound = true;
123  }
124  }
125 
126  // If we found a match, add the proper landmark
127  if (matchFound)
128  {
129  LandmarkPointerType landmark = LandmarkType::New();
130  landmark->SetPoint1(point);
131  landmark->SetPointData1(data);
132  landmark->SetPoint2(pointMatch);
133  landmark->SetPointData2(dataMatch);
134  landmark->SetLandmarkData(searchResult1.second);
135 
136  // Add the new landmark to the landmark list
137  landmarks->PushBack(landmark);
138  }
139  ++pdIt;
140  ++pIt;
141  }
142 }
143 
144 template <class TPointSet, class TDistance>
147 {
148  // std::cout<<"Call to NearestNeighbor()"<<std::endl;
149  // Declare the result
151 
152  // Define iterators on points and point data.
153  PointDataIteratorType pdIt = pointset->GetPointData()->Begin();
154 
155  // local variables
156  unsigned int nearestIndex = 0;
157  double d1 = m_DistanceCalculator->Evaluate(data1, pdIt.Value());
158  ++pdIt;
159  double d2 = m_DistanceCalculator->Evaluate(data1, pdIt.Value());
160  ++pdIt;
161 
162  if (d1 > d2)
163  {
164  nearestIndex = 1;
165  }
166  // Initialize distances
167  double nearestDistance = std::min(d1, d2);
168  double secondNearestDistance = std::max(d1, d2);
169  double distanceValue;
170 
171  // iterate on the pointset
172  while (pdIt != pointset->GetPointData()->End())
173  {
174  // Evaluate the distance
175  distanceValue = m_DistanceCalculator->Evaluate(data1, pdIt.Value());
176 
177  // std::cout<<nearestIndex<<" "<<nearestDistance<<" "<<secondNearestDistance<<std::endl;
178 
179  // Check if this point is the nearest neighbor
180  if (distanceValue < nearestDistance)
181  {
182  secondNearestDistance = nearestDistance;
183  nearestDistance = distanceValue;
184  nearestIndex = pdIt.Index();
185  }
186  // Else check if it is the second nearest neighbor
187  else if (distanceValue < secondNearestDistance)
188  {
189  secondNearestDistance = distanceValue;
190  }
191  ++pdIt;
192  }
193 
194  // Fill results
195  result.first = nearestIndex;
196  if (secondNearestDistance == 0)
197  {
198  result.second = 1;
199  }
200  else
201  {
202  result.second = nearestDistance / secondNearestDistance;
203  }
204 
205  // return the result
206  return result;
207 }
208 
209 template <class TPointSet, class TDistance>
210 void KeyPointSetsMatchingFilter<TPointSet, TDistance>::PrintSelf(std::ostream& os, itk::Indent indent) const
211 {
212  Superclass::PrintSelf(os, indent);
213 }
214 
215 } // end namespace otb
216 
217 #endif
otb::KeyPointSetsMatchingFilter::GetInput2
const PointSetType * GetInput2()
Get the second pointset.
Definition: otbKeyPointSetsMatchingFilter.hxx:52
otb::KeyPointSetsMatchingFilter::NeighborSearchResultType
std::pair< unsigned int, double > NeighborSearchResultType
Definition: otbKeyPointSetsMatchingFilter.h:76
otb::KeyPointSetsMatchingFilter::PointType
PointSetType::PointType PointType
Definition: otbKeyPointSetsMatchingFilter.h:64
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::KeyPointSetsMatchingFilter::PointsIteratorType
PointsContainerType::ConstIterator PointsIteratorType
Definition: otbKeyPointSetsMatchingFilter.h:67
otb::KeyPointSetsMatchingFilter::GetInput1
const PointSetType * GetInput1()
Get the first pointset.
Definition: otbKeyPointSetsMatchingFilter.hxx:40
otb::KeyPointSetsMatchingFilter::GenerateData
void GenerateData() override
Generate Data.
Definition: otbKeyPointSetsMatchingFilter.hxx:64
otb::KeyPointSetsMatchingFilter::PointSetType
TPointSet PointSetType
template typedefs
Definition: otbKeyPointSetsMatchingFilter.h:62
otb::KeyPointSetsMatchingFilter::PointDataIteratorType
PointDataContainerType::ConstIterator PointDataIteratorType
Definition: otbKeyPointSetsMatchingFilter.h:69
otb::KeyPointSetsMatchingFilter::KeyPointSetsMatchingFilter
KeyPointSetsMatchingFilter()
Constructor.
Definition: otbKeyPointSetsMatchingFilter.hxx:30
otb::KeyPointSetsMatchingFilter::PointDataType
PointSetType::PixelType PointDataType
Definition: otbKeyPointSetsMatchingFilter.h:65
otb::KeyPointSetsMatchingFilter::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
PrintSelf method.
Definition: otbKeyPointSetsMatchingFilter.hxx:210
otb::KeyPointSetsMatchingFilter::SetInput2
void SetInput2(const PointSetType *pointset)
Set the second pointset.
Definition: otbKeyPointSetsMatchingFilter.hxx:58
otbKeyPointSetsMatchingFilter.h
otb::KeyPointSetsMatchingFilter::LandmarkListPointerType
LandmarkListType::Pointer LandmarkListPointerType
Definition: otbKeyPointSetsMatchingFilter.h:75
otb::KeyPointSetsMatchingFilter::SetInput1
void SetInput1(const PointSetType *pointset)
Set the first pointset.
Definition: otbKeyPointSetsMatchingFilter.hxx:46
otb::KeyPointSetsMatchingFilter::NearestNeighbor
NeighborSearchResultType NearestNeighbor(const PointDataType &data1, const PointSetType *pointset)
Definition: otbKeyPointSetsMatchingFilter.hxx:146
otb::KeyPointSetsMatchingFilter::LandmarkPointerType
LandmarkType::Pointer LandmarkPointerType
Definition: otbKeyPointSetsMatchingFilter.h:73