Ocean
Loading...
Searching...
No Matches
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
23namespace Ocean
24{
25
26namespace 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 */
35class 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 */
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
471inline 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
479inline uint64_t SphericalEnvironment::uniqueFeaturePointId(const uint32_t frameIndex, const uint32_t pointIndex)
480{
481 return uint64_t(frameIndex) << 32ull | uint64_t(pointIndex);
482}
483
484inline uint32_t SphericalEnvironment::frameIndex(const uint64_t id)
485{
486 return uint32_t(id >> 32ull);
487}
488
489inline 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
This class implements a container for callback functions.
Definition Callback.h:3456
This class implements Ocean's image class.
Definition Frame.h:1808
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
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
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:94
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 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...
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
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:1771
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
float Scalar
Definition of a scalar type.
Definition Math.h:129
std::vector< Scalar > Scalars
Definition of a vector holding Scalar objects.
Definition Math.h:145
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