OTB  9.0.0
Orfeo Toolbox
otbBijectionCoherencyFilter.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 otbBijectionCoherencyFilter_hxx
22 #define otbBijectionCoherencyFilter_hxx
23 
25 
26 #include "itkImageRegionConstIteratorWithIndex.h"
27 #include "itkImageRegionIterator.h"
28 
29 namespace otb
30 {
31 
32 template <class TDisparityImage, class TOutputImage>
34 {
35  // Set the number of inputs (1 moving image by default -> 3 inputs)
36  this->SetNumberOfRequiredInputs(4);
37  this->SetNumberOfRequiredInputs(1);
38  this->m_Tolerance = 1.;
39  this->m_MinHDisp = -5;
40  this->m_MaxHDisp = 5;
41  this->m_MinVDisp = -5;
42  this->m_MaxVDisp = 5;
43 
44  // Set the outputs
45  this->SetNumberOfRequiredOutputs(1);
46  this->SetNthOutput(0, TOutputImage::New());
47 }
48 
49 template <class TDisparityImage, class TOutputImage>
51 {
52  // Process object is not const-correct so the const casting is required.
53  this->SetNthInput(0, const_cast<TDisparityImage*>(hmap));
54 }
55 
56 template <class TDisparityImage, class TOutputImage>
58 {
59  // Process object is not const-correct so the const casting is required.
60  this->SetNthInput(1, const_cast<TDisparityImage*>(vmap));
61 }
62 
63 template <class TDisparityImage, class TOutputImage>
65 {
66  // Process object is not const-correct so the const casting is required.
67  this->SetNthInput(2, const_cast<TDisparityImage*>(hmap));
68 }
69 
70 template <class TDisparityImage, class TOutputImage>
72 {
73  // Process object is not const-correct so the const casting is required.
74  this->SetNthInput(3, const_cast<TDisparityImage*>(vmap));
75 }
76 
77 template <class TDisparityImage, class TOutputImage>
79 {
80  if (this->GetNumberOfInputs() < 1)
81  {
82  return nullptr;
83  }
84  return static_cast<const TDisparityImage*>(this->itk::ProcessObject::GetInput(0));
85 }
86 
87 template <class TDisparityImage, class TOutputImage>
89 {
90  if (this->GetNumberOfInputs() < 2)
91  {
92  return nullptr;
93  }
94  return static_cast<const TDisparityImage*>(this->itk::ProcessObject::GetInput(1));
95 }
96 
97 template <class TDisparityImage, class TOutputImage>
99 {
100  if (this->GetNumberOfInputs() < 3)
101  {
102  return nullptr;
103  }
104  return static_cast<const TDisparityImage*>(this->itk::ProcessObject::GetInput(2));
105 }
106 
107 template <class TDisparityImage, class TOutputImage>
109 {
110  if (this->GetNumberOfInputs() < 4)
111  {
112  return nullptr;
113  }
114  return static_cast<const TDisparityImage*>(this->itk::ProcessObject::GetInput(3));
115 }
116 
117 template <class TDisparityImage, class TOutputImage>
119 {
120  this->Superclass::GenerateOutputInformation();
121 
122  // check that both direct and reverse disparity maps are present
123  const TDisparityImage* directHmap = this->GetDirectHorizontalDisparityMapInput();
124  const TDisparityImage* reverseHmap = this->GetReverseHorizontalDisparityMapInput();
125 
126  const TDisparityImage* directVmap = this->GetDirectVerticalDisparityMapInput();
127  const TDisparityImage* reverseVmap = this->GetReverseVerticalDisparityMapInput();
128 
129  if (!directHmap)
130  {
131  itkExceptionMacro(<< "Direct horizontal disparity map is missing");
132  }
133 
134  if (!reverseHmap)
135  {
136  itkExceptionMacro(<< "Reverse horizontal disparity map is missing");
137  }
138 
139  if (directVmap && directVmap->GetLargestPossibleRegion() != directHmap->GetLargestPossibleRegion())
140  {
141  itkExceptionMacro(<< "Horizontal and vertical direct disparity maps have different sizes.");
142  }
143 
144  if (reverseVmap && reverseVmap->GetLargestPossibleRegion() != reverseHmap->GetLargestPossibleRegion())
145  {
146  itkExceptionMacro(<< "Horizontal and vertical reverse disparity maps have different sizes.");
147  }
148 
149  if (this->m_MinHDisp > this->m_MaxHDisp)
150  {
151  itkExceptionMacro(<< "Wrong horizontal exploration values");
152  }
153  if (this->m_MinVDisp > this->m_MaxVDisp)
154  {
155  itkExceptionMacro(<< "Wrong horizontal exploration values");
156  }
157 }
158 
159 template <class TDisparityImage, class TOutputImage>
161 {
162  this->Superclass::GenerateInputRequestedRegion();
163 
164  OutputRegionType requested = this->GetOutput()->GetRequestedRegion();
165  InputRegionType directLargest = this->GetDirectHorizontalDisparityMapInput()->GetLargestPossibleRegion();
166  InputRegionType directRequested;
167  InputRegionType reverseLargest = this->GetReverseHorizontalDisparityMapInput()->GetLargestPossibleRegion();
168  InputRegionType reverseRequested;
169 
170  this->CallCopyOutputRegionToInputRegion(directRequested, requested);
171 
172  reverseRequested.SetIndex(0, requested.GetIndex(0) + this->m_MinHDisp);
173  reverseRequested.SetIndex(1, requested.GetIndex(1) + this->m_MinVDisp);
174  reverseRequested.SetSize(0, requested.GetSize(0) + this->m_MaxHDisp - this->m_MinHDisp);
175  reverseRequested.SetSize(1, requested.GetSize(1) + this->m_MaxVDisp - this->m_MinVDisp);
176 
177  if (!reverseRequested.Crop(reverseLargest))
178  {
179  reverseRequested.SetIndex(0, reverseLargest.GetIndex(0));
180  reverseRequested.SetIndex(1, reverseLargest.GetIndex(1));
181  reverseRequested.SetSize(0, 0);
182  reverseRequested.SetSize(1, 0);
183  }
184 
185  TDisparityImage* directHmap = const_cast<TDisparityImage*>(this->GetDirectHorizontalDisparityMapInput());
186  TDisparityImage* directVmap = const_cast<TDisparityImage*>(this->GetDirectVerticalDisparityMapInput());
187  TDisparityImage* reverseHmap = const_cast<TDisparityImage*>(this->GetReverseHorizontalDisparityMapInput());
188  TDisparityImage* reverseVmap = const_cast<TDisparityImage*>(this->GetReverseVerticalDisparityMapInput());
189 
190  directHmap->SetRequestedRegion(directRequested);
191  if (directVmap)
192  directVmap->SetRequestedRegion(directRequested);
193 
194  reverseHmap->SetRequestedRegion(reverseRequested);
195  if (reverseVmap)
196  reverseVmap->SetRequestedRegion(reverseRequested);
197 }
198 
199 template <class TDisparityImage, class TOutputImage>
201  itk::ThreadIdType itkNotUsed(threadId))
202 {
203  const TDisparityImage* directHmap = this->GetDirectHorizontalDisparityMapInput();
204  const TDisparityImage* directVmap = this->GetDirectVerticalDisparityMapInput();
205  const TDisparityImage* reverseHmap = this->GetReverseHorizontalDisparityMapInput();
206  const TDisparityImage* reverseVmap = this->GetReverseVerticalDisparityMapInput();
207 
208  TOutputImage* output = this->GetOutput();
209 
210  InputRegionType buffered = reverseHmap->GetBufferedRegion();
211 
212  typedef itk::ImageRegionIterator<TOutputImage> MaskIteratorType;
213  MaskIteratorType outIter = MaskIteratorType(output, outputRegionForThread);
214 
215  typedef itk::ImageRegionConstIteratorWithIndex<TDisparityImage> DispIteratorType;
216  DispIteratorType directHorizIter = DispIteratorType(directHmap, outputRegionForThread);
217 
218  DispIteratorType directVertiIter;
219  if (directVmap)
220  {
221  directVertiIter = DispIteratorType(directVmap, outputRegionForThread);
222  directVertiIter.GoToBegin();
223  }
224 
225  outIter.GoToBegin();
226  directHorizIter.GoToBegin();
227 
228  while (!outIter.IsAtEnd())
229  {
230  IndexType startIndex = directHorizIter.GetIndex();
231  itk::ContinuousIndex<double, 2> tmpIndex(startIndex);
232 
233  tmpIndex[0] += directHorizIter.Get();
234  if (directVmap)
235  tmpIndex[1] += directVertiIter.Get();
236 
237  // Interpolate in reverse disparity map
238  typedef typename IndexType::IndexValueType IndexValueType;
239  IndexType ul, ur, ll, lr;
240  ul[0] = static_cast<long>(std::floor(tmpIndex[0]));
241  ul[1] = static_cast<long>(std::floor(tmpIndex[1]));
242  if (ul[0] < buffered.GetIndex()[0])
243  ul[0] = buffered.GetIndex()[0];
244  if (ul[1] < buffered.GetIndex()[1])
245  ul[1] = buffered.GetIndex()[1];
246  if (ul[0] > static_cast<IndexValueType>(buffered.GetIndex()[0] + buffered.GetSize()[0] - 1))
247  ul[0] = (buffered.GetIndex()[0] + buffered.GetSize()[0] - 1);
248  if (ul[1] > static_cast<IndexValueType>(buffered.GetIndex()[1] + buffered.GetSize()[1] - 1))
249  ul[1] = (buffered.GetIndex()[1] + buffered.GetSize()[1] - 1);
250 
251  ur = ul;
252  ll = ul;
253  lr = ul;
254  if (ul[0] < static_cast<IndexValueType>(buffered.GetIndex()[0] + buffered.GetSize()[0] - 1))
255  {
256  ur[0] += 1;
257  lr[0] += 1;
258  }
259  if (ul[1] < static_cast<IndexValueType>(buffered.GetIndex()[1] + buffered.GetSize()[1] - 1))
260  {
261  ll[1] += 1;
262  lr[1] += 1;
263  }
264 
265  double rx = tmpIndex[0] - static_cast<double>(ul[0]);
266  double ry = tmpIndex[1] - static_cast<double>(ul[1]);
267 
268  itk::ContinuousIndex<double, 2> backIndex(tmpIndex);
269  backIndex[0] += (1. - ry) * ((1. - rx) * reverseHmap->GetPixel(ul) + rx * reverseHmap->GetPixel(ur)) +
270  ry * ((1. - rx) * reverseHmap->GetPixel(ll) + rx * reverseHmap->GetPixel(lr));
271  if (reverseVmap)
272  {
273  backIndex[1] += (1. - ry) * ((1. - rx) * reverseVmap->GetPixel(ul) + rx * reverseVmap->GetPixel(ur)) +
274  ry * ((1. - rx) * reverseVmap->GetPixel(ll) + rx * reverseVmap->GetPixel(lr));
275  }
276 
277  if (std::abs(backIndex[0] - static_cast<double>(startIndex[0])) < this->m_Tolerance &&
278  std::abs(backIndex[1] - static_cast<double>(startIndex[1])) < this->m_Tolerance)
279  {
280  outIter.Set(255);
281  }
282  else
283  {
284  outIter.Set(0);
285  }
286 
287  ++outIter;
288  ++directHorizIter;
289  if (directVmap)
290  ++directVertiIter;
291  }
292 }
293 }
294 
295 #endif
otb::BijectionCoherencyFilter::GetDirectHorizontalDisparityMapInput
const TDisparityImage * GetDirectHorizontalDisparityMapInput() const
Definition: otbBijectionCoherencyFilter.hxx:78
otb::BijectionCoherencyFilter::GenerateOutputInformation
void GenerateOutputInformation() override
Definition: otbBijectionCoherencyFilter.hxx:118
otbBijectionCoherencyFilter.h
otb::BijectionCoherencyFilter::GetDirectVerticalDisparityMapInput
const TDisparityImage * GetDirectVerticalDisparityMapInput() const
Definition: otbBijectionCoherencyFilter.hxx:88
otb::BijectionCoherencyFilter::SetDirectHorizontalDisparityMapInput
void SetDirectHorizontalDisparityMapInput(const TDisparityImage *hmap)
Definition: otbBijectionCoherencyFilter.hxx:50
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::BijectionCoherencyFilter::OutputRegionType
MaskType::RegionType OutputRegionType
Definition: otbBijectionCoherencyFilter.h:68
otb::BijectionCoherencyFilter::SetReverseVerticalDisparityMapInput
void SetReverseVerticalDisparityMapInput(const TDisparityImage *vmap)
Definition: otbBijectionCoherencyFilter.hxx:71
otb::BijectionCoherencyFilter::ThreadedGenerateData
void ThreadedGenerateData(const OutputRegionType &outputRegionForThread, itk::ThreadIdType threadId) override
Definition: otbBijectionCoherencyFilter.hxx:200
otb::BijectionCoherencyFilter::InputRegionType
DispMapType::RegionType InputRegionType
Definition: otbBijectionCoherencyFilter.h:69
otb::BijectionCoherencyFilter::GetReverseHorizontalDisparityMapInput
const TDisparityImage * GetReverseHorizontalDisparityMapInput() const
Definition: otbBijectionCoherencyFilter.hxx:98
otb::BijectionCoherencyFilter::IndexType
DispMapType::IndexType IndexType
Definition: otbBijectionCoherencyFilter.h:71
otb::BijectionCoherencyFilter::BijectionCoherencyFilter
BijectionCoherencyFilter()
Definition: otbBijectionCoherencyFilter.hxx:33
otb::BijectionCoherencyFilter::SetReverseHorizontalDisparityMapInput
void SetReverseHorizontalDisparityMapInput(const TDisparityImage *hmap)
Definition: otbBijectionCoherencyFilter.hxx:64
otb::BijectionCoherencyFilter::GetReverseVerticalDisparityMapInput
const TDisparityImage * GetReverseVerticalDisparityMapInput() const
Definition: otbBijectionCoherencyFilter.hxx:108
otb::BijectionCoherencyFilter::SetDirectVerticalDisparityMapInput
void SetDirectVerticalDisparityMapInput(const TDisparityImage *vmap)
Definition: otbBijectionCoherencyFilter.hxx:57
otb::BijectionCoherencyFilter::GenerateInputRequestedRegion
void GenerateInputRequestedRegion() override
Definition: otbBijectionCoherencyFilter.hxx:160