Ocean
SphericalEnvironment.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_TRACKING_SPHERICAL_ENVIRONMENT_H
9 #define META_OCEAN_TRACKING_SPHERICAL_ENVIRONMENT_H
10 
12 
13 #include "ocean/base/Callback.h"
14 
16 
20 
22 
23 namespace Ocean
24 {
25 
26 namespace Tracking
27 {
28 
29 /**
30  * This class implements a spherical environment based on a panorama frame.
31  * The environment can be extended by new camera frame with unknown orientation as long as the orientation offset between successive frames is not too large.<br>
32  * Further, the environment can be used to determine the orientation of a given camera frame capturing an already known area.<br>
33  * @ingroup tracking
34  */
35 class OCEAN_TRACKING_EXPORT SphericalEnvironment : public CV::Advanced::PanoramaFrame
36 {
37  protected:
38 
39  /**
40  * Definition of a vector holding 8 bit characters.
41  */
42  typedef std::vector<uint8_t> Buffer;
43 
44  /**
45  * Definition of a vector holding buffers.
46  */
47  typedef std::vector<Buffer> Buffers;
48 
49  /**
50  * Definition of a map mapping indices.
51  */
52  typedef std::unordered_map<uint32_t, uint32_t> IndexMap;
53 
54  /**
55  * Definition of a map mapping unique frame-feature-point-ids to unique frame-feature-point-ids.
56  */
57  typedef std::multimap<uint64_t, uint64_t> FeaturePointMap;
58 
59  /**
60  * Forward declaration of a base class for all optimization classes.
61  */
62  class CameraData;
63 
64  /**
65  * Forward declaration of the data class allowing to optimize the intrinsic and extrinsic camera parameters.
66  */
67  class CameraOrientationsData;
68 
69  /**
70  * Forward declaration of the data class allowing to find an initial camera field of view.
71  */
72  class CameraFovData;
73 
74  /**
75  * Forward declaration of a data class allowing to optimize a 2x2 transformation table.
76  */
77  class TransformationTableData2x2;
78 
79  public:
80 
81  /**
82  * Definition of a callback function allowing to determine an update mask for a current camera frame.
83  * Parameter 0: The frame pyramid of the previous frame
84  * Parameter 1: The frame pyramid of the current frame
85  * Parameter 2: The camera profile of the previous frame
86  * Parameter 3: The camera profile of the current frame
87  * Parameter 4: The camera orientation of the previous frame
88  * Parameter 5: The camera orientation of the current frame
89  * Parameter 6: The mask value for static image content
90  * Parameter 7: The resulting update mask frame
91  * Parameter 8: An optional worker object
92  * Return value: True, if the camera frame can be used to update the panorama frame
93  */
95 
96  /**
97  * Definition of a vector holding groups of pairs between camera pose ids and image point ids.
98  */
99  typedef std::vector<IndexPairs32> PoseImagePointPairGroups;
100 
101  public:
102 
103  /**
104  * Creates an invalid spherical environment object.
105  */
106  SphericalEnvironment() = default;
107 
108  /**
109  * Creates a new spherical environment object.
110  * @param panoramaDimensionWidth The width of the entire panorama frame (the maximal possible size) representing horizontal 360 degrees, in pixel with range [1, infinity)
111  * @param panoramaDimensionHeight The height of the entire panorama frame (the maximal possible size) representing vertical 180 degrees, in pixel with range [1, infinity)
112  * @param maskValue The mask value defining the 8 bit pixel value of valid pixels
113  * @param frameMode The update mode of this panorama frame
114  */
115  inline SphericalEnvironment(const unsigned int panoramaDimensionWidth, const unsigned int panoramaDimensionHeight, const uint8_t maskValue, const UpdateMode frameMode);
116 
117  /**
118  * Adds a new camera frame to the panorama frame for which the orientation is unknown.
119  * The frame may be either the first frame of a sequence of frame or a subsequent frame in the sequence as long as the frame content of successive frames does not change too much.<br>
120  * The first frame is assigned with the default camera orientation, the orientation of successive frames is determined automatically.<br>
121  * @param pinholeCamera The camera profile of the current frame
122  * @param frame The camera frame which will be added
123  * @param approximationBinSize Optional width of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
124  * @param fineAdjustmentEstimator A robust estimator type, if the given camera frame will be distorted up to a small scale so that it fits with the already existing image content in the environment
125  * @param optimizeCamera True, to optimize the given camera profile, False to use the given camera profile
126  * @param worker Optional worker object to distribute the computation
127  * @param orientation Optional the resulting orientation of the given camera frame, with respect to the default orientation of the first camera frame
128  * @param optimizedCamera Optional resulting optimized camera profile
129  * @param frameCallback Optional callback function that is invoked before the panorama frame will be updated and which allows to define a frame mask separating the frame in static and dynamic image areas, only static image content is used to extend the environment
130  * @return True, if succeeded
131  */
132  bool extendEnvironment(const PinholeCamera& pinholeCamera, const Frame& frame, const unsigned int approximationBinSize = 20u, const Geometry::Estimator::EstimatorType fineAdjustmentEstimator = Geometry::Estimator::ET_INVALID, const bool optimizeCamera = false, Worker* worker = nullptr, SquareMatrix3* orientation = nullptr, PinholeCamera* optimizedCamera = nullptr, const FrameCallback& frameCallback = FrameCallback());
133 
134  /**
135  * Determines the precise orientation of a given camera frame.
136  * @param pinholeCamera The camera profile of the current frame, must be valid
137  * @param orientation The rough orientation of the given frame, in relation to the spherical environment, must be valid
138  * @param frame The camera frame which will be added, must be valid
139  * @param mask An optional mask defining valid and invalid pixels in the given frame, may be invalid if all pixels are valid
140  * @param estimator The estimator type which is applied to determine the precise orientation
141  * @param optimizedOrientation The resulting precise orientation best matching to the given camera frame
142  * @param optimizedCamera Optional resulting optimized camera profile, nullptr if the given camera profile is not optimized internally
143  * @param fineAdjustment Optional resulting transformation lookup table with relative offsets providing a fine adjustment for the camera frame
144  * @param approximationBinSize Optional width of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
145  * @param worker Optional worker object to distribute the computation
146  * @return True, if succeeded
147  */
148  bool optimizeOrientation(const PinholeCamera& pinholeCamera, const SquareMatrix3& orientation, const Frame& frame, const Frame& mask, const Geometry::Estimator::EstimatorType estimator, SquareMatrix3& optimizedOrientation, PinholeCamera* optimizedCamera = nullptr, LookupTable* fineAdjustment = nullptr, const unsigned int approximationBinSize = 20u, Worker* worker = nullptr);
149 
150  /**
151  * Clears the panorama frame and allows to set a new first camera frame.
152  * @see PanoramaFrame::clear().
153  */
154  virtual void clear();
155 
156  /**
157  * Determines point correspondences between two camera frames captured with individual locations (describable by a homography) by application of a pyramid-based patch tracking approach.
158  * The given homography can be a full 8-DOF homography including e.g., scale and projection.
159  * @param sourceFrame The source frame for which the correspondences will be determined, must be valid
160  * @param targetFrame The second frame for which the correspondences will be determine, with same pixel format as the first frame, must be valid
161  * @param homography The known homography between both frames, transforming points defined in the first frame to points defined in the second frame (pointTargetFrame = H * pointSourceFrame), must be valid
162  * @param sourcePoints The resulting points of the correspondences, defined in the source frame
163  * @param targetPoints The resulting points of the correspondences, defined in the target frame, one for each source point
164  * @param patchSize The size of the patches to be used for tracking, possible values are 7, 15 or 31
165  * @param maximalDistance Maximal expected distance (radius) between two tracked correspondences in pixel, with range [1, infinity)
166  * @param coarsestLayerRadius The search radius on the coarsest layer, with range [2, infinity)
167  * @param downsamplingMode The downsampling mode that is applied to create the pyramid layers
168  * @param worker Optional worker object to distribute the computation
169  * @return True, if succeeded
170  */
171  static bool determinePointCorrespondencesHomography(const Frame& sourceFrame, const Frame& targetFrame, const SquareMatrix3& homography, Vectors2& sourcePoints, Vectors2& targetPoints, const unsigned int patchSize, const unsigned int maximalDistance = 32u, const unsigned int coarsestLayerRadius = 8u, const CV::FramePyramid::DownsamplingMode downsamplingMode = CV::FramePyramid::DM_FILTER_14641, Worker* worker = nullptr);
172 
173  /**
174  * Determines point correspondences between two camera frames captured with individual locations (describable by a homography) by application of a pyramid-based patch tracking approach.
175  * The given homography can be a full 8-DOF homography including e.g., scale and projection.
176  * @param sourceFramePyramid The frame pyramid of the source frame for which the correspondences will be determined, should hold enough layers, must be valid
177  * @param targetFrame The second frame for which the correspondences will be determine, with same pixel format as the first frame, must be valid
178  * @param homography The known homography between both frames, transforming points defined in the first frame to points defined in the second frame (pointTargetFrame = H * pointSourceFrame), must be valid
179  * @param sourcePointCandidates The candidate of source points out of which the resulting correspondences will be created, defined in the source frame
180  * @param validSourcePoints The resulting points of the correspondences, defined in the source frame and a subset of sourcePointCandidates
181  * @param validTargetPoints The resulting points of the correspondences, defined in the target frame, one for each source point
182  * @param validSourcePointIndices The resulting indices of the candidates of the source points which actually has been used as correspondences, one for each correspondence
183  * @param patchSize The size of the patches to be used for tracking, possible values are 7, 15 or 31
184  * @param maximalDistance Maximal expected distance (radius) between two tracked correspondences in pixel, with range [1, infinity)
185  * @param coarsestLayerRadius The search radius on the coarsest layer, with range [2, infinity)
186  * @param downsamplingMode The downsampling mode that is applied to create the pyramid layers
187  * @param worker Optional worker object to distribute the computation
188  * @param usedPointCandidates Optional resulting number of point candidates that have been used (e.g., that are located inside the intersection of both frames), with range [0, sourcePointCandidates.size()]
189  * @return True, if succeeded
190  */
191  static bool determinePointCorrespondencesHomography(const CV::FramePyramid& sourceFramePyramid, const Frame& targetFrame, const SquareMatrix3& homography, const Vectors2& sourcePointCandidates, Vectors2& validSourcePoints, Vectors2& validTargetPoints, Indices32& validSourcePointIndices, const unsigned int patchSize, const unsigned int maximalDistance = 32u, const unsigned int coarsestLayerRadius = 8u, const CV::FramePyramid::DownsamplingMode downsamplingMode = CV::FramePyramid::DM_FILTER_14641, Worker* worker = nullptr, size_t* usedPointCandidates = nullptr);
192 
193  /**
194  * This function determines a mask for image areas not matching with the common homography between two successive camera frames.
195  * An image point does not match with the common homography if the point has a distance larger than 3 pixels to the expected homography point.<br>
196  * @param previousFramePyramid The frame pyramid of the previous camera frame
197  * @param currentFramePyramid The frame pyramid of the current camera frame
198  * @param previousCamera The camera profile of the previous camera frame
199  * @param currentCamera The camera profile of the current camera frame
200  * @param previousOrientation The orientation of the previous camera frame, in relation to the coordinate system of the panorama frame
201  * @param currentOrientation The orientation of the current camera frame, in relation to the coordinate system of the panorama frame
202  * @param maskValue The mask value for static image content
203  * @param currentMask The resulting mask for the current camera frame separating static and dynamic image content
204  * @param worker Optional worker object to distribute the computation
205  * @return True, if a valid mask could be determined
206  */
207  static bool nonHomographyMask(const CV::FramePyramid& previousFramePyramid, const CV::FramePyramid& currentFramePyramid, const PinholeCamera& previousCamera, const PinholeCamera& currentCamera, const SquareMatrix3& previousOrientation, const SquareMatrix3& currentOrientation, const uint8_t maskValue, Frame& currentMask, Worker* worker = nullptr);
208 
209  /**
210  * Optimizes the camera profile for a given set of camera frames with known orientations so that the offset between corresponding points in the individual camera frames becomes as small as possible.
211  * @param pinholeCamera The camera profile which will be optimized
212  * @param frames The individual camera frame
213  * @param orientations The orientations of the individual camera frames, one orientation for each frame
214  * @param optimizedCamera The resulting optimized camera profile
215  * @param worker Optional worker object to distribute the computation
216  * @return True, if a valid mask could be determined
217  */
218  static bool optimizeCamera(const PinholeCamera& pinholeCamera, const Frames& frames, const SquareMatrices3& orientations, PinholeCamera& optimizedCamera, Worker* worker = nullptr);
219 
220  /**
221  * Optimizes the camera profile for a given set of image points from individual camera frames so that the offset between the corresponding points becomes as small as possible.
222  * @param pinholeCamera The camera profile which will be optimized
223  * @param orientations The orientations of the individual camera frames, one orientation for each frame
224  * @param imagePoints The entire set of image points holding all image points from all image frames
225  * @param orientationImagePointPairGroups Groups of pairs combining indices from the set of image points with indices of unique feature points, one set of pairs for each camera frame
226  * @param optimizedCamera The resulting camera profile with ideal field of view
227  * @param optimizedOrientations The camera orientations matching with the new camera profile
228  * @param iterations Number of iterations to be applied at most, if no convergence can be reached
229  * @param estimator Robust error estimator to be used
230  * @param lambda Initial Levenberg-Marquardt damping value which may be changed after each iteration using the damping factor, with range [0, infinity)
231  * @param lambdaFactor Levenberg-Marquardt damping factor to be applied to the damping value, with range [1, infinity)
232  * @param initialError Optional resulting averaged robust (depending on estimator) pixel error for the given initial parameters
233  * @param finalError Optional resulting averaged robust (depending on estimator) pixel error for the final optimized parameters
234  * @param intermediateErrors Optional resulting intermediate (improving) errors
235  * @return True, if the camera profile could be optimized
236  */
237  static bool optimizeCamera(const PinholeCamera& pinholeCamera, const SquareMatrices3& orientations, const ImagePoints& imagePoints, const PoseImagePointPairGroups& orientationImagePointPairGroups, PinholeCamera& optimizedCamera, SquareMatrices3& optimizedOrientations, const unsigned int iterations = 20u, const Geometry::Estimator::EstimatorType estimator = Geometry::Estimator::ET_SQUARE, Scalar lambda = Scalar(0.001), const Scalar lambdaFactor = Scalar(5), Scalar* initialError = nullptr, Scalar* finalError = nullptr, Scalars* intermediateErrors = nullptr);
238 
239  /**
240  * Determines the initial field of view for a set of camera frames with known orientation and a corresponding set of unique features observed in several individual frames.
241  * @param width The width of the camera profile in pixel, with range [1, infinity)
242  * @param height The height of the camera profile in pixel, with range [1, infinity)
243  * @param orientations The known orientations of the individual camera frames
244  * @param imagePoints The entire set of image points observed in individual camera frames
245  * @param orientationImagePointPairGroups Groups of pairs combining indices from the set of image points with indices of unique feature points, one set of pairs for each camera frame
246  * @param optimizedCamera The resulting camera profile with ideal field of view
247  * @param optimizedOrientations The camera orientations matching with the new camera profile
248  * @param lowerFovX The lower bound of the possible horizontal field of view
249  * @param upperFovX The upper bound of the possible horizontal field of view
250  * @param steps The number of steps in which the defined angle range is subdivided
251  * @return True, if succeeded
252  */
253  static bool findInitialFieldOfView(const unsigned int width, const unsigned int height, const SquareMatrices3& orientations, const ImagePoints& imagePoints, const PoseImagePointPairGroups& orientationImagePointPairGroups, PinholeCamera& optimizedCamera, SquareMatrices3& optimizedOrientations, const Scalar lowerFovX = Numeric::deg2rad(40), const Scalar upperFovX = Numeric::deg2rad(90), const unsigned int steps = 10u);
254 
255  /**
256  * Determines a 2x2 transformation table (a lookup table) transforming a set of points (defined in the domain of the transformation table) to another set of points.
257  * The resulting transformation provides relative transformation offset from one point set to the other point set: points1 = transformation(points0).<br>
258  * @param width The width of the resulting lookup table, with range [1, infinity)
259  * @param height The height of the resulting lookup table, with range [1, infinity)
260  * @param points0 The set of points lying inside the resulting lookup table, the transformation will provide corrected positions for these points, with ranges [0, width)x[0, height)
261  * @param points1 The set of points corresponding to the first set of points but having the correct positions, with ranges (-infinity, infinity)x(-infinity, infinity)
262  * @param transformation0to1 The resulting transformation which will transform points0 to points1
263  * @param iterations Number of iterations to be applied at most, if no convergence can be reached
264  * @param estimator Robust error estimator to be used
265  * @param lambda Initial Levenberg-Marquardt damping value which may be changed after each iteration using the damping factor, with range [0, infinity)
266  * @param lambdaFactor Levenberg-Marquardt damping factor to be applied to the damping value, with range [1, infinity)
267  * @param initialError Optional resulting averaged pixel error for the given initial parameters, in relation to the defined estimator
268  * @param finalError Optional resulting averaged pixel error for the final optimized parameters, in relation to the defined estimator
269  * @return True, if succeeded
270  */
271  static bool determineTransformationTable2x2(const unsigned int width, const unsigned int height, const Vectors2& points0, const Vectors2& points1, LookupCorner2<Vector2>& transformation0to1, const unsigned int iterations = 20u, const Geometry::Estimator::EstimatorType estimator = Geometry::Estimator::ET_SQUARE, Scalar lambda = Scalar(0.001), const Scalar lambdaFactor = Scalar(5), Scalar* initialError = nullptr, Scalar* finalError = nullptr);
272 
273  protected:
274 
275  /**
276  * Interpolates square image patches with sub-pixel position and stores the image content as patch buffer.
277  * @param frame The frame in which the patches are located, must be valid
278  * @param positions The center positions of the individual patches, with ranges [tSize / 2, frame.width() - tSize / 2 - 1)x[tSize / 2, frame.height() - tSize / 2 - 1)
279  * @param worker Optional worker object to distribute the computation
280  * @return The buffer storing all interpolated patches consecutively
281  * @tparam tSize The size of the image patches (tSize x tSize)
282  */
283  template <unsigned int tSize>
284  static Buffer interpolateSquarePatches(const Frame& frame, const Vectors2& positions, Worker* worker = nullptr);
285 
286  /**
287  * Interpolates square image patches with sub-pixel position and stores the image content as patch buffer.
288  * @param frame The frame in which the patches are located with 8 bit per channel
289  * @param width The width of the given frame in pixel, with range [1, infinity)
290  * @param height The height of the given frame in pixel, with range [1, infinity)
291  * @param framePaddingElements The number of padding elements at the end of each frame row, in elements, with range [0, infinity)
292  * @param positions The center positions of the individual patches, with ranges [tSize / 2, width - tSize / 2 - 1)x[tSize / 2, height - tSize / 2 - 1)
293  * @param result The buffer receiving the resulting interpolated patches
294  * @param worker Optional worker object to distribute the computation
295  * @tparam tChannels The number of image channels, with range [1, infinity)
296  * @tparam tSize The size of the image patches (tSize x tSize), with range [1, infinity) must be odd
297  */
298  template <unsigned int tChannels, unsigned int tSize>
299  static void interpolateSquarePatches8BitPerChannel(const uint8_t* frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const Vectors2& positions, uint8_t* result, Worker* worker = nullptr);
300 
301  /**
302  * Interpolates a subset of square image patches with sub-pixel position and stores the image content as patch buffer.
303  * @param frame The frame in which the patches are located with 8 bit per channel
304  * @param width The width of the given frame in pixel, with range [1, infinity)
305  * @param height The height of the given frame in pixel, with range [1, infinity)
306  * @param framePaddingElements The number of padding elements at the end of each frame row, in elements, with range [0, infinity)
307  * @param positions The center positions of the individual patches, with ranges [tSize / 2, width - tSize / 2 - 1)x[tSize / 2, height - tSize / 2 - 1)
308  * @param result The buffer receiving the resulting interpolated patches
309  * @param firstPosition The first position to be handled
310  * @param numberPositions The number of positions to be handled
311  * @tparam tChannels The number of image channels, with range [1, infinity)
312  * @tparam tSize The size of the image patches (tSize x tSize), with range [1, infinity) must be odd
313  */
314  template <unsigned int tChannels, unsigned int tSize>
315  static void interpolateSquarePatches8BitPerChannelSubset(const uint8_t* frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const Vector2* positions, uint8_t* result, const unsigned int firstPosition, const unsigned int numberPositions);
316 
317  /**
318  * Finds unique bijective point correspondences between two given camera frames from a set of already detected unique feature points.
319  * @param camera0 The camera profile of the first frame, must be valid
320  * @param camera1 The camera profile of the second frame, must be valid
321  * @param pixelFormat The pixel of the given buffers storing interpolated image patches
322  * @param orientation0 The orientation of the first frame, must be valid
323  * @param orientation1 The orientation of the second frame, must be valid
324  * @param buffer0 The buffer storing interpolated image patches from the first frame, matching with the given image points
325  * @param buffer1 The buffer storing interpolated image patches form the second frame, matching with the given image points
326  * @param points0 The center positions of the image patches in the first frame
327  * @param points1 The center positions of the image patches in the second frame
328  * @param distribution0 The point distribution of the image points from the first frame
329  * @param distribution1 The point distribution of the image points from the second frame
330  * @param worker Optional worker object to distribute the computation
331  * @return A set if unique bijective point correspondences between the first and second frame
332  * @tparam tSize The size of the image patches (tSize x tSize), with range [1, infinity) must be odd
333  * @see findBijectiveCorrespondences8BitPerChannel().
334  */
335  template < unsigned int tSize>
336  static IndexPairs32 findBijectiveCorrespondences(const PinholeCamera& camera0, const PinholeCamera& camera1, const FrameType::PixelFormat pixelFormat, const SquareMatrix3& orientation0, const SquareMatrix3& orientation1, const Buffer& buffer0, const Buffer& buffer1, const Vectors2& points0, const Vectors2& points1, const Geometry::SpatialDistribution::DistributionArray& distribution0, const Geometry::SpatialDistribution::DistributionArray& distribution1, Worker* worker);
337 
338  /**
339  * Finds unique bijective point correspondences between two given camera frames with eight bit per channel from a set of already detected unique feature points.
340  * @param camera0 The camera profile of the first frame, must be valid
341  * @param camera1 The camera profile of the second frame, must be valid
342  * @param orientation0 The orientation of the first frame, must be valid
343  * @param orientation1 The orientation of the second frame, must be valid
344  * @param datas0 The buffer storing interpolated image patches from the first frame, matching with the given image points
345  * @param datas1 The buffer storing interpolated image patches form the second frame, matching with the given image points
346  * @param points0 The center positions of the image patches in the first frame
347  * @param points1 The center positions of the image patches in the second frame
348  * @param distribution0 The point distribution of the image points from the first frame
349  * @param distribution1 The point distribution of the image points from the second frame
350  * @param worker Optional worker object to distribute the computation
351  * @return A set if unique bijective point correspondences between the first and second frame
352  * @tparam tChannels The number of image channels, with range [1, infinity)
353  * @tparam tSize The size of the image patches (tSize x tSize), with range [1, infinity) must be odd
354  * @see findBijectiveCorrespondences().
355  */
356  template <unsigned int tChannels, unsigned int tSize>
357  static IndexPairs32 findBijectiveCorrespondences8BitPerChannel(const PinholeCamera& camera0, const PinholeCamera& camera1, const SquareMatrix3& orientation0, const SquareMatrix3& orientation1, const uint8_t* datas0, const uint8_t* datas1, const Vectors2& points0, const Vectors2& points1, const Geometry::SpatialDistribution::DistributionArray& distribution0, const Geometry::SpatialDistribution::DistributionArray& distribution1, Worker* worker);
358 
359  /**
360  * Finds bidirectional point correspondences between two given camera frames with eight bit per channel from a set of already detected unique feature points.
361  * @param camera0 The camera profile of the first frame, must be valid
362  * @param camera1 The camera profile of the second frame, must be valid
363  * @param orientation0 The orientation of the first frame, must be valid
364  * @param orientation1 The orientation of the second frame, must be valid
365  * @param datas0 The buffer storing interpolated image patches from the first frame, matching with the given image points
366  * @param datas1 The buffer storing interpolated image patches form the second frame, matching with the given image points
367  * @param points0 The center positions of the image patches in the first frame
368  * @param points1 The center positions of the image patches in the second frame
369  * @param distribution0 The point distribution of the image points from the first frame
370  * @param distribution1 The point distribution of the image points from the second frame
371  * @param worker Optional worker object to distribute the computation
372  * @return A set if unique bijective point correspondences between the first and second frame
373  * @tparam tChannels The number of image channels, with range [1, infinity)
374  * @tparam tSize The size of the image patches (tSize x tSize), with range [1, infinity) must be odd
375  * @see findBidirectionalCorrespondences8BitPerChannelSubset().
376  */
377  template <unsigned int tChannels, unsigned int tSize>
378  static IndexPairs32 findBidirectionalCorrespondences8BitPerChannel(const PinholeCamera& camera0, const PinholeCamera& camera1, const SquareMatrix3& orientation0, const SquareMatrix3& orientation1, const uint8_t* datas0, const uint8_t* datas1, const Vectors2& points0, const Vectors2& points1, const Geometry::SpatialDistribution::DistributionArray& distribution0, const Geometry::SpatialDistribution::DistributionArray& distribution1, Worker* worker);
379 
380  /**
381  * Finds subsets of bidirectional point correspondences between two given camera frames with eight bit per channel from a set of already detected unique feature points.
382  * @param camera0 The camera profile of the first frame, must be valid
383  * @param camera1 The camera profile of the second frame, must be valid
384  * @param orientation0 The orientation of the first frame, must be valid
385  * @param orientation1 The orientation of the second frame, must be valid
386  * @param datas0 The buffer storing interpolated image patches from the first frame, matching with the given image points
387  * @param datas1 The buffer storing interpolated image patches form the second frame, matching with the given image points
388  * @param points0 The center positions of the image patches in the first frame
389  * @param points1 The center positions of the image patches in the second frame
390  * @param distribution0 The point distribution of the image points from the first frame
391  * @param distribution1 The point distribution of the image points from the second frame
392  * @param lock Optional lock for multi-thread execution
393  * @param results The resulting unique bijective point correspondences between the first and second frame
394  * @param firstPoint The first point to be handled
395  * @param numberPoints The number of points to be handled
396  * @tparam tChannels The number of image channels, with range [1, infinity)
397  * @tparam tSize The size of the image patches (tSize x tSize), with range [1, infinity) must be odd
398  * @see findBidirectionalCorrespondences8BitPerChannel().
399  */
400  template <unsigned int tChannels, unsigned int tSize>
401  static void findBidirectionalCorrespondences8BitPerChannelSubset(const PinholeCamera* camera0, const PinholeCamera* camera1, const SquareMatrix3* orientation0, const SquareMatrix3* orientation1, const uint8_t* datas0, const uint8_t* datas1, const Vectors2* points0, const Vectors2* points1, const Geometry::SpatialDistribution::DistributionArray* distribution0, const Geometry::SpatialDistribution::DistributionArray* distribution1, Lock* lock, IndexPairs32* results, const unsigned int firstPoint, const unsigned int numberPoints);
402 
403  /**
404  * Finds a corresponding patch for a given patch from a second set of patches.
405  * @param data0 The image patch for which a second best matching patch has to be found
406  * @param datas1 The set of image patches from which the best matching patch has to be found
407  * @param indices The indices of possible patch candidates from the set of image patches
408  * @return The index of the image patch best matching to the given patch
409  * @tparam tChannels The number of image channels, with range [1, infinity)
410  * @tparam tSize The size of the image patches (tSize x tSize), with range [1, infinity) must be odd
411  */
412  template <unsigned int tChannels, unsigned int tSize>
413  static unsigned int findCorrespondingPoint8BitPerChannel(const uint8_t* data0, const uint8_t* datas1, const Indices32& indices);
414 
415  /**
416  * Determines a set of corresponding image points representing the same unique feature point (only observed in individual camera frames).
417  * @param correspondences All possible correspondences from which the set will be extracted
418  * @param minSiblings The minimal number of image points which are necessary to define one unique feature point (the minimal number of frames in which the feature point has been observed), 0u if any number is welcome
419  * @return The set of unique feature points
420  */
421  static std::vector<Indices64> determineFeaturePointsFromPointCloud(const FeaturePointMap& correspondences, const unsigned int minSiblings = 0u);
422 
423  /**
424  * Determines all sibling image point correspondences for a given correspondence.
425  * @param correspondences The set of all correspondences
426  * @param iStart The current correspondence for which all sibling correspondences are determined
427  * @param siblings The resulting unique ids of all sibling correspondences which have been found
428  * @param usedSet A set of unique correspondences which have been used/marked already
429  * @param frameSet A map of frame indices counting the number of image points for each frame to valid that a frame holds more than one image point
430  * @return The iterator of the next correspondence to be investigated
431  */
432  static FeaturePointMap::const_iterator determineSiblings(const FeaturePointMap& correspondences, const FeaturePointMap::const_iterator& iStart, UnorderedIndexSet64& siblings, UnorderedIndexSet64& usedSet, IndexMap& frameSet);
433 
434  /**
435  * Creates a unique ids for a given frame index and points index located in the frame.
436  * @param frameIndex The index of the frame
437  * @param pointIndex The index of the point ion the frame
438  * @return Resulting unique feature point id
439  */
440  static inline uint64_t uniqueFeaturePointId(const uint32_t frameIndex, const uint32_t pointIndex);
441 
442  /**
443  * Extracts the frame index of a unique feature point id.
444  * @param id The unique feature point id
445  * @return The frame index of the id
446  */
447  static inline uint32_t frameIndex(const uint64_t id);
448 
449  /**
450  * Extracts the point index of a unique feature point id.
451  * @param id The unique feature point id
452  * @return The point index of the id
453  */
454  static inline uint32_t pointIndex(const uint64_t id);
455 
456  protected:
457 
458  /// The initial orientation of the first camera frame.
459  SquareMatrix3 initialOrientation_ = SquareMatrix3(true);
460 
461  /// The orientation of the camera of the most recent frame.
462  SquareMatrix3 previousOrientation_ = SquareMatrix3(false);
463 
464  /// The camera profile of the most recent frame.
466 
467  /// The frame pyramid of the most recent frame.
469 };
470 
471 inline SphericalEnvironment::SphericalEnvironment(const unsigned int dimensionWidth, const unsigned int dimensionHeight, const uint8_t maskValue, const UpdateMode updateMode) :
472  CV::Advanced::PanoramaFrame(dimensionWidth, dimensionHeight, maskValue, updateMode),
473  initialOrientation_(true),
474  previousOrientation_(false)
475 {
476  // nothing to do here
477 }
478 
479 inline uint64_t SphericalEnvironment::uniqueFeaturePointId(const uint32_t frameIndex, const uint32_t pointIndex)
480 {
481  return uint64_t(frameIndex) << 32ull | uint64_t(pointIndex);
482 }
483 
484 inline uint32_t SphericalEnvironment::frameIndex(const uint64_t id)
485 {
486  return uint32_t(id >> 32ull);
487 }
488 
489 inline uint32_t SphericalEnvironment::pointIndex(const uint64_t id)
490 {
491  return uint32_t(id & 0xFFFFFFFFull);
492 }
493 
494 }
495 
496 }
497 
498 #endif // META_OCEAN_TRACKING_SPHERICAL_ENVIRONMENT_H
This class implements a panorama frame with spherical projection model.
Definition: PanoramaFrame.h:47
UpdateMode
Definition of individual frame update modes.
Definition: PanoramaFrame.h:54
This class implements a frame pyramid.
Definition: FramePyramid.h:37
DownsamplingMode
Definition of individual down sampling modes.
Definition: FramePyramid.h:44
@ DM_FILTER_14641
Down sampling is realized by a 5x5 Gaussian filter.
Definition: FramePyramid.h:72
This class implements a container for callback functions.
Definition: Callback.h:3456
This class implements Ocean's image class.
Definition: Frame.h:1760
PixelFormat
Definition of all pixel formats available in the Ocean framework.
Definition: Frame.h:183
EstimatorType
Definition of individual robust estimator types.
Definition: Estimator.h:34
@ ET_SQUARE
The standard square error estimator (L2).
Definition: Estimator.h:52
@ ET_INVALID
An invalid estimator type.
Definition: Estimator.h:38
This class implements a distribution array.
Definition: SpatialDistribution.h:228
This class implements a recursive lock object.
Definition: Lock.h:31
This class implements a 2D lookup object with values at the bins' corners defining the individual loo...
Definition: Lookup2.h:636
static constexpr T deg2rad(const T deg)
Converts deg to rad.
Definition: Numeric.h:3232
This class implements a spherical environment based on a panorama frame.
Definition: SphericalEnvironment.h:36
static FeaturePointMap::const_iterator determineSiblings(const FeaturePointMap &correspondences, const FeaturePointMap::const_iterator &iStart, UnorderedIndexSet64 &siblings, UnorderedIndexSet64 &usedSet, IndexMap &frameSet)
Determines all sibling image point correspondences for a given correspondence.
std::vector< IndexPairs32 > PoseImagePointPairGroups
Definition of a vector holding groups of pairs between camera pose ids and image point ids.
Definition: SphericalEnvironment.h:99
virtual void clear()
Clears the panorama frame and allows to set a new first camera frame.
std::vector< uint8_t > Buffer
Definition of a vector holding 8 bit characters.
Definition: SphericalEnvironment.h:42
static bool optimizeCamera(const PinholeCamera &pinholeCamera, const Frames &frames, const SquareMatrices3 &orientations, PinholeCamera &optimizedCamera, Worker *worker=nullptr)
Optimizes the camera profile for a given set of camera frames with known orientations so that the off...
SphericalEnvironment()=default
Creates an invalid spherical environment object.
static bool determinePointCorrespondencesHomography(const CV::FramePyramid &sourceFramePyramid, const Frame &targetFrame, const SquareMatrix3 &homography, const Vectors2 &sourcePointCandidates, Vectors2 &validSourcePoints, Vectors2 &validTargetPoints, Indices32 &validSourcePointIndices, const unsigned int patchSize, const unsigned int maximalDistance=32u, const unsigned int coarsestLayerRadius=8u, const CV::FramePyramid::DownsamplingMode downsamplingMode=CV::FramePyramid::DM_FILTER_14641, Worker *worker=nullptr, size_t *usedPointCandidates=nullptr)
Determines point correspondences between two camera frames captured with individual locations (descri...
static void interpolateSquarePatches8BitPerChannelSubset(const uint8_t *frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const Vector2 *positions, uint8_t *result, const unsigned int firstPosition, const unsigned int numberPositions)
Interpolates a subset of square image patches with sub-pixel position and stores the image content as...
std::multimap< uint64_t, uint64_t > FeaturePointMap
Definition of a map mapping unique frame-feature-point-ids to unique frame-feature-point-ids.
Definition: SphericalEnvironment.h:57
Callback< bool, const CV::FramePyramid &, const CV::FramePyramid &, const PinholeCamera &, const PinholeCamera &, const SquareMatrix3 &, const SquareMatrix3 &, const uint8_t, Frame &, Worker * > FrameCallback
Definition of a callback function allowing to determine an update mask for a current camera frame.
Definition: SphericalEnvironment.h:77
CV::FramePyramid previousFramePyramid_
The frame pyramid of the most recent frame.
Definition: SphericalEnvironment.h:468
static IndexPairs32 findBidirectionalCorrespondences8BitPerChannel(const PinholeCamera &camera0, const PinholeCamera &camera1, const SquareMatrix3 &orientation0, const SquareMatrix3 &orientation1, const uint8_t *datas0, const uint8_t *datas1, const Vectors2 &points0, const Vectors2 &points1, const Geometry::SpatialDistribution::DistributionArray &distribution0, const Geometry::SpatialDistribution::DistributionArray &distribution1, Worker *worker)
Finds bidirectional point correspondences between two given camera frames with eight bit per channel ...
std::unordered_map< uint32_t, uint32_t > IndexMap
Definition of a map mapping indices.
Definition: SphericalEnvironment.h:52
static bool findInitialFieldOfView(const unsigned int width, const unsigned int height, const SquareMatrices3 &orientations, const ImagePoints &imagePoints, const PoseImagePointPairGroups &orientationImagePointPairGroups, PinholeCamera &optimizedCamera, SquareMatrices3 &optimizedOrientations, const Scalar lowerFovX=Numeric::deg2rad(40), const Scalar upperFovX=Numeric::deg2rad(90), const unsigned int steps=10u)
Determines the initial field of view for a set of camera frames with known orientation and a correspo...
static Buffer interpolateSquarePatches(const Frame &frame, const Vectors2 &positions, Worker *worker=nullptr)
Interpolates square image patches with sub-pixel position and stores the image content as patch buffe...
static void findBidirectionalCorrespondences8BitPerChannelSubset(const PinholeCamera *camera0, const PinholeCamera *camera1, const SquareMatrix3 *orientation0, const SquareMatrix3 *orientation1, const uint8_t *datas0, const uint8_t *datas1, const Vectors2 *points0, const Vectors2 *points1, const Geometry::SpatialDistribution::DistributionArray *distribution0, const Geometry::SpatialDistribution::DistributionArray *distribution1, Lock *lock, IndexPairs32 *results, const unsigned int firstPoint, const unsigned int numberPoints)
Finds subsets of bidirectional point correspondences between two given camera frames with eight bit p...
bool optimizeOrientation(const PinholeCamera &pinholeCamera, const SquareMatrix3 &orientation, const Frame &frame, const Frame &mask, const Geometry::Estimator::EstimatorType estimator, SquareMatrix3 &optimizedOrientation, PinholeCamera *optimizedCamera=nullptr, LookupTable *fineAdjustment=nullptr, const unsigned int approximationBinSize=20u, Worker *worker=nullptr)
Determines the precise orientation of a given camera frame.
static bool determinePointCorrespondencesHomography(const Frame &sourceFrame, const Frame &targetFrame, const SquareMatrix3 &homography, Vectors2 &sourcePoints, Vectors2 &targetPoints, const unsigned int patchSize, const unsigned int maximalDistance=32u, const unsigned int coarsestLayerRadius=8u, const CV::FramePyramid::DownsamplingMode downsamplingMode=CV::FramePyramid::DM_FILTER_14641, Worker *worker=nullptr)
Determines point correspondences between two camera frames captured with individual locations (descri...
static bool optimizeCamera(const PinholeCamera &pinholeCamera, const SquareMatrices3 &orientations, const ImagePoints &imagePoints, const PoseImagePointPairGroups &orientationImagePointPairGroups, PinholeCamera &optimizedCamera, SquareMatrices3 &optimizedOrientations, const unsigned int iterations=20u, const Geometry::Estimator::EstimatorType estimator=Geometry::Estimator::ET_SQUARE, Scalar lambda=Scalar(0.001), const Scalar lambdaFactor=Scalar(5), Scalar *initialError=nullptr, Scalar *finalError=nullptr, Scalars *intermediateErrors=nullptr)
Optimizes the camera profile for a given set of image points from individual camera frames so that th...
static unsigned int findCorrespondingPoint8BitPerChannel(const uint8_t *data0, const uint8_t *datas1, const Indices32 &indices)
Finds a corresponding patch for a given patch from a second set of patches.
bool extendEnvironment(const PinholeCamera &pinholeCamera, const Frame &frame, const unsigned int approximationBinSize=20u, const Geometry::Estimator::EstimatorType fineAdjustmentEstimator=Geometry::Estimator::ET_INVALID, const bool optimizeCamera=false, Worker *worker=nullptr, SquareMatrix3 *orientation=nullptr, PinholeCamera *optimizedCamera=nullptr, const FrameCallback &frameCallback=FrameCallback())
Adds a new camera frame to the panorama frame for which the orientation is unknown.
static IndexPairs32 findBijectiveCorrespondences8BitPerChannel(const PinholeCamera &camera0, const PinholeCamera &camera1, const SquareMatrix3 &orientation0, const SquareMatrix3 &orientation1, const uint8_t *datas0, const uint8_t *datas1, const Vectors2 &points0, const Vectors2 &points1, const Geometry::SpatialDistribution::DistributionArray &distribution0, const Geometry::SpatialDistribution::DistributionArray &distribution1, Worker *worker)
Finds unique bijective point correspondences between two given camera frames with eight bit per chann...
static void interpolateSquarePatches8BitPerChannel(const uint8_t *frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const Vectors2 &positions, uint8_t *result, Worker *worker=nullptr)
Interpolates square image patches with sub-pixel position and stores the image content as patch buffe...
std::vector< Buffer > Buffers
Definition of a vector holding buffers.
Definition: SphericalEnvironment.h:47
static bool nonHomographyMask(const CV::FramePyramid &previousFramePyramid, const CV::FramePyramid &currentFramePyramid, const PinholeCamera &previousCamera, const PinholeCamera &currentCamera, const SquareMatrix3 &previousOrientation, const SquareMatrix3 &currentOrientation, const uint8_t maskValue, Frame &currentMask, Worker *worker=nullptr)
This function determines a mask for image areas not matching with the common homography between two s...
static uint64_t uniqueFeaturePointId(const uint32_t frameIndex, const uint32_t pointIndex)
Creates a unique ids for a given frame index and points index located in the frame.
Definition: SphericalEnvironment.h:479
static IndexPairs32 findBijectiveCorrespondences(const PinholeCamera &camera0, const PinholeCamera &camera1, const FrameType::PixelFormat pixelFormat, const SquareMatrix3 &orientation0, const SquareMatrix3 &orientation1, const Buffer &buffer0, const Buffer &buffer1, const Vectors2 &points0, const Vectors2 &points1, const Geometry::SpatialDistribution::DistributionArray &distribution0, const Geometry::SpatialDistribution::DistributionArray &distribution1, Worker *worker)
Finds unique bijective point correspondences between two given camera frames from a set of already de...
static uint32_t frameIndex(const uint64_t id)
Extracts the frame index of a unique feature point id.
Definition: SphericalEnvironment.h:484
static bool determineTransformationTable2x2(const unsigned int width, const unsigned int height, const Vectors2 &points0, const Vectors2 &points1, LookupCorner2< Vector2 > &transformation0to1, const unsigned int iterations=20u, const Geometry::Estimator::EstimatorType estimator=Geometry::Estimator::ET_SQUARE, Scalar lambda=Scalar(0.001), const Scalar lambdaFactor=Scalar(5), Scalar *initialError=nullptr, Scalar *finalError=nullptr)
Determines a 2x2 transformation table (a lookup table) transforming a set of points (defined in the d...
static uint32_t pointIndex(const uint64_t id)
Extracts the point index of a unique feature point id.
Definition: SphericalEnvironment.h:489
PinholeCamera previousCamera_
The camera profile of the most recent frame.
Definition: SphericalEnvironment.h:465
static std::vector< Indices64 > determineFeaturePointsFromPointCloud(const FeaturePointMap &correspondences, const unsigned int minSiblings=0u)
Determines a set of corresponding image points representing the same unique feature point (only obser...
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
std::vector< IndexPair32 > IndexPairs32
Definition of a vector holding 32 bit index pairs.
Definition: Base.h:144
std::vector< Frame > Frames
Definition of a vector holding padding frames.
Definition: Frame.h:1723
std::vector< Index32 > Indices32
Definition of a vector holding 32 bit index values.
Definition: Base.h:96
std::unordered_set< Index64 > UnorderedIndexSet64
Definition of an unordered_set holding 64 bit indices.
Definition: Base.h:132
SquareMatrixT3< Scalar > SquareMatrix3
Definition of the SquareMatrix3 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with ...
Definition: SquareMatrix3.h:35
float Scalar
Definition of a scalar type.
Definition: Math.h:128
std::vector< Scalar > Scalars
Definition of a vector holding Scalar objects.
Definition: Math.h:144
std::vector< SquareMatrix3 > SquareMatrices3
Definition of a vector holding SquareMatrix3 objects.
Definition: SquareMatrix3.h:71
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition: Vector2.h:64
std::vector< ImagePoint > ImagePoints
Definition of a vector holding 2D image points.
Definition: Tracking.h:55
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15