Ocean
Mapping.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_CV_SYNTHESIS_MAPPING_H
9 #define META_OCEAN_CV_SYNTHESIS_MAPPING_H
10 
12 
15 
17 
18 #include "ocean/math/Vector2.h"
19 
20 namespace Ocean
21 {
22 
23 namespace CV
24 {
25 
26 namespace Synthesis
27 {
28 
29 /**
30  * This class is the base class for all mappings.
31  * A mapping object stores source pixel locations for every target pixel (every pixel) of the work area.
32  * @ingroup cvsynthesis
33  */
34 class Mapping
35 {
36  public:
37 
38  /**
39  * Returns the width of this mapping object.
40  * @return Mapping width in pixel, with range [0, infinity)
41  */
42  inline unsigned int width() const;
43 
44  /**
45  * Returns the height of this mapping object.
46  * @return Mapping height in pixel, with range [0, infinity)
47  */
48  inline unsigned int height() const;
49 
50  /**
51  * Applies the current mapping for one given frame.<br>
52  * Only mask pixels will be updated in the frame while the specification of a bounding box in which the mapping will be applied is used to improve the performance of the execution.
53  * @param frame The frame holding source and target area, with frame dimension identical to width() x height()
54  * @param mask The 8 bit mask defining source and target area with 0xFF defining a non-mask pixel, with same frame dimension and pixel origin as the provided frame
55  * @param xStart Horizontal start position of the update area in pixel, with range [0, width())
56  * @param xWidth Width of the update area in pixel, with range [1, width() - xStart]
57  * @param yStart Vertical start position of the update area in pixel, with range [0, height())
58  * @param yHeight Height of the update area in pixel, with range [1, height() - yStart]
59  * @param worker Optional worker object to distribute the computation
60  */
61  virtual void applyMapping(Frame& frame, const Frame& mask, const unsigned int xStart, const unsigned int xWidth, const unsigned int yStart, const unsigned int yHeight, Worker* worker = nullptr) const = 0;
62 
63  /**
64  * Returns whether this mapping object is not empty.
65  * @return True, if so
66  */
67  explicit inline operator bool() const;
68 
69  /**
70  * Calculates the normalization term for the appearance cost in accordance to the frame dimension of this mapping.
71  * @return The normalization term for the appearance cost, with range [1, infinity)
72  */
73  template <unsigned int tChannels>
74  inline unsigned int appearanceCostNormalization() const;
75 
76  /**
77  * Calculates the normalization term for the spatial cost in accordance to the frame dimension of this mapping.
78  * @return The normalization term for the spatial cost, with range [1, infinity)
79  */
80  template <unsigned int tChannels>
81  inline unsigned int spatialCostNormalization() const;
82 
83  protected:
84 
85  /**
86  * Creates a new mapping object.
87  */
88  Mapping() = default;
89 
90  /**
91  * Copies a mapping from a given mapping object.
92  * @param pixelMapping Pixel mapping to be copied
93  */
94  inline Mapping(const Mapping& pixelMapping);
95 
96  /**
97  * Moves constructor.
98  * @param pixelMapping Pixel mapping to be moved
99  */
100  inline Mapping(Mapping&& pixelMapping) noexcept;
101 
102  /**
103  * Creates a new mapping object.
104  */
105  inline Mapping(const unsigned int width, const unsigned int height);
106 
107  /**
108  * Destructs a mapping object.
109  */
110  virtual inline ~Mapping();
111 
112  /**
113  * Calculates the normalization term for the appearance cost in accordance to a specified frame dimension.
114  * @param width The width of the frame in pixel, with range [0, infinity)
115  * @param height The height of the frame in pixel, with range [0, infinity)
116  * @return The normalization term for the appearance cost, with range [1, infinity)
117  */
118  template <unsigned int tChannels>
119  static inline unsigned int calculateAppearanceCostNormalization(const unsigned int width, const unsigned int height);
120 
121  /**
122  * Calculates the normalization term for the spatial cost in accordance to a specified frame dimension.
123  * @param width The width of the frame in pixel, with range [0, infinity)
124  * @param height The height of the frame in pixel, with range [0, infinity)
125  * @return The normalization term for the spatial cost, with range [1, infinity)
126  */
127  template <unsigned int tChannels>
128  inline unsigned int calculateSpatialCostNormalization(const unsigned int width, const unsigned int height);
129 
130  /**
131  * Assign operator.
132  * @param mapping The mapping object to be copied
133  * @return Reference to this object
134  */
135  inline Mapping& operator=(const Mapping& mapping);
136 
137  /**
138  * Move operator.
139  * @param mapping The mapping object to be moved
140  * @return Reference to this object
141  */
142  inline Mapping& operator=(Mapping&& mapping) noexcept;
143 
144  protected:
145 
146  /// Width of this pixel mapping object in pixel.
147  unsigned int width_ = 0u;
148 
149  /// Height of this pixel mapping object in pixel.
150  unsigned int height_ = 0u;
151 
152  /// Appearance cost normalization factor for 1 channel 8 bit frames.
154 
155  /// Appearance cost normalization factor for 2 channel 16 bit frames.
157 
158  /// Appearance cost normalization factor for 3 channel 24 bit frames.
160 
161  /// Appearance cost normalization factor for 4 channel 32 bit frames.
163 
164  /// Spatial cost normalization factor for 1 channel 8 bit frames.
166 
167  /// Spatial cost normalization factor for 2 channel 16 bit frames.
169 
170  /// Spatial cost normalization factor for 3 channel 24 bit frames.
172 
173  /// Spatial cost normalization factor for 4 channel 32 bit frames.
175 };
176 
177 inline Mapping::Mapping(const Mapping& pixelMapping) :
178  width_(pixelMapping.width_),
179  height_(pixelMapping.height_),
180  appearanceCostNormalizationInt8_(pixelMapping.appearanceCostNormalizationInt8_),
181  appearanceCostNormalizationInt16_(pixelMapping.appearanceCostNormalizationInt16_),
182  appearanceCostNormalizationInt24_(pixelMapping.appearanceCostNormalizationInt24_),
183  appearanceCostNormalizationInt32_(pixelMapping.appearanceCostNormalizationInt32_),
184  sapatialCostNormalizationInt8_(pixelMapping.sapatialCostNormalizationInt8_),
185  spatialCostNormalizationInt16_(pixelMapping.spatialCostNormalizationInt16_),
186  spatialCostNormalizationInt24_(pixelMapping.spatialCostNormalizationInt24_),
187  spatialCostNormalizationInt32_(pixelMapping.spatialCostNormalizationInt32_)
188 {
189  const unsigned int windowHalf = 2u; // **TODO** find a good solution to be able to use flexible patch sizes (not always 5x5)
190 
191  ocean_assert(int64_t(appearanceCostNormalizationInt8_) * int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(width_) + sqr(height_)) +
192  int64_t(sapatialCostNormalizationInt8_) + int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(255)) * 26ll < int64_t((unsigned int)(-1)));
193 
194  ocean_assert(int64_t(appearanceCostNormalizationInt16_) * int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(width_) + sqr(height_)) +
195  int64_t(spatialCostNormalizationInt16_) + int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(255)) * 2ll * 26ll < int64_t((unsigned int)(-1)));
196 
197  ocean_assert(int64_t(appearanceCostNormalizationInt24_) * int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(width_) + sqr(height_)) +
198  int64_t(spatialCostNormalizationInt24_) + int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(255)) * 3ll * 26ll < int64_t((unsigned int)(-1)));
199 
200  ocean_assert(int64_t(appearanceCostNormalizationInt32_) * int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(width_) + sqr(height_)) +
201  int64_t(spatialCostNormalizationInt32_) + int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(255)) * 4ll * 26ll < int64_t((unsigned int)(-1)));
202 
203  OCEAN_SUPPRESS_UNUSED_WARNING(windowHalf);
204 }
205 
206 inline Mapping::Mapping(Mapping&& pixelMapping) noexcept :
207  width_(pixelMapping.width_),
208  height_(pixelMapping.height_),
209  appearanceCostNormalizationInt8_(pixelMapping.appearanceCostNormalizationInt8_),
210  appearanceCostNormalizationInt16_(pixelMapping.appearanceCostNormalizationInt16_),
211  appearanceCostNormalizationInt24_(pixelMapping.appearanceCostNormalizationInt24_),
212  appearanceCostNormalizationInt32_(pixelMapping.appearanceCostNormalizationInt32_),
213  sapatialCostNormalizationInt8_(pixelMapping.sapatialCostNormalizationInt8_),
214  spatialCostNormalizationInt16_(pixelMapping.spatialCostNormalizationInt16_),
215  spatialCostNormalizationInt24_(pixelMapping.spatialCostNormalizationInt24_),
216  spatialCostNormalizationInt32_(pixelMapping.spatialCostNormalizationInt32_)
217 {
218  const unsigned int windowHalf = 2u; // **TODO** find a good solution to be able to use flexible patch sizes (not always 5x5)
219 
220  ocean_assert(int64_t(appearanceCostNormalizationInt8_) * int64_t(sqr(2 * windowHalf + 1)) * int64_t(sqr(width_) + sqr(height_)) +
221  int64_t(sapatialCostNormalizationInt8_) + int64_t(sqr(2 * windowHalf + 1)) * int64_t(sqr(255)) * 26ll < int64_t((unsigned int)(-1)));
222 
223  ocean_assert(int64_t(appearanceCostNormalizationInt16_) * int64_t(sqr(2 * windowHalf + 1)) * int64_t(sqr(width_) + sqr(height_)) +
224  int64_t(spatialCostNormalizationInt16_) + int64_t(sqr(2 * windowHalf + 1)) * int64_t(sqr(255)) * 2ll * 26ll < int64_t((unsigned int)(-1)));
225 
226  ocean_assert(int64_t(appearanceCostNormalizationInt24_) * int64_t(sqr(2 * windowHalf + 1)) * int64_t(sqr(width_) + sqr(height_)) +
227  int64_t(spatialCostNormalizationInt24_) + int64_t(sqr(2 * windowHalf + 1)) * int64_t(sqr(255)) * 3ll * 26ll < int64_t((unsigned int)(-1)));
228 
229  ocean_assert(int64_t(appearanceCostNormalizationInt32_) * int64_t(sqr(2 * windowHalf + 1)) * int64_t(sqr(width_) + sqr(height_)) +
230  int64_t(spatialCostNormalizationInt32_) + int64_t(sqr(2 * windowHalf + 1)) * int64_t(sqr(255)) * 4ll * 26ll < int64_t((unsigned int)(-1)));
231 
232  OCEAN_SUPPRESS_UNUSED_WARNING(windowHalf);
233 
234  pixelMapping.width_ = 0u;
235  pixelMapping.height_ = 0u;
236 
237  pixelMapping.appearanceCostNormalizationInt8_ = 0u;
238  pixelMapping.appearanceCostNormalizationInt16_ = 0u;
239  pixelMapping.appearanceCostNormalizationInt24_ = 0u;
240  pixelMapping.appearanceCostNormalizationInt32_ = 0u;
241 
242  pixelMapping.sapatialCostNormalizationInt8_ = 0u;
243  pixelMapping.spatialCostNormalizationInt16_ = 0u;
244  pixelMapping.spatialCostNormalizationInt24_ = 0u;
245  pixelMapping.spatialCostNormalizationInt32_ = 0u;
246 }
247 
248 inline Mapping::Mapping(const unsigned int width, const unsigned int height) :
249  width_(width),
250  height_(height),
251  appearanceCostNormalizationInt8_(calculateAppearanceCostNormalization<1u>(width, height)),
252  appearanceCostNormalizationInt16_(calculateAppearanceCostNormalization<2u>(width, height)),
253  appearanceCostNormalizationInt24_(calculateAppearanceCostNormalization<3u>(width, height)),
254  appearanceCostNormalizationInt32_(calculateAppearanceCostNormalization<4u>(width, height)),
255  sapatialCostNormalizationInt8_(calculateSpatialCostNormalization<1u>(width, height)),
256  spatialCostNormalizationInt16_(calculateSpatialCostNormalization<2u>(width, height)),
257  spatialCostNormalizationInt24_(calculateSpatialCostNormalization<3u>(width, height)),
258  spatialCostNormalizationInt32_(calculateSpatialCostNormalization<4u>(width, height))
259 {
260  const unsigned int windowHalf = 2u; // **TODO** find a good solution to be able to use flexible patch sizes (not always 5x5)
261 
262  ocean_assert(int64_t(appearanceCostNormalizationInt8_) * int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(width_) + sqr(height_)) +
263  int64_t(sapatialCostNormalizationInt8_) + int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(255)) * 26ll < int64_t((unsigned int)(-1)));
264 
265  ocean_assert(int64_t(appearanceCostNormalizationInt16_) * int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(width_) + sqr(height_)) +
266  int64_t(spatialCostNormalizationInt16_) + int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(255)) * 2ll * 26ll < int64_t((unsigned int)(-1)));
267 
268  ocean_assert(int64_t(appearanceCostNormalizationInt24_) * int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(width_) + sqr(height_)) +
269  int64_t(spatialCostNormalizationInt24_) + int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(255)) * 3ll * 26ll < int64_t((unsigned int)(-1)));
270 
271  ocean_assert(int64_t(appearanceCostNormalizationInt32_) * int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(width_) + sqr(height_)) +
272  int64_t(spatialCostNormalizationInt32_) + int64_t(sqr(2u * windowHalf + 1u)) * int64_t(sqr(255)) * 4ll * 26ll < int64_t((unsigned int)(-1)));
273 
274  OCEAN_SUPPRESS_UNUSED_WARNING(windowHalf);
275 }
276 
278 {
279  // nothing to do here
280 }
281 
282 inline unsigned int Mapping::width() const
283 {
284  return width_;
285 }
286 
287 inline unsigned int Mapping::height() const
288 {
289  return height_;
290 }
291 
292 inline Mapping::operator bool() const
293 {
294  return width_ != 0u && height_ != 0u;
295 }
296 
297 template <unsigned int tChannels>
298 inline unsigned int Mapping::appearanceCostNormalization() const
299 {
300  static_assert(oceanFalse<tChannels>(), "Invalid number of frame channels!");
301 
302  return 0u;
303 }
304 
305 template <>
306 inline unsigned int Mapping::appearanceCostNormalization<1u>() const
307 {
309 }
310 
311 template <>
312 inline unsigned int Mapping::appearanceCostNormalization<2u>() const
313 {
315 }
316 
317 template <>
318 inline unsigned int Mapping::appearanceCostNormalization<3u>() const
319 {
321 }
322 
323 template <>
324 inline unsigned int Mapping::appearanceCostNormalization<4u>() const
325 {
327 }
328 
329 template <unsigned int tChannels>
330 inline unsigned int Mapping::spatialCostNormalization() const
331 {
332  static_assert(oceanFalse<tChannels>(), "Invalid number of frame channels!");
333 
334  return 0u;
335 }
336 
337 template <>
338 inline unsigned int Mapping::spatialCostNormalization<1u>() const
339 {
341 }
342 
343 template <>
344 inline unsigned int Mapping::spatialCostNormalization<2u>() const
345 {
347 }
348 
349 template <>
350 inline unsigned int Mapping::spatialCostNormalization<3u>() const
351 {
353 }
354 
355 template <>
356 inline unsigned int Mapping::spatialCostNormalization<4u>() const
357 {
359 }
360 
361 template <unsigned int tChannels>
362 unsigned int Mapping::calculateAppearanceCostNormalization(const unsigned int width, const unsigned int height)
363 {
364  if (width == 0u || height == 0u)
365  return 1u;
366 
367  unsigned int appearanceNormalization = tChannels * 255u * 255u;
368  unsigned int spatialCost = width * width + height * height;
369 
370  if (appearanceNormalization > spatialCost)
371  {
372  appearanceNormalization = (appearanceNormalization + spatialCost / 2u) / spatialCost;
373  // spatialCost = 1u;
374  }
375  else
376  {
377  //spatialCost = (spatialCost + appearanceNormalization / 2u) / appearanceNormalization;
378  appearanceNormalization = 1u;
379  }
380 
381  return appearanceNormalization;
382 }
383 
384 template <unsigned int tChannels>
385 unsigned int Mapping::calculateSpatialCostNormalization(const unsigned int width, const unsigned int height)
386 {
387  if (width == 0u || height == 0u)
388  return 1u;
389 
390  unsigned int appearanceNormalization = tChannels * 255u * 255u;
391  unsigned int spatialCost = width * width + height * height;
392 
393  if (appearanceNormalization > spatialCost)
394  {
395  //appearanceNormalization = (appearanceNormalization + spatialCost / 2u) / spatialCost;
396  spatialCost = 1;
397  }
398  else
399  {
400  spatialCost = (spatialCost + appearanceNormalization / 2u) / appearanceNormalization;
401  //appearanceNormalization = 1;
402  }
403 
404  return spatialCost;
405 }
406 
407 inline Mapping& Mapping::operator=(const Mapping& mapping)
408 {
409  width_ = mapping.width_;
410  height_ = mapping.height_;
411 
416 
421 
422  return *this;
423 }
424 
425 inline Mapping& Mapping::operator=(Mapping&& mapping) noexcept
426 {
427  if (this != &mapping)
428  {
429  width_ = mapping.width_;
430  height_ = mapping.height_;
431 
432  appearanceCostNormalizationInt8_ = mapping.appearanceCostNormalizationInt8_;
433  appearanceCostNormalizationInt16_ = mapping.appearanceCostNormalizationInt16_;
434  appearanceCostNormalizationInt24_ = mapping.appearanceCostNormalizationInt24_;
435  appearanceCostNormalizationInt32_ = mapping.appearanceCostNormalizationInt32_;
436 
437  sapatialCostNormalizationInt8_ = mapping.sapatialCostNormalizationInt8_;
438  spatialCostNormalizationInt16_ = mapping.spatialCostNormalizationInt16_;
439  spatialCostNormalizationInt24_ = mapping.spatialCostNormalizationInt24_;
440  spatialCostNormalizationInt32_ = mapping.spatialCostNormalizationInt32_;
441 
442  mapping.width_ = 0u;
443  mapping.height_ = 0u;
444 
445  mapping.appearanceCostNormalizationInt8_ = 0u;
446  mapping.appearanceCostNormalizationInt16_ = 0u;
447  mapping.appearanceCostNormalizationInt24_ = 0u;
448  mapping.appearanceCostNormalizationInt32_ = 0u;
449 
450  mapping.sapatialCostNormalizationInt8_ = 0u;
451  mapping.spatialCostNormalizationInt16_ = 0u;
452  mapping.spatialCostNormalizationInt24_ = 0u;
453  mapping.spatialCostNormalizationInt32_ = 0u;
454  }
455 
456  return *this;
457 }
458 
459 }
460 
461 }
462 
463 }
464 
465 #endif // META_OCEAN_CV_SYNTHESIS_MAPPING_H
This class is the base class for all mappings.
Definition: Mapping.h:35
unsigned int width_
Width of this pixel mapping object in pixel.
Definition: Mapping.h:147
unsigned int spatialCostNormalization() const
Calculates the normalization term for the spatial cost in accordance to the frame dimension of this m...
Definition: Mapping.h:330
unsigned int width() const
Returns the width of this mapping object.
Definition: Mapping.h:282
unsigned int spatialCostNormalizationInt32_
Spatial cost normalization factor for 4 channel 32 bit frames.
Definition: Mapping.h:174
Mapping & operator=(const Mapping &mapping)
Assign operator.
Definition: Mapping.h:407
unsigned int appearanceCostNormalizationInt32_
Appearance cost normalization factor for 4 channel 32 bit frames.
Definition: Mapping.h:162
unsigned int appearanceCostNormalization() const
Calculates the normalization term for the appearance cost in accordance to the frame dimension of thi...
Definition: Mapping.h:298
unsigned int spatialCostNormalizationInt16_
Spatial cost normalization factor for 2 channel 16 bit frames.
Definition: Mapping.h:168
unsigned int height_
Height of this pixel mapping object in pixel.
Definition: Mapping.h:150
unsigned int sapatialCostNormalizationInt8_
Spatial cost normalization factor for 1 channel 8 bit frames.
Definition: Mapping.h:165
unsigned int spatialCostNormalizationInt24_
Spatial cost normalization factor for 3 channel 24 bit frames.
Definition: Mapping.h:171
unsigned int height() const
Returns the height of this mapping object.
Definition: Mapping.h:287
virtual ~Mapping()
Destructs a mapping object.
Definition: Mapping.h:277
unsigned int calculateSpatialCostNormalization(const unsigned int width, const unsigned int height)
Calculates the normalization term for the spatial cost in accordance to a specified frame dimension.
Definition: Mapping.h:385
unsigned int appearanceCostNormalizationInt16_
Appearance cost normalization factor for 2 channel 16 bit frames.
Definition: Mapping.h:156
virtual void applyMapping(Frame &frame, const Frame &mask, const unsigned int xStart, const unsigned int xWidth, const unsigned int yStart, const unsigned int yHeight, Worker *worker=nullptr) const =0
Applies the current mapping for one given frame.
unsigned int appearanceCostNormalizationInt8_
Appearance cost normalization factor for 1 channel 8 bit frames.
Definition: Mapping.h:153
static unsigned int calculateAppearanceCostNormalization(const unsigned int width, const unsigned int height)
Calculates the normalization term for the appearance cost in accordance to a specified frame dimensio...
Definition: Mapping.h:362
unsigned int appearanceCostNormalizationInt24_
Appearance cost normalization factor for 3 channel 24 bit frames.
Definition: Mapping.h:159
Mapping()=default
Creates a new mapping object.
This class implements Ocean's image class.
Definition: Frame.h:1760
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
unsigned int sqr(const char value)
Returns the square value of a given value.
Definition: base/Utilities.h:1029
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15