Ocean
tracking/Utilities.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_UTILITIES_H
9 #define META_OCEAN_TRACKING_UTILITIES_H
10 
12 
13 #include "ocean/base/Frame.h"
14 #include "ocean/base/Maintenance.h"
15 #include "ocean/base/Thread.h"
16 #include "ocean/base/Worker.h"
17 
19 #include "ocean/cv/Canvas.h"
20 
21 #include "ocean/io/Bitstream.h"
22 
23 #include "ocean/math/AnyCamera.h"
24 #include "ocean/math/Box3.h"
25 #include "ocean/math/Cone3.h"
26 #include "ocean/math/Cylinder3.h"
29 #include "ocean/math/Triangle3.h"
30 #include "ocean/math/Vector2.h"
31 #include "ocean/math/Vector3.h"
32 
34 
35 namespace Ocean
36 {
37 
38 namespace Tracking
39 {
40 
41 /**
42  * This class implements utility functions allowing e.g., for a more comfortable visualization of tracking data.
43  * @ingroup tracking
44  */
45 class OCEAN_TRACKING_EXPORT Utilities
46 {
47  public:
48 
49  /**
50  * Blends two given frames having the same frame type.
51  * The resulting frame holds pixel intensity values of fifty percent of each frame.
52  * @param frame0 The first frame that will be blended, must be valid
53  * @param frame1 The second frame that will be blended, with same frame type as the first frame, must be valid
54  * @param worker Optional worker object to distribute the computation
55  * @return The resulting blended frame
56  */
57  static Frame blendFrames(const Frame& frame0, const Frame& frame1, Worker* worker = nullptr);
58 
59  /**
60  * Blends two given frames with same pixel origin.
61  * In case the image resolution varies, both images will be aligned at the image center and missing image content is added at the border.
62  * The resulting frame holds pixel intensity values of fifty percent of each frame.<br>
63  * @param frame0 The first frame that will be blended, must be valid
64  * @param frame1 The second frame that will be blended, with same frame type as the first frame, must be valid
65  * @param offset0 The location of the top-left corner of the first frame within the blended frame, with range [0, 0]x(infinity, infinity)
66  * @param offset1 The location of the top-left corner of the second frame within the blended frame, with range [0, 0]x(infinity, infinity)
67  * @param pixelFormat The pixel format the resulting blended image will have, FORMAT_UNDEFINED to use the pixel format of the given images (which must be identical in that case)
68  * @param worker Optional worker object to distribute the computation
69  * @return The resulting blended frame
70  */
71  static Frame blendFrames(const Frame& frame0, const Frame& frame1, Vector2& offset0, Vector2& offset1, const FrameType::PixelFormat pixelFormat = FrameType::FORMAT_UNDEFINED, Worker* worker = nullptr);
72 
73  /**
74  * Paints a line into a given frame.
75  * @param frame The frame in which is drawn
76  * @param startPosition Start position of line
77  * @param stopPosition Stop position of line
78  * @param color The color that will be used to paint the points, ensure that one value is provided for each frame channel, otherwise black is used
79  * @param subPixel True, to paint the line with sub-pixel accuracy; False, to paint the line with pixel accuracy
80  */
81  static inline void paintLine(Frame& frame, const Vector2& startPosition, const Vector2& stopPosition, const uint8_t* color = nullptr, const bool subPixel = true);
82 
83  /**
84  * Paints a set of lines into a given frame.
85  * @param frame The frame in which is drawn
86  * @param startPositions Start positions of the lines
87  * @param stopPositions Stop positions of the lines, each end position must have a corresponding start position
88  * @param numberLines The number of lines, with range [0, infinity)
89  * @param color The color that will be used to paint the points, ensure that one value is provided for each frame channel, nullptr to apply black
90  * @param worker Optional worker object to distribute the computation
91  * @param subPixel True, to paint the lines with sub-pixel accuracy; False, to paint the lines with pixel accuracy
92  * @param offsetStartPositions The offset which will be added to each start position before painting the line, with range (-infinity, infinity)x(-infinity, infinity)
93  * @param offsetStopPositions The offset which will be added to each stop position before painting the line, with range (-infinity, infinity)x(-infinity, infinity)
94  */
95  static inline void paintLines(Frame& frame, const Vector2* startPositions, const Vector2* stopPositions, const size_t numberLines, const uint8_t* color = nullptr, Worker* worker = nullptr, const bool subPixel = true, const Vector2& offsetStartPositions = Vector2(0, 0), const Vector2& offsetStopPositions = Vector2(0, 0));
96 
97  /**
98  * Paints a set of lines into a given frame with sub-pixel accuracy.
99  * @param frame The frame in which is drawn, must be valid
100  * @param startPositions Start positions of the lines
101  * @param stopPositions Stop positions of the lines, each end position must have a corresponding start position
102  * @param numberLines The number of lines, with range [0, infinity)
103  * @param color The color that will be used to paint the points, ensure that one value is provided for each frame channel, nullptr to apply black
104  * @param worker Optional worker object to distribute the computation
105  * @tparam tSize The thickness of the lines in pixel, must be odd with range [1, infinity)
106  */
107  template <unsigned int tSize>
108  static inline void paintLines(Frame& frame, const Vector2* startPositions, const Vector2* stopPositions, const size_t numberLines, const uint8_t* color = nullptr, Worker* worker = nullptr);
109 
110  /**
111  * Paints a set of lines with (foreground and) background color into a given frame with sub-pixel accuracy.
112  * @param frame The frame in which is drawn, must be valid
113  * @param startPositions Start positions of the lines
114  * @param stopPositions Stop positions of the lines, each end position must have a corresponding start position
115  * @param numberLines The number of lines, with range [0, infinity)
116  * @param colorForeground Foreground color that will be used to paint the points, ensure that one value is provided for each frame channel, nullptr to use black
117  * @param colorBackground Background color that will be used to paint the points, ensure that one value is provided for each frame channel, nullptr to use black
118  * @param worker Optional worker object to distribute the computation
119  * @tparam tSizeForeground The thickness of the foreground lines in pixel, must be odd with range [1, infinity)
120  * @tparam tSizeBackground The thickness of the background lines in pixel, must be odd with range (tSizeForeground, infinity)
121  */
122  template <unsigned int tSizeForeground, unsigned int tSizeBackground>
123  static inline void paintLines(Frame& frame, const Vector2* startPositions, const Vector2* stopPositions, const size_t numberLines, const uint8_t* colorForeground = nullptr, const uint8_t* colorBackground = nullptr, Worker* worker = nullptr);
124 
125  /**
126  * Paints several paths into a given frame with sub-pixel accuracy.
127  * A path is a chain of connected image points with arbitrary length (start and end point are not connected).
128  * @param frame The frame in which the paths will be painted
129  * @param paths The individual paths to be painted
130  * @param size The number of given paths, with range [0, infinity)
131  * @param color The color that will be used to paint the points, ensure that one value is provided for each frame channel, nullptr to apply black
132  * @param worker Optional worker object to distribute the computation
133  * @tparam tSize The thickness of the paths in pixel, must be odd with range [1, infinity)
134  */
135  template <unsigned int tSize>
136  static inline void paintPaths(Frame& frame, const Vectors2* paths, const size_t size, const uint8_t* color = nullptr, Worker* worker = nullptr);
137 
138  /**
139  * Paints several paths into a given frame with sub-pixel accuracy.
140  * A path is a chain of connected image points with arbitrary length (start and end point are not connected).<br>
141  * The colors of the paths are determined by an interpolation between two separate color values.
142  * @param frame The frame in which the paths will be painted
143  * @param paths The individual paths to be painted
144  * @param size The number of given paths, with range [0, infinity)
145  * @param color0 The first color value, ensure that one value is provided for each frame channel
146  * @param color1 The second color value, ensure that one value is provided for each frame channel
147  * @param factors The interpolation factor, one factor for each path, with range [0, 1]
148  * @param worker Optional worker object to distribute the computation
149  * @tparam tSize The thickness of the paths in pixel, must be odd with range [1, infinity)
150  */
151  template <unsigned int tSize>
152  static inline void paintPaths(Frame& frame, const Vectors2* paths, const size_t size, const uint8_t* color0, const uint8_t* color1, const Scalar* factors, Worker* worker = nullptr);
153 
154  /**
155  * Paints a 2D triangle into a given frame with sub-pixel accuracy.
156  * @param frame The frame receiving the triangles
157  * @param triangle The triangle that will be painted, must be valid
158  * @param color The color that will be used to paint the triangle edges, ensure that one value is provided for each frame channel, otherwise black is used
159  * @tparam tSize The thickness of the triangle edges in pixels, must be odd with range [1, infinity)
160  */
161  template <unsigned int tSize = 1u>
162  static void paintTriangle(Frame& frame, const Triangle2& triangle, const uint8_t* color = nullptr);
163 
164  /**
165  * Paints a set of 2D triangles into a given frame with sub-pixel accuracy.
166  * @param frame The frame receiving the triangles
167  * @param triangles The triangles that will be painted
168  * @param color The color that will be used to paint the triangle edges, ensure that one value is provided for each frame channel, otherwise black is used
169  * @param worker Optional worker to distribute the computation
170  * @tparam tSize The thickness of the triangle edges in pixels, must be odd with range [1, infinity)
171  */
172  template <unsigned int tSize = 1u>
173  static void paintTriangles(Frame& frame, const Triangles2& triangles, const uint8_t* color = nullptr, Worker* worker = nullptr);
174 
175  /**
176  * Paints a set of 2D image points into a given frame with sub-pixel accuracy.
177  * @param frame The frame in which the image points will be painted
178  * @param imagePoints The image points which will be painted
179  * @param size The number of given 2D points, with range [0, infinity)
180  * @param color The color for the image points
181  * @param worker Optional worker object to distribute the computation
182  * @tparam tPointSize The radius of the image points, must be odd with range [1, infinity)
183  */
184  template <unsigned int tPointSize>
185  static inline void paintImagePoints(Frame& frame, const Vector2* imagePoints, const size_t size, const uint8_t* color, Worker* worker = nullptr);
186 
187  /**
188  * Paints a set of 3D object points (rather their projected 2D counterparts respectively) into a given frame with sub-pixel accuracy.
189  * @param frame The frame in which the projected object points will be painted
190  * @param anyCamera The camera profile defining the projection between 3D object points and camera plane
191  * @param world_T_camera The camera pose from which the 3D object points are observed with default viewing direction towards the negative z-space and y-axis as up vector, transforming camera to world, must be valid
192  * @param objectPoints The object points which will be projected into the camera frame, defined in world
193  * @param size The number of given 3D points, with range [0, infinity)
194  * @param color The color for the object points
195  * @param worker Optional worker object to distribute the computation
196  * @tparam tPointSize The radius of the object points, must be odd with range [1, infinity)
197  */
198  template <unsigned int tPointSize>
199  static inline void paintObjectPoints(Frame& frame, const AnyCamera& anyCamera, const HomogenousMatrix4& world_T_camera, const Vector3* objectPoints, const size_t size, const uint8_t* color, Worker* worker = nullptr);
200 
201  /**
202  * Paints a feature point having a radius (a scale) and orientation.
203  * @param frame The frame in which the projected object points will be painted, must be valid
204  * @param position The position of the feature point defined in the pixel domain of the given frame, with range (-infinity, infinity)x(-infinity, infinity)
205  * @param radius The radius (scale) of the feature point in pixel, with range (0, infinity)
206  * @param orientation The orientation of the feature point as CCW angle in radian, with range [0, 2PI)
207  * @param color The color for the feature point, one value for each frame data channel
208  * @param shadowColor The outer color for the object points, one value for each frame data channel or nullptr to skip painting the shadow
209  */
210  static void paintFeaturePoint(Frame& frame, const Vector2& position, const Scalar radius, const Scalar orientation, const uint8_t* color, const uint8_t* shadowColor);
211 
212  /**
213  * Paints a feature point having a radius (a scale) and orientation.
214  * @param frame The frame in which the feature points will be painted, must be valid
215  * @param width The width of the frame in pixel, with range (0, infinity)
216  * @param height The height of the frame in pixel, with range (0, infinity)
217  * @param position The position of the feature point defined in the pixel domain of the given frame, with range (-infinity, infinity)x(-infinity, infinity)
218  * @param radius The radius (scale) of the feature point in pixel, with range (0, infinity)
219  * @param orientation The orientation of the feature point as CCW angle in radian, with range [0, 2PI)
220  * @param color The color for the feature point, one value for each frame data channel
221  * @param shadowColor The outer color for the object points, one value for each frame data channel or nullptr to skip painting the shadow
222  * @param framePaddingElements The number of padding elements at the end of each frame row, in elements, with range [0, infinity)
223  * @tparam tChannels The number of data channels, with range [1, infinity)
224  */
225  template <unsigned int tChannels>
226  static void paintFeaturePoint8BitPerChannel(uint8_t* frame, const unsigned int width, const unsigned int height, const Vector2& position, const Scalar radius, const Scalar orientation, const uint8_t* color, const uint8_t* shadowColor, const unsigned int framePaddingElements = 0u);
227 
228  /**
229  * Paints feature points having a radius (a scale) and orientation.
230  * @param frame The frame in which the projected object points will be painted, must be valid
231  * @param positions The positions of the feature points defined in the pixel domain of the given frame, with range (-infinity, infinity)x(-infinity, infinity), can be nullptr if size is 0
232  * @param radii The radii (scale) of the feature points in pixel, with range (0, infinity), one for each position, can be nullptr if size is 0
233  * @param orientations The orientations of the feature points as CCW angle in radian, with range [0, 2PI), one for each position, can be nullptr if size is 0
234  * @param size The number of feature points to be painted, with range [0, infinity)
235  * @param color The color for the feature point, one value for each frame data channel
236  * @param shadowColor The outer color for the object points, one value for each frame data channel or nullptr to skip painting the shadow
237  * @param explicitOffset Optional explicit offset which will be added to every feature point location before the point is painted, with range (-infinity, infinity)x(-infinity, infinity)
238  * @param worker Optional worker object to distribute the computation
239  */
240  static void paintFeaturePoints(Frame& frame, const Vector2* positions, const Scalar* radii, const Scalar* orientations, const size_t size, const uint8_t* color, const uint8_t* shadowColor, const Vector2& explicitOffset = Vector2(0, 0), Worker* worker = nullptr);
241 
242  /**
243  * Paints feature points having a radius (a scale) and orientation.
244  * @param frame The frame in which the feature points will be painted, must be valid
245  * @param width The width of the frame in pixel, with range (0, infinity)
246  * @param height The height of the frame in pixel, with range (0, infinity)
247  * @param positions The positions of the feature points defined in the pixel domain of the given frame, with range (-infinity, infinity)x(-infinity, infinity), can be nullptr if size is 0
248  * @param radii The radii (scale) of the feature points in pixel, with range (0, infinity), one for each position, can be nullptr if size is 0
249  * @param orientations The orientations of the feature points as CCW angle in radian, with range [0, 2PI), one for each position, can be nullptr if size is 0
250  * @param size The number of feature points to be painted, with range [0, infinity)
251  * @param color The color for the feature point, one value for each frame data channel
252  * @param shadowColor The outer color for the object points, one value for each frame data channel or nullptr to skip painting the shadow
253  * @param explicitOffset Optional explicit offset which will be added to every feature point location before the point is painted, with range (-infinity, infinity)x(-infinity, infinity)
254  * @param framePaddingElements The number of padding elements at the end of each frame row, in elements, with range [0, infinity)
255  * @param worker Optional worker object to distribute the computation
256  * @tparam tChannels The number of data channels, with range [1, infinity)
257  */
258  template <unsigned int tChannels>
259  static inline void paintFeaturePoints8BitPerChannel(uint8_t* frame, const unsigned int width, const unsigned int height, const Vector2* positions, const Scalar* radii, const Scalar* orientations, const size_t size, const uint8_t* color, const uint8_t* shadowColor, const Vector2& explicitOffset, const unsigned int framePaddingElements, Worker* worker = nullptr);
260 
261  /**
262  * Paints a set of correspondences between 2D image points and 3D object points (rather their projected 2D counterparts respectively) into a given frame with sub-pixel accuracy.
263  * The projected object points will be painted first, followed by their corresponding image points.<br>
264  * Further, a connection between the projected object points and the corresponding image points can be painted, which can be helpful if the given pose is not accurate.
265  * @param frame The frame in which the projected object points and image points will be painted
266  * @param camera The camera profile defining the projection between 3D object points and camera plane
267  * @param model_T_camera The camera pose transforming the camera coordinate system to the coordinate system of the object points (with viewing direction along the negative z-axis and y-axis as up vector), must be valid
268  * @param objectPoints The object points which will be projected into the camera frame
269  * @param imagePoints The image points corresponding to the given object points, the smaller the distance between image points and projected object points the more accurate the camera pose
270  * @param correspondences The number of given 2D/3D point correspondences, with range [0, infinity)
271  * @param maxSqrError The maximal square pixel error between a projected object point and the corresponding image point to count as valid, with range [0, infinity)
272  * @param colorValidObjectPoints The color for valid object points
273  * @param colorValidImagePoints The color for valid object points
274  * @param colorInvalidObjectPoints The color for invalid object points
275  * @param colorInvalidImagePoints The color for invalid image points
276  * @param drawObjectPoints True, to draw the object points
277  * @param drawImagePoints True, to draw the image points
278  * @param drawConnections True, to draw the connections between projected object points and the corresponding image points
279  * @param worker Optional worker object to distribute the computation
280  * @tparam tObjectPointSize The radius of the object points, must be odd with range [tImagePointSize, infinity)
281  * @tparam tImagePointSize The radius of the image points, must be odd, with range [1, infinity)
282  */
283  template <unsigned int tObjectPointSize, unsigned int tImagePointSize>
284  static inline void paintCorrespondences(Frame& frame, const AnyCamera& camera, const HomogenousMatrix4& model_T_camera, const Vector3* objectPoints, const Vector2* imagePoints, const size_t correspondences, const Scalar maxSqrError, const uint8_t* colorValidObjectPoints, const uint8_t* colorValidImagePoints, const uint8_t* colorInvalidObjectPoints, const uint8_t* colorInvalidImagePoints, const bool drawObjectPoints = true, const bool drawImagePoints = true, const bool drawConnections = true, Worker* worker = nullptr);
285 
286  /**
287  * Blends two corresponding frames each with a ratio of fifty percent and paints a set of given feature correspondences.
288  * Both frames must have the same pixel origin, while internally both images will be converted to FORMAT_RGB24 images.
289  * @param frame0 The first frame, must be valid
290  * @param frame1 The second frame, with same frame type as the first frame
291  * @param points0 The positions of the feature correspondences in the first frame
292  * @param points1 The positions of the feature correspondences in the second frame, each point as a corresponding point in the first frame
293  * @param numberPoints The number of given feature correspondences, with range [0, infinity)
294  * @param rgbColor The color that will be used to paint the points, ensure that three values are provided (with order: R, G, B), otherwise nullptr to use black
295  * @param worker Optional worker object to distribute the computation
296  * @return Returns the resulting blend frame showing the feature correspondences, with pixel format FORMAT_RGB24
297  */
298  static Frame paintCorrespondencesBlend(const Frame& frame0, const Frame& frame1, const Vector2* points0, const Vector2* points1, const size_t numberPoints, const uint8_t* rgbColor = nullptr, Worker* worker = nullptr);
299 
300  /**
301  * Joins two corresponding frames horizontally and paints a set of given feature correspondences.
302  * Both frame can have individual frame dimensions (as long as the pixel origin is identical).<br>
303  * Internally both images will be converted to FORMAT_RGB24 images.
304  * @param frame0 The first frame, must be valid
305  * @param frame1 The second frame, with same pixel origin as the first frame, must be valid
306  * @param points0 The positions of the feature correspondences in the first frame
307  * @param points1 The positions of the feature correspondences in the second frame, each point as a corresponding point in the first frame
308  * @param numberPoints The number of given feature correspondences, with range [0, infinity)
309  * @param color The color that will be used to paint the points, ensure that three values are provided (with order R, G, B), otherwise nullptr to use black
310  * @param worker Optional worker object to distribute the computation
311  * @return Returns the resulting joined frame showing the feature correspondences, with pixel format FORMAT_RGB24
312  */
313  static Frame paintCorrespondencesHorizontal(const Frame& frame0, const Frame& frame1, const Vector2* points0, const Vector2* points1, const size_t numberPoints, const uint8_t* color = nullptr, Worker* worker = nullptr);
314 
315  /**
316  * Joins two corresponding frames vertically and paints a set of given feature correspondences.
317  * Both frame can have individual frame dimensions, while internally both images will be converted to FORMAT_RGB24 images.
318  * @param frame0 The first frame, must be valid
319  * @param frame1 The second frame, with pixel origin as the first frame, must be valid
320  * @param points0 The positions of the feature correspondences in the first frame
321  * @param points1 The positions of the feature correspondences in the second frame, each point as a corresponding point in the first frame
322  * @param numberPoints The number of given feature correspondences, with range [0, infinity)
323  * @param color The color that will be used to paint the points, ensure that three values are provided (with order: R, G, B), otherwise nullptr to use black
324  * @param worker Optional worker object to distribute the computation
325  * @return Returns the resulting joined frame showing the feature correspondences, with pixel format FORMAT_RGB24
326  */
327  static Frame paintCorrespondencesVertical(const Frame& frame0, const Frame& frame1, const Vector2* points0, const Vector2* points1, const size_t numberPoints, const uint8_t* color = nullptr, Worker* worker = nullptr);
328 
329  /**
330  * Joins two corresponding frames by application of a homography and paints a set of given feature correspondences.
331  * The second frame will be aligned so that it matches with the first frame (by application of the homography).<br>
332  * Both frame can have individual frame dimensions.
333  * @param frame0 The first frame, must be valid
334  * @param frame1 The second frame, with pixel origin as the first frame, must be valid
335  * @param points1_H_points0 The homography transforming points defined in the first frame to points defined in the second frame, must be valid
336  * @param points0 The positions of the feature correspondences in the first frame, with range [0, frame0.width())x[0, frame0.height())
337  * @param points1 The positions of the feature correspondences in the second frame, each point as a corresponding point in the first frame, with range [0, frame1.width())x[0, frame1.height())
338  * @param numberPoints The number of given feature correspondences, with range [0, infinity)
339  * @param fullCoverage True, to create a frame fully covering both frames; False, to create a frame covering the first frame only
340  * @param result Returns the resulting joined frame showing the feature correspondences
341  * @param foregroundColor The foreground color that will be used to paint the lines, ensure that one value is provided for each frame channel, nullptr to use black
342  * @param backgroundColor Optional background color that will used for each line, nullptr to avoid the usage of a background color
343  * @param startColor Optional color of the start points of each line, nullptr to avoid the usage of a color for the start point
344  * @param worker Optional worker object to distribute the computation
345  * @return True, if succeeded
346  */
347  static bool paintCorrespondencesHomography(const Frame& frame0, const Frame& frame1, const SquareMatrix3& points1_H_points0, const Vector2* points0, const Vector2* points1, const size_t numberPoints, const bool fullCoverage, Frame& result, const uint8_t* foregroundColor = nullptr, const uint8_t* backgroundColor = nullptr, const uint8_t* startColor = nullptr, Worker* worker = nullptr);
348 
349  /**
350  * Joins two corresponding frames by application of their orientations and paints a set of given feature correspondences.
351  * @param pinholeCamera The pinhole camera profile defining the project, must be valid
352  * @param frame0 The first frame with frame dimension as the camera dimension, must be valid
353  * @param frame1 The second frame, with frame type as the first frame, must be valid
354  * @param orientation0 The orientation of the first frame, must be valid
355  * @param orientation1 The orientation of the second frame, must be valid
356  * @param points0 The positions of the feature correspondences in the first frame, with range [0, frame0.width())x[0, frame0.height())
357  * @param points1 The positions of the feature correspondences in the second frame, each point as a corresponding point in the first frame, with range [0, frame1.width())x[0, frame1.height())
358  * @param numberPoints The number of given feature correspondences, with range [0, infinity)
359  * @param result Returns the resulting joined frame showing the feature correspondences
360  * @param foregroundColor The foreground color that will be used to paint the lines, ensure that one value is provided for each frame channel, nullptr to use black
361  * @param backgroundColor Optional background color that will used for each line, nullptr to avoid the usage of a background color
362  * @param startColor Optional color of the start points of each line, nullptr to avoid the usage of a color for the start point
363  * @param worker Optional worker object to distribute the computation
364  * @return True, if succeeded
365  */
366  static bool paintCorrespondencesOrientations(const PinholeCamera& pinholeCamera, const Frame& frame0, const Frame& frame1, const SquareMatrix3& orientation0, const SquareMatrix3& orientation1, const Vector2* points0, const Vector2* points1, const size_t numberPoints, Frame& result, const uint8_t* foregroundColor = nullptr, const uint8_t* backgroundColor = nullptr, const uint8_t* startColor = nullptr, Worker* worker = nullptr);
367 
368  /**
369  * Paints a set of image points into a given frame.
370  * @param frame The frame receiving the points
371  * @param imagePoints Image points that will be painted
372  * @param number The number of provided image points, with range [0, infinity)
373  * @param radius The radius of the paintings in pixel, with range [0, infinity)
374  * @param colorInner Inner color that will be used, ensure that one value is provided for each frame channel, otherwise white is used
375  * @param colorOuter Outer color that will be used, ensure that one value is provided for each frame channel, otherwise black is used
376  */
377  static void paintPoints(Frame& frame, const Vector2* imagePoints, const size_t number, const unsigned int radius, const uint8_t* colorInner = nullptr, const uint8_t* colorOuter = nullptr);
378 
379  /**
380  * Paints (projected) object points and image points into a given frame.
381  * @param frame The frame receiving the points
382  * @param world_T_camera The transformations between camera and the world, must be valid
383  * @param pinholeCamera The pinhole camera profile defining the projection, with dimension equal to the frame dimension
384  * @param objectPoints The object points that will be painted, defined in world
385  * @param numberObjectPoints Number of provided object points, with range [0, infinity)
386  * @param imagePoints Image points that will be painted
387  * @param numberImagePoints Number of provided image points, with range [0, infinity)
388  * @param distortProjectedObjectPoints True, to apply the distortion parameters of the camera to the projected object points
389  * @param radiusObjectPoints Radius of the object point paintings in pixel
390  * @param radiusImagePoints Radius of the image point paintings in pixel
391  * @param colorObjectPoints Color that will be used to paint the object points, ensure that one value is provided for each frame channel, otherwise white is used
392  * @param colorImagePoints Color that will be used to paint the image points, ensure that one value is provided for each frame channel, otherwise white is used
393  */
394  static inline void paintPoints(Frame& frame, const HomogenousMatrix4& world_T_camera, const PinholeCamera& pinholeCamera, const Vector3* objectPoints, const size_t numberObjectPoints, const Vector2* imagePoints, const size_t numberImagePoints, const bool distortProjectedObjectPoints, const unsigned int radiusObjectPoints, const unsigned int radiusImagePoints, const uint8_t* colorObjectPoints = nullptr, const uint8_t* colorImagePoints = nullptr);
395 
396  /**
397  * Paints (projected) object points and image points into a given frame.
398  * @param frame The frame receiving the points, must be valid
399  * @param flippedCamera_T_world The transformation between the world and the flipped camera, must be valid
400  * @param pinholeCamera The pinhole camera profile defining the projection, with dimension equal to the frame dimension
401  * @param objectPoints The object points that will be painted, defined in world
402  * @param numberObjectPoints Number of provided object points, with range [0, infinity)
403  * @param imagePoints Image points that will be painted
404  * @param numberImagePoints Number of provided image points, with range [0, infinity)
405  * @param distortProjectedObjectPoints True, to apply the distortion parameters of the camera to the projected object points
406  * @param radiusObjectPoints Radius of the object point paintings in pixel
407  * @param radiusImagePoints Radius of the image point paintings in pixel
408  * @param colorObjectPoints Color that will be used to paint the object points, ensure that one value is provided for each frame channel, otherwise white is used
409  * @param colorImagePoints Color that will be used to paint the image points, ensure that one value is provided for each frame channel, otherwise white is used
410  */
411  static void paintPointsIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const PinholeCamera& pinholeCamera, const Vector3* objectPoints, const size_t numberObjectPoints, const Vector2* imagePoints, const size_t numberImagePoints, const bool distortProjectedObjectPoints, const unsigned int radiusObjectPoints, const unsigned int radiusImagePoints, const uint8_t* colorObjectPoints = nullptr, const uint8_t* colorImagePoints = nullptr);
412 
413  /**
414  * Paints a (projected) 3D axis aligned bounding box into a given frame.
415  * @param frame The frame receiving the points, must be valid
416  * @param flippedCamera_T_world The transformation between world and the flipped camera, must be valid
417  * @param anyCamera The camera profile defining the projection, with dimension equal to the frame dimension
418  * @param boundingBox The bounding box that will be painted, defined in world
419  * @param foregroundColor The foreground color of the plane, nullptr to skip the painting with the foreground color
420  * @param backgroundColor The background color of the plane, nullptr to skip the painting with the background color
421  * @param edgesOnly True, to paint the edges of the bounding box only; False, to paint also the diagonal connections
422  */
423  static void paintBoundingBoxIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const Box3& boundingBox, const uint8_t* foregroundColor, const uint8_t* backgroundColor, const bool edgesOnly = true);
424 
425  /**
426  * Paints a (projected) wire-frame cone into a given frame.
427  * @param frame The frame being drawn to, must be valid
428  * @param flippedCamera_T_cone Inverted and flipped pose of the camera w.r.t the cone
429  * @param pinholeCamera The pinhole camera profile defining the projection, with dimension equal to the frame dimension
430  * @param cone The cone that will be painted
431  * @param distortProjectedObjectPoints True, to apply the distortion parameters of the camera to the projected object points
432  * @param worker Optional worker to distribute the computation
433  * @param color The color for the drawn lines
434  * @param numCircles Number of axis-slicing circles to draw along the cone's vertical span, with range [2, infinity)
435  * @param numVerticalLines Number axis-parallel lines to draw around the cone, with range [0, infinity)
436  * @param numSamples Number of lines to draw to approximate the projection of each circle, with range [3, infinity)
437  */
438  static void paintWireframeConeIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_cone, const PinholeCamera& pinholeCamera, const Cone3& cone, const bool distortProjectedObjectPoints = true, Worker* worker = nullptr, const uint8_t* color = CV::Canvas::yellow(), const unsigned int numCircles = 6u, const unsigned int numVerticalLines = 4u, const unsigned int numSamples = 72u);
439 
440  /**
441  * Paints a (projected) wire-frame cylinder into a given frame.
442  * @param frame The frame being drawn to, must be valid
443  * @param flippedCamera_T_cylinder Inverted and flipped pose of the camera w.r.t the cylinder
444  * @param pinholeCamera The pinhole camera profile defining the projection, with dimension equal to the frame dimension
445  * @param cylinder The cylinder that will be painted
446  * @param distortProjectedObjectPoints True, to apply the distortion parameters of the camera to the projected object points
447  * @param worker Optional worker to distribute the computation
448  * @param color The color for the drawn lines
449  * @param numCircles Number of axis-slicing circles to draw along the cylinder's vertical span, with range [2, infinity)
450  * @param numVerticalLines Number axis-parallel lines to draw around the cylinder, with range [0, infinity)
451  * @param numSamples Number of lines to draw to approximate the projection of each circle, with range [3, infinity)
452  */
453  static void paintWireframeCylinderIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_cylinder, const PinholeCamera& pinholeCamera, const Cylinder3& cylinder, const bool distortProjectedObjectPoints = true, Worker* worker = nullptr, const uint8_t* color = CV::Canvas::yellow(), const unsigned int numCircles = 6u, const unsigned int numVerticalLines = 4u, const unsigned int numSamples = 72u);
454 
455  /**
456  * Paints a (projected) 3D triangle into a given frame.
457  * @param frame The frame in which the triangle will be painted, must be valid
458  * @param flippedCamera_T_world The transformation transforming world to the flipped camera, the flipped camera points towards the positive z-space with y-axis down, must be valid
459  * @param anyCamera The camera profile defining the projection, must be valid
460  * @param triangle The triangle that will be painted
461  * @param color The color to be used to paint the triangle edges, nullptr to use black
462  * @tparam tSize The thickness of the triangle edges in pixels, must be odd with range [1, infinity)
463  */
464  template <unsigned int tSize = 1u>
465  static inline void paintTriangleIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const Triangle3& triangle, const uint8_t* color = nullptr);
466 
467  /**
468  * Paints (projected) 3D triangles into a given frame.
469  * @param frame The frame in which the triangles will be painted, must be valid
470  * @param flippedCamera_T_world The transformation transforming world to the flipped camera, the flipped camera points towards the positive z-space with y-axis down, must be valid
471  * @param anyCamera The camera profile defining the projection, must be valid
472  * @param triangles The 3D triangles that will be painted, defined in world, can be nullptr if 'numberTriangles == 0'
473  * @param numberTriangles Number of triangles that will be painted, with range [0, infinity)
474  * @param color The color to be used to paint the triangle edges, nullptr to use black
475  * @param worker Optional worker to distribute the computation
476  * @tparam tSize The thickness of the triangle edges in pixels, must be odd with range [1, infinity)
477  */
478  template <unsigned int tSize = 1u>
479  static void paintTrianglesIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const Triangle3* triangles, const size_t numberTriangles, const uint8_t* color = nullptr, Worker* worker = nullptr);
480 
481  /**
482  * Paints a (projected) 3D line into a given frame.
483  * @param frame The frame in which the triangle will be painted, must be valid
484  * @param flippedCamera_T_world The transformation transforming world to the flipped camera, the flipped camera points towards the positive z-space with y-axis down, must be valid
485  * @param anyCamera The camera profile defining the projection, must be valid
486  * @param objectPoint0 The start 3D object point of the 3D line, defined in world
487  * @param objectPoint1 The end 3D object point of the 3D line, defined in world
488  * @param segments The number of segments in which the line will be separated, with range [1, infinity), the more segments the better the adjustment to the camera distortion (if any)
489  * @param foregroundColor The foreground color of the plane, nullptr to skip the painting with the foreground color
490  * @param backgroundColor The background color of the plane, nullptr to skip the painting with the background color
491  */
492  static void paintLineIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const Vector3& objectPoint0, const Vector3& objectPoint1, const unsigned int segments, const uint8_t* foregroundColor, const uint8_t* backgroundColor);
493 
494  /**
495  * Paints a 3D coordinate system (projected) into a frame.
496  * If the frame in an RGB 24bit frame, than the axis are painted in red (x), green (y), and blue (z); otherwise axis with color zero are.<br>
497  * @param frame The frame in which the coordinate system is painted, must be valid
498  * @param flippedCamera_T_world The camera posed converting world to the flipped camera coordinate system (a camera coordinate system pointing towards the positive z-space), must be valid
499  * @param anyCamera The camera profile that is used to render the coordinate system
500  * @param world_T_coordinateSystem The transformation of the coordinate system which transformed points defined in the local coordinate system (which will be rendered) into points defined in the world coordinate system, must be valid
501  * @param length The length of the three axis of the coordinate system, defined in the units of the local coordinate system (coordinateSystem)
502  */
503  static void paintCoordinateSystemIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const HomogenousMatrix4& world_T_coordinateSystem, const Scalar length);
504 
505  /**
506  * Paints a 3D plane into the frame, further the origin of the plane is painted.
507  * This function determines a worthwhile expansion of the plane best matching with the scene.
508  * @param frame The frame in which the plane is painted
509  * @param world_T_camera The camera pose from which the 3D object points are observed with default viewing direction towards the negative z-space and y-axis as up vector, transforming camera to world, must be valid
510  * @param camera The camera profile defining the project, must be valid
511  * @param planeTransformation The transformation having the origin on the plane and the z-axis parallel to the plane's normal
512  * @param bins The number of bins in both direction that will be painted, with range [1, infinity)
513  * @param foregroundColor The foreground color of the plane, nullptr to skip the painting with the foreground color
514  * @param backgroundColor The background color of the plane, nullptr to skip the painting with the background color
515  * @param expansion Optional resulting plane's expansion in the scene in x-axis and y-axis defined in world coordinates, with range (0, infinity)
516  * @return True, if the plane is perpendicular to the given camera frame
517  */
518  static bool paintPlane(Frame& frame, const HomogenousMatrix4& world_T_camera, const AnyCamera& camera, const HomogenousMatrix4& planeTransformation, const unsigned int bins, const uint8_t* foregroundColor, const uint8_t* backgroundColor, Scalar* expansion = nullptr);
519 
520  /**
521  * Paints a 3D plane into the frame, further the origin of the plane is painted.
522  * @param frame The frame in which the plane is painted
523  * @param flippedCamera_T_world The camera posed converting world to the flipped camera coordinate system (a camera coordinate system pointing towards the positive z-space), must be valid
524  * @param camera The camera profile defining the project, must be valid
525  * @param planeTransformation The transformation having the origin on the plane and the z-axis parallel to the plane's normal
526  * @param expansion The plane's expansion for the scene in x-axis and y-axis defined in world coordinates, with range (0, infinity)
527  * @param bins The number of bins in both direction that will be painted, with range [1, infinity)
528  * @param foregroundColor The foreground color of the plane, nullptr to skip the painting with the foreground color
529  * @param backgroundColor The background color of the plane, nullptr to skip the painting with the background color
530  * @return True, if the plane is perpendicular to the given camera frame
531  */
532  static bool paintPlaneIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& camera, const HomogenousMatrix4& planeTransformation, const Scalar expansion, const unsigned int bins, const uint8_t* foregroundColor, const uint8_t* backgroundColor);
533 
534  /**
535  * Paints quads that are located on a 3D plane into a given frame.
536  * @param frame The frame receiving the points
537  * @param world_T_camera The camera pose from which the 3D object points are observed with default viewing direction towards the negative z-space and y-axis as up vector, transforming camera to world, must be valid
538  * @param camera The camera profile defining the projection, with dimension equal to the frame dimension
539  * @param quadOrigin Origin of the upper left quad position, defined in world
540  * @param quadHorizontal Vector starting at the quad origin and defining the horizontal direction of the quads, defined in world
541  * @param quadVertical Vector starting at the quad origin and defining the vertical direction of the quads, defined in world
542  * @param horizontalBins Number of horizontal bins that will be painted
543  * @param verticalBins Number of vertical bins that will be painted
544  * @param color The color that will be used to paint the points, ensure that one value is provided for each frame channel, otherwise black is used
545  */
546  static inline void paintQuads(Frame& frame, const HomogenousMatrix4& world_T_camera, const AnyCamera& camera, const Vector3& quadOrigin, const Vector3& quadHorizontal, const Vector3& quadVertical, const unsigned int horizontalBins, const unsigned int verticalBins, const uint8_t* color = nullptr);
547 
548  /**
549  * Paints quads that are located on a 3D plane into a given frame.
550  * @see paintQuads().
551  */
552  static void paintQuadsIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& camera, const Vector3& quadOrigin, const Vector3& quadHorizontal, const Vector3& quadVertical, const unsigned int horizontalBins, const unsigned int verticalBins, const uint8_t* color = nullptr);
553 
554  /**
555  * Paints / blends a binary 8 bit mask into a given frame with identical frame dimension.
556  * @param frame The frame in which the mask will be painted, must be valid
557  * @param mask The binary mask frame, with frame dimension matching with the given frame, must be valid
558  * @param maskValue The mask value defining pixels which will be painted as masked, may be 0x00 or 0xFF
559  * @param worker Optional worker object to distribute the computation
560  * @return The resulting frame with blended mask
561  */
562  static Frame paintMask(const Frame& frame, const Frame& mask, const uint8_t maskValue = uint8_t(0xFFu), Worker* worker = nullptr);
563 
564  /**
565  * Paints / blends a bounding box into a given frame.
566  * @param frame The frame in which the bounding box will be painted, must be valid
567  * @param boundingBox The bounding box, must be valid and must be defined inside the frame
568  * @param worker Optional worker object to distribute the computation
569  * @return The resulting frame with blended mask
570  */
571  static Frame paintBoundingBox(const Frame& frame, const CV::PixelBoundingBox& boundingBox, Worker* worker = nullptr);
572 
573  /**
574  * Aligns two frames connected by a given homography into one frame while the resulting frame covers the area of one given frame only (the fixed frame).
575  * @param fixedFrame The fixed frame which will be untouched while the dynamic frame will be transformed by application of the homography and aligned to this frame, must be valid
576  * @param dynamicFrame The dynamic frame which will be transformed and then aligned to the fixed frame, with same pixel format and pixel orientation as the fixed frame
577  * @param dynamic_H_fixed The homography transforming points defined in the fixed frame to points defined in the dynamic frame, must be valid
578  * @param result The resulting frame with aligned frames, the frame type will be adjusted/set internally
579  * @param blend True, to blend both frames; False, to overwrite each pixel for which a corresponding pixel in the dynamic frame exist
580  * @param worker Optional worker object to distribute the computation
581  * @return True, if succeeded
582  */
583  static bool alignFramesHomography(const Frame& fixedFrame, const Frame& dynamicFrame, const SquareMatrix3& dynamic_H_fixed, Frame& result, const bool blend, Worker* worker = nullptr);
584 
585  /**
586  * Aligns two frames connected by a given homography into one frame entirely covering the frame content of both images.
587  * @param fixedFrame The fixed frame which will be untouched while the dynamic frame will be transformed by application of the homography and aligned to this frame, must be valid
588  * @param dynamicFrame The dynamic frame which will be transformed and then aligned to the fixed frame, with same pixel format and pixel orientation as the fixed frame
589  * @param dynamic_H_fixed The homography transforming points defined in the fixed frame to points defined in the dynamic frame, must be valid
590  * @param result The resulting frame with aligned frames converting the image content of both frames, the frame type will be adjusted/set internally
591  * @param blend True, to blend both frames; False, to overwrite each pixel for which a corresponding pixel in the dynamic frame exist
592  * @param worker Optional worker object to distribute the computation
593  * @param maximalWidth The maximal width of the resulting frame to ensure that an extreme homography does not create an extreme large result, in pixel with range [1, infinity)
594  * @param maximalHeight The maximal height of the resulting frame to ensure that an extreme homography does not create an extreme large result, in pixel with range [1, infinity)
595  * @param fixedFrameLeft Optional resulting horizontal location of the top left pixel of the fixed frame in the resulting aligned frame, with range [0, result.width() - fixedFrame.width()]
596  * @param fixedFrameTop Optional resulting vertical location of the top left pixel of the fixed frame in the resulting aligned frame, with range [0, result.height() - fixedFrame.height()]
597  * @param dynamicFrameLeft Optional resulting horizontal location of the top left pixel of the dynamic frame in relation to 'fixedFrameLeft', with range (-infinity, infinity)
598  * @param dynamicFrameTop Optional resulting horizontal location of the top left pixel of the dynamic frame in relation to 'fixedFrameTop', with range (-infinity, infinity)
599  * @param fullFixedFrame Optional resulting frame covering the fixed frame only, but with same frame dimension as the resulting aligned frame
600  * @param fullDynamicFrame Optional resulting frame covering the transformed dynamic frame only, but with same frame dimension as the resulting aligned frame
601  * @return True, if succeeded
602  */
603  static bool alignFramesHomographyFullCoverage(const Frame& fixedFrame, const Frame& dynamicFrame, const SquareMatrix3& dynamic_H_fixed, Frame& result, const bool blend, Worker* worker = nullptr, unsigned int maximalWidth = 16384u, const unsigned int maximalHeight = 16384u, unsigned int* fixedFrameLeft = nullptr, unsigned int* fixedFrameTop = nullptr, Scalar* dynamicFrameLeft = nullptr, Scalar* dynamicFrameTop = nullptr, Frame* fullFixedFrame = nullptr, Frame* fullDynamicFrame = nullptr);
604 
605  /**
606  * Visualizes image point information of a tracking database for a specific pose id.
607  * @param database The database holding the tracking information to be visualized
608  * @param poseId The id of the pose for which the visualization will be created
609  * @param frame The frame receiving the visualization of the database
610  * @param colorImagePoints The color for feature points, ensure that one value is provided for each frame channel
611  * @param colorImagePointsInstable The color for instable paths, ensure that one value is provided for each frame channel
612  * @param colorImagePointsStable The color for stable paths, ensure that one value is provided for each frame channel
613  * @param maximalPathLength The maximal length (number of concurrent frames) of paths of feature points that will be visualized, with range [0, infinity)
614  * @param stablePathLength The length (number of concurrent frames) of paths so that they count as stable, with range [1, infinity)
615  * @param transformation The transformation matrix which will be applied to each feature point position before the position is visualized
616  * @param worker Optional worker to distribute the computation
617  */
618  static void visualizeDatabase(const Database& database, const Index32 poseId, Frame& frame, const uint8_t* colorImagePoints, const uint8_t* colorImagePointsInstable, const uint8_t* colorImagePointsStable, const unsigned int maximalPathLength = 20u, const unsigned int stablePathLength = 100u, const SquareMatrix3& transformation = SquareMatrix3(true), Worker* worker = nullptr);
619 
620  /**
621  * Writes a camera profile to a binary output stream.
622  * @param pinholeCamera The pinhole camera profile to be written
623  * @param outputStream The output stream receiving the information
624  * @return True, if succeeded
625  * @see readCamera().
626  */
627  static bool writeCamera(const PinholeCamera& pinholeCamera, IO::OutputBitstream& outputStream);
628 
629  /**
630  * Reads a camera profile from a binary input stream.
631  * @param inputStream The input stream providing the information
632  * @param pinholeCamera The resulting pinhole camera profile
633  * @see writeCamera().
634  */
635  static bool readCamera(IO::InputBitstream& inputStream, PinholeCamera& pinholeCamera);
636 
637  /**
638  * Writes the information of a database to a given output stream as binary information.
639  * @param database The database to be written
640  * @param outputStream The output stream receiving the information
641  * @return True, if succeeded
642  * @see readDatabase(), writeCamera().
643  */
644  static bool writeDatabase(const Database& database, IO::OutputBitstream& outputStream);
645 
646  /**
647  * Reads a database information from a binary input stream.
648  * @param inputStream The input stream providing the information
649  * @param database The database receiving the information, the given database will cleared before the information is assigned
650  * @return True, if succeeded
651  * @see writeDatabase(), readCamera().
652  */
653  static bool readDatabase(IO::InputBitstream& inputStream, Database& database);
654 
655  /**
656  * Encodes the tracking environment composes of a frame mesh (a frame with correspondences of 2D image points and 3D object points), a camera pose from which the frame has been captured and an independent set of 3D object points.<br>
657  * @param frame The frame to encode
658  * @param frameImagePoints The image points located in the given frame
659  * @param frameObjectPoints The object points, one object point for each image point
660  * @param framePose The camera pose to encode
661  * @param objectPoints The independent object points to encode
662  * @return The encoded buffer
663  */
664  static Maintenance::Buffer encodeEnvironment(const Frame& frame, const Vectors2& frameImagePoints, const Vectors3& frameObjectPoints, const HomogenousMatrix4& framePose, const Vectors3& objectPoints);
665 
666  protected:
667 
668  /**
669  * Paints a subset of a set of lines into a given frame.
670  * @param frame The frame in which is drawn
671  * @param startPositions Start positions of the lines
672  * @param stopPositions Stop positions of the lines, each end position must have a corresponding start position
673  * @param color The color that will be used to paint the lines, ensure that one value is provided for each frame channel, nullptr to use black
674  * @param subPixel True, to paint the lines with sub-pixel accuracy; False, to paint the lines with pixel accuracy
675  * @param offsetStartPositions The offset which will be added to each start position before painting the line, with range (-infinity, infinity)x(-infinity, infinity)
676  * @param offsetStopPositions The offset which will be added to each stop position before painting the line, with range (-infinity, infinity)x(-infinity, infinity)
677  * @param firstLine First line to be handled
678  * @param numberLines The number of lines to be handled
679  */
680  static inline void paintLinesSubset(Frame* frame, const Vector2* startPositions, const Vector2* stopPositions, const uint8_t* color, const bool subPixel, const Vector2* offsetStartPositions, const Vector2* offsetStopPositions, const unsigned int firstLine, const unsigned int numberLines);
681 
682  /**
683  * Paints a subset of a set of lines into a given frame with sub-pixel accuracy.
684  * @param frame The frame in which is drawn, must be valid
685  * @param startPositions Start positions of the lines
686  * @param stopPositions Stop positions of the lines, each end position must have a corresponding start position
687  * @param color The color that will be used to paint the lines, ensure that one value is provided for each frame channel, nullptr to use black
688  * @param firstLine First line to be handled
689  * @param numberLines The number of lines to be handled
690  * @tparam tSize The thickness of the lines in pixel, must be odd with range [1, infinity)
691  */
692  template <unsigned int tSize>
693  static inline void paintLinesSubset(Frame* frame, const Vector2* startPositions, const Vector2* stopPositions, const uint8_t* color, const unsigned int firstLine, const unsigned int numberLines);
694 
695  /**
696  * Paints a subset of a set of lines into a given frame with sub-pixel accuracy.
697  * @param frame The frame in which is drawn, must be valid
698  * @param startPositions Start positions of the lines
699  * @param stopPositions Stop positions of the lines, each end position must have a corresponding start position
700  * @param colorForeground Foreground color that will be used to paint the points, ensure that one value is provided for each frame channel, nullptr to use black
701  * @param colorBackground Background color that will be used to paint the points, ensure that one value is provided for each frame channel, nullptr to use black
702  * @param firstLine First line to be handled
703  * @param numberLines The number of lines to be handled
704  * @tparam tSizeForeground The thickness of the foreground lines in pixel, must be odd with range [1, infinity)
705  * @tparam tSizeBackground The thickness of the background lines in pixel, must be odd with range (tSizeForeground, infinity)
706  */
707  template <unsigned int tSizeForeground, unsigned int tSizeBackground>
708  static inline void paintLinesSubset(Frame* frame, const Vector2* startPositions, const Vector2* stopPositions, const uint8_t* colorForeground, const uint8_t* colorBackground, const unsigned int firstLine, const unsigned int numberLines);
709 
710  /**
711  * Paints a subset of several paths into a given frame with sub-pixel accuracy.
712  * @param frame The frame in which the paths will be painted
713  * @param paths The individual paths to be painted
714  * @param color The color that will be used to paint the points, ensure that one value is provided for each frame channel, nullptr to apply black
715  * @param firstPath The first path to handled
716  * @param numberPaths The number of paths to handle
717  * @tparam tSize The thickness of the paths in pixel, must be odd with range [1, infinity)
718  * @see paintPaths().
719  */
720  template <unsigned int tSize>
721  static inline void paintPathsSubset(Frame* frame, const Vectors2* paths, const uint8_t* color, const unsigned int firstPath, const unsigned int numberPaths);
722 
723  /**
724  * Paints a subset of several paths into a given frame with sub-pixel accuracy.
725  * The colors of the paths are determined by an interpolation between two separate color values.
726  * @param frame The frame in which the paths will be painted
727  * @param paths The individual paths to be painted
728  * @param color0 The first color value, ensure that one value is provided for each frame channel
729  * @param color1 The second color value, ensure that one value is provided for each frame channel
730  * @param factors The interpolation factor, one factor for each path, with range [0, 1]
731  * @param firstPath The first path to handled
732  * @param numberPaths The number of paths to handle
733  * @tparam tSize The thickness of the paths in pixel, must be odd with range [1, infinity)
734  * @see paintPaths().
735  */
736  template <unsigned int tSize>
737  static inline void paintPathsAdvancedSubset(Frame* frame, const Vectors2* paths, const uint8_t* color0, const uint8_t* color1, const Scalar* factors, const unsigned int firstPath, const unsigned int numberPaths);
738 
739  /**
740  * Paints a subset of 2D triangles into a given frame with sub-pixel accuracy.
741  * @param frame The frame receiving the triangles
742  * @param triangles The triangles that will be painted
743  * @param color The color that will be used to paint the triangle points, ensure that one value is provided for each frame channel, otherwise black is used
744  * @param firstTriangle The first triangle to handled
745  * @param numberTriangles The number of triangle to handle
746  * @tparam tSize The thickness of the triangle edges in pixels, must be odd with range [1, infinity)
747  */
748  template <unsigned int tSize = 1u>
749  static inline void paintTrianglesSubset(Frame* frame, const Triangle2* triangles, const uint8_t* color, const unsigned int firstTriangle, const unsigned int numberTriangles);
750 
751  /**
752  * Projects and paints a subset of 3D triangles into a given frame with sub-pixel accuracy.
753  * @param frame The frame in which the triangle will be painted, must be valid
754  * @param flippedCamera_T_world The transformation transforming world to the flipped camera, the flipped camera points towards the positive z-space with y-axis down, must be valid
755  * @param anyCamera The camera profile defining the projection, must be valid
756  * @param triangles The triangles that will be painted, defined in world, must be valid
757  * @param color The color to be used to paint the triangle edges, nullptr to use black
758  * @param firstTriangle The first triangle to handled
759  * @param numberTriangles The number of triangle to handle
760  * @tparam tSize The thickness of the triangle edges in pixels, must be odd with range [1, infinity)
761  */
762  template <unsigned int tSize = 1u>
763  static inline void paintTrianglesIFSubset(Frame* frame, const HomogenousMatrix4* flippedCamera_T_world, const AnyCamera* anyCamera, const Triangle3* triangles, const uint8_t* color, const unsigned int firstTriangle, const unsigned int numberTriangles);
764 
765  /**
766  * Paints subset of a set of 2D image points into a given frame with sub-pixel accuracy.
767  * @param frame The frame in which the image points will be painted
768  * @param imagePoints The image points which will be painted
769  * @param color The color for the image points
770  * @param firstImagePoint The first image point to handle
771  * @param numberImagePoints The number of image points to handle
772  * @tparam tPointSize The radius of the image points, must be odd with range [1, infinity)
773  */
774  template <unsigned int tPointSize>
775  static inline void paintImagePointsSubset(Frame* frame, const Vector2* imagePoints, const uint8_t* color, const unsigned int firstImagePoint, const unsigned int numberImagePoints);
776 
777  /**
778  * Paints a subset of set of 3D object points (rather their projected 2D counterparts respectively) into a given frame with sub-pixel accuracy.
779  * @param frame The frame in which the projected object points will be painted
780  * @param anyCamera The camera profile defining the projection between 3D object points and camera plane, must be valid
781  * @param flippedCamera_T_world The inverted and flipped camera pose from which the 3D object points are observed, with default camera pointing towards the positive z-space with y-axis down, must be valid
782  * @param objectPoints The object points which will be projected into the camera frame
783  * @param color The color for the object points
784  * @param firstObjectPoint The first object point to handle
785  * @param numberObjectPoints The number of object points to handle
786  * @tparam tPointSize The radius of the object points, must be odd with range [1, infinity)
787  */
788  template <unsigned int tPointSize>
789  static inline void paintObjectPointsSubset(Frame* frame, const AnyCamera* anyCamera, const HomogenousMatrix4* flippedCamera_T_world, const Vector3* objectPoints, const uint8_t* color, const unsigned int firstObjectPoint, const unsigned int numberObjectPoints);
790 
791  /**
792  * Paints a subset of feature points having a radius (a scale) and orientation.
793  * @param frame The frame in which the feature points will be painted, must be valid
794  * @param width The width of the frame in pixel, with range (0, infinity)
795  * @param height The height of the frame in pixel, with range (0, infinity)
796  * @param positions The positions of the feature points defined in the pixel domain of the given frame, with range (-infinity, infinity)x(-infinity, infinity)
797  * @param radii The radii (scale) of the feature points in pixel, with range (0, infinity), one for each position
798  * @param orientations The orientations of the feature points as CCW angle in radian, with range [0, 2PI), one for each position
799  * @param color The color for the feature point, one value for each frame data channel
800  * @param shadowColor The outer color for the object points, one value for each frame data channel or nullptr to skip painting the shadow
801  * @param offsetX Explicit horizontal offset which will be added to every feature point location before the point is painted, with range (-infinity, infinity)
802  * @param offsetY Explicit vertical offset which will be added to every feature point location before the point is painted, with range (-infinity, infinity)
803  * @param framePaddingElements The number of padding elements at the end of each frame row, in elements, with range [0, infinity)
804  * @param firstFeaturePoint The first feature point to be handled, with range [0, 'size')
805  * @param numberFeaturePoints The number of feature points to be handled, with range [1, 'size']
806  * @tparam tChannels The number of data channels, with range [1, infinity)
807  */
808  template <unsigned int tChannels>
809  static inline void paintFeaturePoints8BitPerChannelSubset(uint8_t* frame, const unsigned int width, const unsigned int height, const Vector2* positions, const Scalar* radii, const Scalar* orientations, const uint8_t* color, const uint8_t* shadowColor, const Scalar offsetX, const Scalar offsetY, const unsigned int framePaddingElements, const unsigned int firstFeaturePoint, const unsigned int numberFeaturePoints);
810 
811  /**
812  * Paints a subset of a set of correspondences between 2D image points and 3D object points (rather their projected 2D counterparts respectively) into a given frame with sub-pixel accuracy.
813  * The projected object points will be painted first, followed by their corresponding image points.<br>
814  * Further, a connection between the projected object points and the corresponding image points can be painted, which can be helpful if the given pose is not accurate.
815  * @param frame The frame in which the projected object points and image points will be painted
816  * @param camera The camera profile defining the projection between 3D object points and camera plane
817  * @param flippedCamera_T_model The inverted and flipped camera pose transforming points located in coordinate system of the model to points located in the coordinate system of the flipped camera, must be valid
818  * @param objectPoints The object points which will be projected into the camera frame
819  * @param imagePoints The image points corresponding to the given object points, the smaller the distance between image points and projected object points the more accurate the camera pose
820  * @param maxSqrError The maximal square pixel error between a projected object point and the corresponding image point to count as valid, with range [0, infinity)
821  * @param colorValidObjectPoints The color for valid object points
822  * @param colorValidImagePoints The color for valid object points
823  * @param colorInvalidObjectPoints The color for invalid object points
824  * @param colorInvalidImagePoints The color for invalid image points
825  * @param drawObjectPoints True, to draw the object points
826  * @param drawImagePoints True, to draw the image points
827  * @param drawConnections True, to draw the connections between projected object points and the corresponding image points
828  * @param firstCorrespondence The first correspondence to handle
829  * @param numberCorrespondences The number of correspondences to handle
830  * @tparam tObjectPointSize The radius of the object points, must be odd with range [tImagePointSize, infinity)
831  * @tparam tImagePointSize The radius of the image points, must be odd, with range [1, infinity)
832  * @see paintCorrespondences().
833  */
834  template <unsigned int tObjectPointSize, unsigned int tImagePointSize>
835  static void paintCorrespondencesSubset(Frame* frame, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_model, const Vector3* objectPoints, const Vector2* imagePoints, const Scalar maxSqrError, const uint8_t* colorValidObjectPoints, const uint8_t* colorValidImagePoints, const uint8_t* colorInvalidObjectPoints, const uint8_t* colorInvalidImagePoints, const bool drawObjectPoints, const bool drawImagePoints, const bool drawConnections, const unsigned int firstCorrespondence, const unsigned int numberCorrespondences);
836 
837  /**
838  * Paints / blends a binary 8 bit mask pixel into a given pixel with 8 bit per channel.
839  * @param pixel The pixel data which will receive the mask
840  * @param blendFactor The blend factor for the given pixel
841  * @tparam tBlendChannel The index of the data channel which will be blended, with range [0, tChannels)
842  * @tparam tChannels The number of data channels of the given pixel
843  */
844  template <unsigned int tBlendChannel, unsigned int tChannels>
845  static inline void blendPixel(uint8_t* pixel, const uint8_t blendFactor);
846 };
847 
848 inline void Utilities::paintLine(Frame& frame, const Vector2& startPosition, const Vector2& stopPosition, const uint8_t* color, const bool subPixel)
849 {
850  if (subPixel)
851  {
852  CV::Canvas::line<1u>(frame, startPosition.x(), startPosition.y(), stopPosition.x(), stopPosition.y(), color);
853  }
854  else
855  {
856  CV::Canvas::line(frame, Numeric::round32(startPosition.x()), Numeric::round32(startPosition.y()), Numeric::round32(stopPosition.x()), Numeric::round32(stopPosition.y()), color);
857  }
858 }
859 
860 inline void Utilities::paintLines(Frame& frame, const Vector2* startPositions, const Vector2* stopPositions, const size_t numberLines, const uint8_t* color, Worker* worker, const bool subPixel, const Vector2& offsetStartPositions, const Vector2& offsetStopPositions)
861 {
862  if (numberLines == 0)
863  {
864  return;
865  }
866 
867  if (worker)
868  {
869  worker->executeFunction(Worker::Function::createStatic(&paintLinesSubset, &frame, startPositions, stopPositions, color, subPixel, &offsetStartPositions, &offsetStopPositions, 0u, 0u), 0u, (unsigned int)(numberLines));
870  }
871  else
872  {
873  paintLinesSubset(&frame, startPositions, stopPositions, color, subPixel, &offsetStartPositions, &offsetStopPositions, 0u, (unsigned int)(numberLines));
874  }
875 }
876 
877 template <unsigned int tSize>
878 inline void Utilities::paintLines(Frame& frame, const Vector2* startPositions, const Vector2* stopPositions, const size_t numberLines, const uint8_t* color, Worker* worker)
879 {
880  if (numberLines == 0)
881  {
882  return;
883  }
884 
885  if (worker)
886  {
887  worker->executeFunction(Worker::Function::createStatic(&paintLinesSubset<tSize>, &frame, startPositions, stopPositions, color, 0u, 0u), 0u, (unsigned int)numberLines);
888  }
889  else
890  {
891  paintLinesSubset<tSize>(&frame, startPositions, stopPositions, color, 0u, (unsigned int)numberLines);
892  }
893 }
894 
895 template <unsigned int tSizeForeground, unsigned int tSizeBackground>
896 inline void Utilities::paintLines(Frame& frame, const Vector2* startPositions, const Vector2* stopPositions, const size_t numberLines, const uint8_t* foregroundColor, const uint8_t* backgroundColor, Worker* worker)
897 {
898  if (numberLines == 0)
899  {
900  return;
901  }
902 
903  if (worker)
904  {
905  worker->executeFunction(Worker::Function::createStatic(&paintLinesSubset<tSizeForeground, tSizeBackground>, &frame, startPositions, stopPositions, foregroundColor, backgroundColor, 0u, 0u), 0u, (unsigned int)numberLines);
906  }
907  else
908  {
909  paintLinesSubset<tSizeForeground, tSizeBackground>(&frame, startPositions, stopPositions, foregroundColor, backgroundColor, 0u, (unsigned int)numberLines);
910  }
911 }
912 
913 template <unsigned int tSize>
914 inline void Utilities::paintPaths(Frame& frame, const Vectors2* paths, const size_t size, const uint8_t* color, Worker* worker)
915 {
916  if (size == 0)
917  {
918  return;
919  }
920 
921  if (worker)
922  {
923  worker->executeFunction(Worker::Function::createStatic(&paintPathsSubset<tSize>, &frame, paths, color, 0u, 0u), 0u, (unsigned int)size);
924  }
925  else
926  {
927  paintPathsSubset<tSize>(&frame, paths, color, 0u, (unsigned int)size);
928  }
929 }
930 
931 template <unsigned int tSize>
932 inline void Utilities::paintPaths(Frame& frame, const Vectors2* paths, const size_t size, const uint8_t* color0, const uint8_t* color1, const Scalar* factors, Worker* worker)
933 {
934  if (size == 0)
935  {
936  return;
937  }
938 
939  if (worker)
940  {
941  worker->executeFunction(Worker::Function::createStatic(&paintPathsAdvancedSubset<tSize>, &frame, paths, color0, color1, factors, 0u, 0u), 0u, (unsigned int)size);
942  }
943  else
944  {
945  paintPathsAdvancedSubset<tSize>(&frame, paths, color0, color1, factors, 0u, (unsigned int)size);
946  }
947 }
948 
949 template <unsigned int tSize>
950 void Utilities::paintTriangle(Frame& frame, const Triangle2& triangle, const uint8_t* color)
951 {
952  paintTrianglesSubset<tSize>(&frame, &triangle, color, 0u, 1u);
953 }
954 
955 template <unsigned int tSize>
956 void Utilities::paintTriangles(Frame& frame, const Triangles2& triangles, const uint8_t* color, Worker* worker)
957 {
958  if (triangles.empty())
959  {
960  return;
961  }
962 
963  if (worker)
964  {
965  worker->executeFunction(Worker::Function::createStatic(&paintTrianglesSubset<tSize>, &frame, triangles.data(), color, 0u, 0u), 0u, (unsigned int)triangles.size());
966  }
967  else
968  {
969  paintTrianglesSubset<tSize>(&frame, triangles.data(), color, 0u, (unsigned int)triangles.size());
970  }
971 }
972 
973 template <unsigned int tPointSize>
974 inline void Utilities::paintImagePoints(Frame& frame, const Vector2* imagePoints, const size_t size, const uint8_t* color, Worker* worker)
975 {
976  static_assert(tPointSize % 2u == 1u, "Invalid point size!");
977 
978  if (size == 0)
979  {
980  return;
981  }
982 
983  if (worker)
984  {
985  worker->executeFunction(Worker::Function::createStatic(&paintImagePointsSubset<tPointSize>, &frame, imagePoints, color, 0u, 0u), 0u, (unsigned int)size);
986  }
987  else
988  {
989  paintImagePointsSubset<tPointSize>(&frame, imagePoints, color, 0u, (unsigned int)size);
990  }
991 }
992 
993 template <unsigned int tPointSize>
994 inline void Utilities::paintObjectPoints(Frame& frame, const AnyCamera& anyCamera, const HomogenousMatrix4& world_T_camera, const Vector3* objectPoints, const size_t size, const uint8_t* color, Worker* worker)
995 {
996  static_assert(tPointSize % 2u == 1u, "Invalid point size!");
997 
998  ocean_assert(frame.isValid() && anyCamera.isValid());
999  ocean_assert(frame.width() == anyCamera.width() && frame.height() == anyCamera.height());
1000 
1001  if (size == 0)
1002  {
1003  return;
1004  }
1005 
1006  const HomogenousMatrix4 flippedCamera_T_world(AnyCamera::standard2InvertedFlipped(world_T_camera));
1007 
1008  if (worker)
1009  {
1010  worker->executeFunction(Worker::Function::createStatic(&paintObjectPointsSubset<tPointSize>, &frame, &anyCamera, &flippedCamera_T_world, objectPoints, color, 0u, 0u), 0u, (unsigned int)(size));
1011  }
1012  else
1013  {
1014  paintObjectPointsSubset<tPointSize>(&frame, &anyCamera, &flippedCamera_T_world, objectPoints, color, 0u, (unsigned int)(size));
1015  }
1016 }
1017 
1018 template <unsigned int tChannels>
1019 void Utilities::paintFeaturePoint8BitPerChannel(uint8_t* frame, const unsigned int width, const unsigned int height, const Vector2& position, const Scalar radius, const Scalar orientation, const uint8_t* color, const uint8_t* shadowColor, const unsigned int framePaddingElements)
1020 {
1021  ocean_assert(frame && width != 0u && height != 0u && color);
1022  ocean_assert(radius >= Numeric::eps() && orientation >= 0 && orientation <= Numeric::pi2());
1023 
1024  const Quaternion rotation(Vector3(0, 0, 1), orientation);
1025 
1026  const Vector3 direction = rotation * Vector3(radius, 0, 0);
1027  const Vector3 leftTop = rotation * Vector3(-radius, -radius, 0);
1028  const Vector3 rightTop = rotation * Vector3(radius, -radius, 0);
1029  const Vector3 rightBottom = rotation * Vector3(radius, radius, 0);
1030  const Vector3 leftBottom = rotation * Vector3(-radius, radius, 0);
1031 
1032  if (shadowColor)
1033  {
1034  CV::Canvas::line8BitPerChannel<tChannels, 3u>(frame, width, height, position.x(), position.y(), position.x() + direction.x(), position.y() + direction.y(), shadowColor, framePaddingElements);
1035 
1036  CV::Canvas::line8BitPerChannel<tChannels, 3u>(frame, width, height, position.x() + leftTop.x(), position.y() + leftTop.y(), position.x() + leftBottom.x(), position.y() + leftBottom.y(), shadowColor, framePaddingElements);
1037  CV::Canvas::line8BitPerChannel<tChannels, 3u>(frame, width, height, position.x() + leftBottom.x(), position.y() + leftBottom.y(), position.x() + rightBottom.x(), position.y() + rightBottom.y(), shadowColor, framePaddingElements);
1038  CV::Canvas::line8BitPerChannel<tChannels, 3u>(frame, width, height, position.x() + rightBottom.x(), position.y() + rightBottom.y(), position.x() + rightTop.x(), position.y() + rightTop.y(), shadowColor, framePaddingElements);
1039  CV::Canvas::line8BitPerChannel<tChannels, 3u>(frame, width, height, position.x() + rightTop.x(), position.y() + rightTop.y(), position.x() + leftTop.x(), position.y() + leftTop.y(), shadowColor, framePaddingElements);
1040  }
1041 
1042  CV::Canvas::line8BitPerChannel<tChannels, 1u>(frame, width, height, position.x(), position.y(), position.x() + direction.x(), position.y() + direction.y(), color, framePaddingElements);
1043 
1044  CV::Canvas::line8BitPerChannel<tChannels, 1u>(frame, width, height, position.x() + leftTop.x(), position.y() + leftTop.y(), position.x() + leftBottom.x(), position.y() + leftBottom.y(), color, framePaddingElements);
1045  CV::Canvas::line8BitPerChannel<tChannels, 1u>(frame, width, height, position.x() + leftBottom.x(), position.y() + leftBottom.y(), position.x() + rightBottom.x(), position.y() + rightBottom.y(), color, framePaddingElements);
1046  CV::Canvas::line8BitPerChannel<tChannels, 1u>(frame, width, height, position.x() + rightBottom.x(), position.y() + rightBottom.y(), position.x() + rightTop.x(), position.y() + rightTop.y(), color, framePaddingElements);
1047  CV::Canvas::line8BitPerChannel<tChannels, 1u>(frame, width, height, position.x() + rightTop.x(), position.y() + rightTop.y(), position.x() + leftTop.x(), position.y() + leftTop.y(), color, framePaddingElements);
1048 }
1049 
1050 template <unsigned int tChannels>
1051 inline void Utilities::paintFeaturePoints8BitPerChannel(uint8_t* frame, const unsigned int width, const unsigned int height, const Vector2* positions, const Scalar* radii, const Scalar* orientations, const size_t size, const uint8_t* color, const uint8_t* shadowColor, const Vector2& explicitOffset, const unsigned int framePaddingElements, Worker* worker)
1052 {
1053  static_assert(tChannels != 0u, "Invalid channel number!");
1054 
1055  ocean_assert(frame && width != 0u && height != 0u);
1056 
1057  if (size == 0)
1058  {
1059  return;
1060  }
1061 
1062  if (worker)
1063  {
1064  worker->executeFunction(Worker::Function::createStatic(&paintFeaturePoints8BitPerChannelSubset<tChannels>, frame, width, height, positions, radii, orientations, color, shadowColor, explicitOffset.x(), explicitOffset.y(), framePaddingElements, 0u, 0u), 0u, (unsigned int)(size), 11u, 12u, 20u);
1065  }
1066  else
1067  {
1068  paintFeaturePoints8BitPerChannelSubset<tChannels>(frame, width, height, positions, radii, orientations, color, shadowColor, explicitOffset.x(), explicitOffset.y(), framePaddingElements, 0u, (unsigned int)(size));
1069  }
1070 }
1071 
1072 template <unsigned int tObjectPointSize, unsigned int tImagePointSize>
1073 inline void Utilities::paintCorrespondences(Frame& frame, const AnyCamera& camera, const HomogenousMatrix4& model_T_camera, const Vector3* objectPoints, const Vector2* imagePoints, const size_t correspondences, const Scalar maxSqrError, const uint8_t* colorValidObjectPoints, const uint8_t* colorValidImagePoints, const uint8_t* colorInvalidObjectPoints, const uint8_t* colorInvalidImagePoints, const bool drawObjectPoints, const bool drawImagePoints, const bool drawConnections, Worker* worker)
1074 {
1075  static_assert(tObjectPointSize >= tImagePointSize, "Invalid point size!");
1076  static_assert(tObjectPointSize % 2u == 1u, "Invalid point size!");
1077  static_assert(tImagePointSize % 2u == 1u, "Invalid point size!");
1078 
1079  if (correspondences == 0)
1080  {
1081  return;
1082  }
1083 
1084  const HomogenousMatrix4 flippedCamera_T_model(AnyCamera::standard2InvertedFlipped(model_T_camera));
1085 
1086  if (worker)
1087  {
1088  worker->executeFunction(Worker::Function::createStatic(&paintCorrespondencesSubset<tObjectPointSize, tImagePointSize>, &frame, &camera, &flippedCamera_T_model, objectPoints, imagePoints, maxSqrError, colorValidObjectPoints, colorValidImagePoints, colorInvalidObjectPoints, colorInvalidImagePoints, drawObjectPoints, drawImagePoints, drawConnections, 0u, 0u), 0u, (unsigned int)correspondences);
1089  }
1090  else
1091  {
1092  paintCorrespondencesSubset<tObjectPointSize, tImagePointSize>(&frame, &camera, &flippedCamera_T_model, objectPoints, imagePoints, maxSqrError, colorValidObjectPoints, colorValidImagePoints, colorInvalidObjectPoints, colorInvalidImagePoints, drawObjectPoints, drawImagePoints, drawConnections, 0u, (unsigned int)correspondences);
1093  }
1094 }
1095 
1096 inline void Utilities::paintPoints(Frame& frame, const HomogenousMatrix4& world_T_camera, const PinholeCamera& pinholeCamera, const Vector3* objectPoints, const size_t numberObjectPoints, const Vector2* imagePoints, const size_t numberImagePoints, const bool distortProjectedObjectPoints, const unsigned int radiusObjectPoints, const unsigned int radiusImagePoints, const uint8_t* colorObjectPoints, const uint8_t* colorImagePoints)
1097 {
1098  paintPointsIF(frame, PinholeCamera::standard2InvertedFlipped(world_T_camera), pinholeCamera, objectPoints, numberObjectPoints, imagePoints, numberImagePoints, distortProjectedObjectPoints, radiusObjectPoints, radiusImagePoints, colorObjectPoints, colorImagePoints);
1099 }
1100 
1101 inline void Utilities::paintQuads(Frame& frame, const HomogenousMatrix4& world_T_camera, const AnyCamera& camera, const Vector3& quadOrigin, const Vector3& quadHorizontal, const Vector3& quadVertical, const unsigned int horizontalBins, const unsigned int verticalBins, const uint8_t* color)
1102 {
1103  paintQuadsIF(frame, AnyCamera::standard2InvertedFlipped(world_T_camera), camera, quadOrigin, quadHorizontal, quadVertical, horizontalBins, verticalBins, color);
1104 }
1105 
1106 template <unsigned int tSize>
1107 void inline Utilities::paintTriangleIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const Triangle3& triangle, const uint8_t* color)
1108 {
1109  paintTrianglesIFSubset<tSize>(&frame, &flippedCamera_T_world, &anyCamera, &triangle, color, 0u, 1u);
1110 }
1111 
1112 template <unsigned int tSize>
1113 void Utilities::paintTrianglesIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const Triangle3* triangles, const size_t numberTriangles, const uint8_t* color, Worker* worker)
1114 {
1115  if (numberTriangles == 0)
1116  {
1117  return;
1118  }
1119 
1120  if (worker)
1121  {
1122  worker->executeFunction(Worker::Function::createStatic(&paintTrianglesIFSubset<tSize>, &frame, &flippedCamera_T_world, &anyCamera, triangles, color, 0u, 0u), 0u, (unsigned int)(numberTriangles));
1123  }
1124  else
1125  {
1126  paintTrianglesIFSubset<tSize>(&frame, &flippedCamera_T_world, &anyCamera, triangles, color, 0u, (unsigned int)(numberTriangles));
1127  }
1128 }
1129 
1130 inline void Utilities::paintLinesSubset(Frame* frame, const Vector2* startPositions, const Vector2* stopPositions, const uint8_t* color, const bool subPixel, const Vector2* offsetStartPositions, const Vector2* offsetStopPositions, const unsigned int firstLine, const unsigned int numberLines)
1131 {
1132  ocean_assert(frame != nullptr);
1133  ocean_assert(startPositions != nullptr && stopPositions != nullptr);
1134  ocean_assert(offsetStartPositions != nullptr && offsetStopPositions != nullptr);
1135 
1136  for (unsigned int n = firstLine; n < firstLine + numberLines; ++n)
1137  {
1138  paintLine(*frame, startPositions[n] + *offsetStartPositions, stopPositions[n] + *offsetStopPositions, color, subPixel);
1139  }
1140 }
1141 
1142 template <unsigned int tSize>
1143 inline void Utilities::paintLinesSubset(Frame* frame, const Vector2* startPositions, const Vector2* stopPositions, const uint8_t* color, const unsigned int firstLine, const unsigned int numberLines)
1144 {
1145  ocean_assert(frame && startPositions && stopPositions);
1146 
1147  for (unsigned int n = firstLine; n < firstLine + numberLines; ++n)
1148  {
1149  CV::Canvas::line<tSize>(*frame, startPositions[n].x(), startPositions[n].y(), stopPositions[n].x(), stopPositions[n].y(), color);
1150  }
1151 }
1152 
1153 template <unsigned int tSizeForeground, unsigned int tSizeBackground>
1154 inline void Utilities::paintLinesSubset(Frame* frame, const Vector2* startPositions, const Vector2* stopPositions, const uint8_t* colorForeground, const uint8_t* colorBackground, const unsigned int firstLine, const unsigned int numberLines)
1155 {
1156  static_assert(tSizeForeground < tSizeBackground, "Invalid line size");
1157  ocean_assert(frame && startPositions && stopPositions);
1158 
1159  for (unsigned int n = firstLine; n < firstLine + numberLines; ++n)
1160  {
1161  CV::Canvas::line<tSizeBackground>(*frame, startPositions[n].x(), startPositions[n].y(), stopPositions[n].x(), stopPositions[n].y(), colorBackground);
1162  CV::Canvas::line<tSizeForeground>(*frame, startPositions[n].x(), startPositions[n].y(), stopPositions[n].x(), stopPositions[n].y(), colorForeground);
1163  }
1164 }
1165 
1166 template <unsigned int tSize>
1167 inline void Utilities::paintPathsSubset(Frame* frame, const Vectors2* paths, const uint8_t* color, const unsigned int firstPath, const unsigned int numberPaths)
1168 {
1169  static_assert(tSize % 2u == 1u, "Invalid size parameter.");
1170 
1171  ocean_assert(frame != nullptr);
1172 
1173  for (unsigned int n = firstPath; n < firstPath + numberPaths; ++n)
1174  {
1175  const Vectors2& path = paths[n];
1176 
1177  for (size_t i = 1; i < path.size(); ++i)
1178  {
1179  CV::Canvas::line<tSize>(*frame, path[i - 1], path[i], color);
1180  }
1181  }
1182 }
1183 
1184 template <unsigned int tSize>
1185 inline void Utilities::paintPathsAdvancedSubset(Frame* frame, const Vectors2* paths, const uint8_t* color0, const uint8_t* color1, const Scalar* factors, const unsigned int firstPath, const unsigned int numberPaths)
1186 {
1187  static_assert(tSize % 2u == 1u, "Invalid size parameter.");
1188 
1189  ocean_assert(frame != nullptr);
1190 
1191  std::vector<uint8_t> color(frame->channels());
1192 
1193  for (unsigned int n = firstPath; n < firstPath + numberPaths; ++n)
1194  {
1195  Numeric::isInsideRange(0, factors[n], 1);
1196 
1197  for (unsigned int c = 0u; c < frame->channels(); ++c)
1198  {
1199  color[c] = uint8_t(Scalar(color0[c]) * (1 - factors[n]) + Scalar(color1[c]) * factors[n]);
1200  }
1201 
1202  const Vectors2& path = paths[n];
1203 
1204  for (size_t i = 1; i < path.size(); ++i)
1205  {
1206  CV::Canvas::line<tSize>(*frame, path[i - 1], path[i], color.data());
1207  }
1208  }
1209 }
1210 
1211 template <unsigned int tSize>
1212 inline void Utilities::paintTrianglesSubset(Frame* frame, const Triangle2* triangles, const uint8_t* color, const unsigned int firstTriangle, const unsigned int numberTriangles)
1213 {
1214  static_assert(tSize % 2u == 1u, "Invalid line width!");
1215 
1216  ocean_assert(frame && triangles);
1217 
1218  for (unsigned int n = firstTriangle; n < firstTriangle + numberTriangles; ++n)
1219  {
1220  const Triangle2& triangle = triangles[n];
1221  ocean_assert(triangle.isValid());
1222 
1223  CV::Canvas::line<tSize>(*frame, triangle.point0().x(), triangle.point0().y(), triangle.point1().x(), triangle.point1().y(), color);
1224  CV::Canvas::line<tSize>(*frame, triangle.point1().x(), triangle.point1().y(), triangle.point2().x(), triangle.point2().y(), color);
1225  CV::Canvas::line<tSize>(*frame, triangle.point2().x(), triangle.point2().y(), triangle.point0().x(), triangle.point0().y(), color);
1226  }
1227 }
1228 
1229 template <unsigned int tSize>
1230 inline void Utilities::paintTrianglesIFSubset(Frame* frame, const HomogenousMatrix4* flippedCamera_T_world, const AnyCamera* anyCamera, const Triangle3* triangles, const uint8_t* color, const unsigned int firstTriangle, const unsigned int numberTriangles)
1231 {
1232  static_assert(tSize % 2u == 1u, "Invalid line width!");
1233 
1234  ocean_assert(frame != nullptr && flippedCamera_T_world != nullptr && anyCamera != nullptr && triangles != nullptr);
1235 
1236  for (unsigned int n = firstTriangle; n < firstTriangle + numberTriangles; ++n)
1237  {
1238  if (AnyCamera::isObjectPointInFrontIF(*flippedCamera_T_world, triangles[n].point0()) && AnyCamera::isObjectPointInFrontIF(*flippedCamera_T_world, triangles[n].point1()) && AnyCamera::isObjectPointInFrontIF(*flippedCamera_T_world, triangles[n].point2()))
1239  {
1240  const Vector2 imagePoint0 = anyCamera->projectToImageIF(*flippedCamera_T_world, triangles[n][0]);
1241  const Vector2 imagePoint1 = anyCamera->projectToImageIF(*flippedCamera_T_world, triangles[n][1]);
1242  const Vector2 imagePoint2 = anyCamera->projectToImageIF(*flippedCamera_T_world, triangles[n][2]);
1243 
1244  CV::Canvas::line<tSize>(*frame, imagePoint0.x(), imagePoint0.y(), imagePoint1.x(), imagePoint1.y(), color);
1245  CV::Canvas::line<tSize>(*frame, imagePoint1.x(), imagePoint1.y(), imagePoint2.x(), imagePoint2.y(), color);
1246  CV::Canvas::line<tSize>(*frame, imagePoint2.x(), imagePoint2.y(), imagePoint0.x(), imagePoint0.y(), color);
1247  }
1248  }
1249 }
1250 
1251 template <unsigned int tPointSize>
1252 inline void Utilities::paintImagePointsSubset(Frame* frame, const Vector2* imagePoints, const uint8_t* color, const unsigned int firstImagePoint, const unsigned int numberImagePoints)
1253 {
1254  static_assert(tPointSize % 2u == 1u, "Invalid point size!");
1255 
1256  ocean_assert(frame != nullptr && imagePoints != nullptr);
1257 
1258  for (unsigned int n = firstImagePoint; n < firstImagePoint + numberImagePoints; ++n)
1259  {
1260  CV::Canvas::point<tPointSize>(*frame, imagePoints[n], color);
1261  }
1262 }
1263 
1264 template <unsigned int tPointSize>
1265 inline void Utilities::paintObjectPointsSubset(Frame* frame, const AnyCamera* anyCamera, const HomogenousMatrix4* flippedCamera_T_world, const Vector3* objectPoints, const uint8_t* color, const unsigned int firstObjectPoint, const unsigned int numberObjectPoints)
1266 {
1267  static_assert(tPointSize % 2u == 1u, "Invalid point size!");
1268 
1269  ocean_assert(frame != nullptr && anyCamera != nullptr && flippedCamera_T_world != nullptr && objectPoints != nullptr);
1270 
1271  for (unsigned int n = firstObjectPoint; n < firstObjectPoint + numberObjectPoints; ++n)
1272  {
1273  if (AnyCamera::isObjectPointInFrontIF(*flippedCamera_T_world, objectPoints[n]))
1274  {
1275  const Vector2 projectedObjectPoint(anyCamera->projectToImageIF(*flippedCamera_T_world, objectPoints[n]));
1276 
1277  CV::Canvas::point<tPointSize>(*frame, projectedObjectPoint, color);
1278  }
1279  }
1280 }
1281 
1282 template <unsigned int tChannels>
1283 inline void Utilities::paintFeaturePoints8BitPerChannelSubset(uint8_t* frame, const unsigned int width, const unsigned int height, const Vector2* positions, const Scalar* radii, const Scalar* orientations, const uint8_t* color, const uint8_t* shadowColor, const Scalar offsetX, const Scalar offsetY, const unsigned int framePaddingElements, const unsigned int firstFeaturePoint, const unsigned int numberFeaturePoints)
1284 {
1285  ocean_assert(frame && width != 0u && height != 0u);
1286  ocean_assert(positions && radii && orientations && color);
1287 
1288  for (unsigned int n = firstFeaturePoint; n < firstFeaturePoint + numberFeaturePoints; ++n)
1289  {
1290  paintFeaturePoint8BitPerChannel<tChannels>(frame, width, height, positions[n] + Vector2(offsetX, offsetY), radii[n], orientations[n], color, shadowColor, framePaddingElements);
1291  }
1292 }
1293 
1294 template <unsigned int tObjectPointSize, unsigned int tImagePointSize>
1295 void Utilities::paintCorrespondencesSubset(Frame* frame, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_model, const Vector3* objectPoints, const Vector2* imagePoints, const Scalar maxSqrError, const uint8_t* colorValidObjectPoints, const uint8_t* colorValidImagePoints, const uint8_t* colorInvalidObjectPoints, const uint8_t* colorInvalidImagePoints, const bool drawObjectPoints, const bool drawImagePoints, const bool drawConnections, const unsigned int firstCorrespondence, const unsigned int numberCorrespondences)
1296 {
1297  static_assert(tObjectPointSize >= tImagePointSize, "Invalid point size!");
1298  static_assert(tObjectPointSize % 2u == 1u, "Invalid point size!");
1299  static_assert(tImagePointSize % 2u == 1u, "Invalid point size!");
1300 
1301  ocean_assert(frame != nullptr && camera != nullptr && flippedCamera_T_model != nullptr && objectPoints != nullptr && imagePoints != nullptr );
1302 
1303  for (unsigned int n = firstCorrespondence; n < firstCorrespondence + numberCorrespondences; ++n)
1304  {
1305  const Vector2 projectedObjectPoint(camera->projectToImageIF(*flippedCamera_T_model, objectPoints[n]));
1306 
1307  const Scalar sqrDistance = imagePoints[n].sqrDistance(projectedObjectPoint);
1308 
1309  const uint8_t* colorObjectPoint = (sqrDistance <= maxSqrError) ? colorValidObjectPoints : colorInvalidObjectPoints;
1310  const uint8_t* colorImagePoint = (sqrDistance <= maxSqrError) ? colorValidImagePoints : colorInvalidImagePoints;
1311 
1312  if (drawObjectPoints)
1313  {
1314  CV::Canvas::point<tObjectPointSize>(*frame, projectedObjectPoint, colorObjectPoint);
1315  }
1316 
1317  if (drawConnections && sqrDistance > 2 * 2)
1318  {
1319  CV::Canvas::line<1u>(*frame, projectedObjectPoint, imagePoints[n], colorImagePoint);
1320  }
1321 
1322  if (drawImagePoints)
1323  {
1324  CV::Canvas::point<tImagePointSize>(*frame, imagePoints[n], colorImagePoint);
1325  }
1326  }
1327 }
1328 
1329 template <unsigned int tBlendChannel, unsigned int tChannels>
1330 inline void Utilities::blendPixel(uint8_t* pixel, const uint8_t blendFactor)
1331 {
1332  static_assert(tBlendChannel < tChannels, "Invalid blend channel!");
1333 
1334  ocean_assert(pixel);
1335 
1336  if (blendFactor == 0xFF)
1337  {
1338  for (unsigned int n = 0u; n < tChannels; ++n)
1339  {
1340  if (n == tBlendChannel)
1341  {
1342  pixel[n] = 0xFF;
1343  }
1344  else
1345  {
1346  pixel[n] >>= 1;
1347  }
1348  }
1349  }
1350 }
1351 
1352 }
1353 
1354 }
1355 
1356 #endif // META_OCEAN_TRACKING_UTILITIES_H
This class implements the abstract base class for all AnyCamera objects.
Definition: AnyCamera.h:130
virtual unsigned int width() const =0
Returns the width of the camera image.
virtual VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const =0
Projects a 3D object point into the camera frame.
virtual unsigned int height() const =0
Returns the height of the camera image.
virtual bool isValid() const =0
Returns whether this camera is valid.
static bool line(Frame &frame, const int xStart, const int yStart, const int xEnd, const int yEnd, const uint8_t *value=nullptr)
Paints a line with specified start and end position with pixel accuracy.
static const uint8_t * yellow(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a yellow color.
static Caller< void > createStatic(typename StaticFunctionPointerMaker< void, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass >::Type function)
Creates a new caller container for a static function with no function parameter.
Definition: Caller.h:2876
static HomogenousMatrixT4< U > standard2InvertedFlipped(const HomogenousMatrixT4< U > &world_T_camera)
Transforms a standard homogenous 4x4 viewing (extrinsic camera) matrix into an inverted and flipped c...
Definition: Camera.h:734
static bool isObjectPointInFrontIF(const HomogenousMatrixT4< T > &flippedCamera_T_world, const VectorT3< T > &objectPoint, const T epsilon=NumericT< T >::eps())
Determines whether a given 3D object point lies in front of a camera while the location of the camera...
Definition: Camera.h:811
This class implements a (possibly truncated) 3D cone.
Definition: Cone3.h:59
This class implements a 3D cylinder defined by its origin, axis, radius, and (signed) starting and st...
Definition: Cylinder3.h:80
This class implements Ocean's image class.
Definition: Frame.h:1760
T * data(const unsigned int planeIndex=0u)
Returns a pointer to the pixel data of a specific plane.
Definition: Frame.h:4127
bool isValid() const
Returns whether this frame is valid.
Definition: Frame.h:4416
PixelFormat
Definition of all pixel formats available in the Ocean framework.
Definition: Frame.h:183
@ FORMAT_UNDEFINED
Undefined pixel format.
Definition: Frame.h:187
unsigned int width() const
Returns the width of the frame format in pixel.
Definition: Frame.h:3111
unsigned int height() const
Returns the height of the frame in pixel.
Definition: Frame.h:3116
unsigned int channels() const
Returns the number of individual channels the frame has.
Definition: Frame.h:3141
This class implements an input bitstream.
Definition: Bitstream.h:51
This class implements an output bitstream.
Definition: Bitstream.h:168
std::vector< unsigned char > Buffer
Definition of a vector holding bytes.
Definition: Maintenance.h:41
static constexpr T pi2()
Returns 2*PI which is equivalent to 360 degree.
Definition: Numeric.h:932
static constexpr bool isInsideRange(const T lower, const T value, const T upper, const T epsilon=NumericT< T >::eps())
Returns whether a value lies between a given range up to a provided epsilon border.
Definition: Numeric.h:2872
static constexpr int32_t round32(const T value)
Returns the rounded 32 bit integer value of a given value.
Definition: Numeric.h:2064
static constexpr T eps()
Returns a small epsilon.
This class implements a database for 3D object points, 2D image points and 6DOF camera poses.
Definition: Database.h:67
This class implements utility functions allowing e.g., for a more comfortable visualization of tracki...
Definition: tracking/Utilities.h:46
static bool readCamera(IO::InputBitstream &inputStream, PinholeCamera &pinholeCamera)
Reads a camera profile from a binary input stream.
static void paintTriangles(Frame &frame, const Triangles2 &triangles, const uint8_t *color=nullptr, Worker *worker=nullptr)
Paints a set of 2D triangles into a given frame with sub-pixel accuracy.
Definition: tracking/Utilities.h:956
static void paintPaths(Frame &frame, const Vectors2 *paths, const size_t size, const uint8_t *color=nullptr, Worker *worker=nullptr)
Paints several paths into a given frame with sub-pixel accuracy.
Definition: tracking/Utilities.h:914
static void paintTrianglesIF(Frame &frame, const HomogenousMatrix4 &flippedCamera_T_world, const AnyCamera &anyCamera, const Triangle3 *triangles, const size_t numberTriangles, const uint8_t *color=nullptr, Worker *worker=nullptr)
Paints (projected) 3D triangles into a given frame.
Definition: tracking/Utilities.h:1113
static void paintPathsAdvancedSubset(Frame *frame, const Vectors2 *paths, const uint8_t *color0, const uint8_t *color1, const Scalar *factors, const unsigned int firstPath, const unsigned int numberPaths)
Paints a subset of several paths into a given frame with sub-pixel accuracy.
Definition: tracking/Utilities.h:1185
static Frame paintCorrespondencesBlend(const Frame &frame0, const Frame &frame1, const Vector2 *points0, const Vector2 *points1, const size_t numberPoints, const uint8_t *rgbColor=nullptr, Worker *worker=nullptr)
Blends two corresponding frames each with a ratio of fifty percent and paints a set of given feature ...
static void paintObjectPoints(Frame &frame, const AnyCamera &anyCamera, const HomogenousMatrix4 &world_T_camera, const Vector3 *objectPoints, const size_t size, const uint8_t *color, Worker *worker=nullptr)
Paints a set of 3D object points (rather their projected 2D counterparts respectively) into a given f...
Definition: tracking/Utilities.h:994
static bool paintPlane(Frame &frame, const HomogenousMatrix4 &world_T_camera, const AnyCamera &camera, const HomogenousMatrix4 &planeTransformation, const unsigned int bins, const uint8_t *foregroundColor, const uint8_t *backgroundColor, Scalar *expansion=nullptr)
Paints a 3D plane into the frame, further the origin of the plane is painted.
static void paintImagePointsSubset(Frame *frame, const Vector2 *imagePoints, const uint8_t *color, const unsigned int firstImagePoint, const unsigned int numberImagePoints)
Paints subset of a set of 2D image points into a given frame with sub-pixel accuracy.
Definition: tracking/Utilities.h:1252
static void paintLinesSubset(Frame *frame, const Vector2 *startPositions, const Vector2 *stopPositions, const uint8_t *color, const bool subPixel, const Vector2 *offsetStartPositions, const Vector2 *offsetStopPositions, const unsigned int firstLine, const unsigned int numberLines)
Paints a subset of a set of lines into a given frame.
Definition: tracking/Utilities.h:1130
static void paintWireframeConeIF(Frame &frame, const HomogenousMatrix4 &flippedCamera_T_cone, const PinholeCamera &pinholeCamera, const Cone3 &cone, const bool distortProjectedObjectPoints=true, Worker *worker=nullptr, const uint8_t *color=CV::Canvas::yellow(), const unsigned int numCircles=6u, const unsigned int numVerticalLines=4u, const unsigned int numSamples=72u)
Paints a (projected) wire-frame cone into a given frame.
static bool alignFramesHomography(const Frame &fixedFrame, const Frame &dynamicFrame, const SquareMatrix3 &dynamic_H_fixed, Frame &result, const bool blend, Worker *worker=nullptr)
Aligns two frames connected by a given homography into one frame while the resulting frame covers the...
static void paintLineIF(Frame &frame, const HomogenousMatrix4 &flippedCamera_T_world, const AnyCamera &anyCamera, const Vector3 &objectPoint0, const Vector3 &objectPoint1, const unsigned int segments, const uint8_t *foregroundColor, const uint8_t *backgroundColor)
Paints a (projected) 3D line into a given frame.
static void paintLines(Frame &frame, const Vector2 *startPositions, const Vector2 *stopPositions, const size_t numberLines, const uint8_t *color=nullptr, Worker *worker=nullptr, const bool subPixel=true, const Vector2 &offsetStartPositions=Vector2(0, 0), const Vector2 &offsetStopPositions=Vector2(0, 0))
Paints a set of lines into a given frame.
Definition: tracking/Utilities.h:860
static Frame blendFrames(const Frame &frame0, const Frame &frame1, Worker *worker=nullptr)
Blends two given frames having the same frame type.
static Frame blendFrames(const Frame &frame0, const Frame &frame1, Vector2 &offset0, Vector2 &offset1, const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_UNDEFINED, Worker *worker=nullptr)
Blends two given frames with same pixel origin.
static void paintObjectPointsSubset(Frame *frame, const AnyCamera *anyCamera, const HomogenousMatrix4 *flippedCamera_T_world, const Vector3 *objectPoints, const uint8_t *color, const unsigned int firstObjectPoint, const unsigned int numberObjectPoints)
Paints a subset of set of 3D object points (rather their projected 2D counterparts respectively) into...
Definition: tracking/Utilities.h:1265
static bool readDatabase(IO::InputBitstream &inputStream, Database &database)
Reads a database information from a binary input stream.
static void blendPixel(uint8_t *pixel, const uint8_t blendFactor)
Paints / blends a binary 8 bit mask pixel into a given pixel with 8 bit per channel.
Definition: tracking/Utilities.h:1330
static void paintFeaturePoint8BitPerChannel(uint8_t *frame, const unsigned int width, const unsigned int height, const Vector2 &position, const Scalar radius, const Scalar orientation, const uint8_t *color, const uint8_t *shadowColor, const unsigned int framePaddingElements=0u)
Paints a feature point having a radius (a scale) and orientation.
Definition: tracking/Utilities.h:1019
static bool paintPlaneIF(Frame &frame, const HomogenousMatrix4 &flippedCamera_T_world, const AnyCamera &camera, const HomogenousMatrix4 &planeTransformation, const Scalar expansion, const unsigned int bins, const uint8_t *foregroundColor, const uint8_t *backgroundColor)
Paints a 3D plane into the frame, further the origin of the plane is painted.
static void paintPathsSubset(Frame *frame, const Vectors2 *paths, const uint8_t *color, const unsigned int firstPath, const unsigned int numberPaths)
Paints a subset of several paths into a given frame with sub-pixel accuracy.
Definition: tracking/Utilities.h:1167
static Frame paintBoundingBox(const Frame &frame, const CV::PixelBoundingBox &boundingBox, Worker *worker=nullptr)
Paints / blends a bounding box into a given frame.
static void paintFeaturePoint(Frame &frame, const Vector2 &position, const Scalar radius, const Scalar orientation, const uint8_t *color, const uint8_t *shadowColor)
Paints a feature point having a radius (a scale) and orientation.
static void paintQuads(Frame &frame, const HomogenousMatrix4 &world_T_camera, const AnyCamera &camera, const Vector3 &quadOrigin, const Vector3 &quadHorizontal, const Vector3 &quadVertical, const unsigned int horizontalBins, const unsigned int verticalBins, const uint8_t *color=nullptr)
Paints quads that are located on a 3D plane into a given frame.
Definition: tracking/Utilities.h:1101
static void paintFeaturePoints8BitPerChannel(uint8_t *frame, const unsigned int width, const unsigned int height, const Vector2 *positions, const Scalar *radii, const Scalar *orientations, const size_t size, const uint8_t *color, const uint8_t *shadowColor, const Vector2 &explicitOffset, const unsigned int framePaddingElements, Worker *worker=nullptr)
Paints feature points having a radius (a scale) and orientation.
Definition: tracking/Utilities.h:1051
static void visualizeDatabase(const Database &database, const Index32 poseId, Frame &frame, const uint8_t *colorImagePoints, const uint8_t *colorImagePointsInstable, const uint8_t *colorImagePointsStable, const unsigned int maximalPathLength=20u, const unsigned int stablePathLength=100u, const SquareMatrix3 &transformation=SquareMatrix3(true), Worker *worker=nullptr)
Visualizes image point information of a tracking database for a specific pose id.
static void paintPoints(Frame &frame, const Vector2 *imagePoints, const size_t number, const unsigned int radius, const uint8_t *colorInner=nullptr, const uint8_t *colorOuter=nullptr)
Paints a set of image points into a given frame.
static void paintQuadsIF(Frame &frame, const HomogenousMatrix4 &flippedCamera_T_world, const AnyCamera &camera, const Vector3 &quadOrigin, const Vector3 &quadHorizontal, const Vector3 &quadVertical, const unsigned int horizontalBins, const unsigned int verticalBins, const uint8_t *color=nullptr)
Paints quads that are located on a 3D plane into a given frame.
static void paintLine(Frame &frame, const Vector2 &startPosition, const Vector2 &stopPosition, const uint8_t *color=nullptr, const bool subPixel=true)
Paints a line into a given frame.
Definition: tracking/Utilities.h:848
static Frame paintMask(const Frame &frame, const Frame &mask, const uint8_t maskValue=uint8_t(0xFFu), Worker *worker=nullptr)
Paints / blends a binary 8 bit mask into a given frame with identical frame dimension.
static bool alignFramesHomographyFullCoverage(const Frame &fixedFrame, const Frame &dynamicFrame, const SquareMatrix3 &dynamic_H_fixed, Frame &result, const bool blend, Worker *worker=nullptr, unsigned int maximalWidth=16384u, const unsigned int maximalHeight=16384u, unsigned int *fixedFrameLeft=nullptr, unsigned int *fixedFrameTop=nullptr, Scalar *dynamicFrameLeft=nullptr, Scalar *dynamicFrameTop=nullptr, Frame *fullFixedFrame=nullptr, Frame *fullDynamicFrame=nullptr)
Aligns two frames connected by a given homography into one frame entirely covering the frame content ...
static void paintCorrespondences(Frame &frame, const AnyCamera &camera, const HomogenousMatrix4 &model_T_camera, const Vector3 *objectPoints, const Vector2 *imagePoints, const size_t correspondences, const Scalar maxSqrError, const uint8_t *colorValidObjectPoints, const uint8_t *colorValidImagePoints, const uint8_t *colorInvalidObjectPoints, const uint8_t *colorInvalidImagePoints, const bool drawObjectPoints=true, const bool drawImagePoints=true, const bool drawConnections=true, Worker *worker=nullptr)
Paints a set of correspondences between 2D image points and 3D object points (rather their projected ...
Definition: tracking/Utilities.h:1073
static void paintTrianglesIFSubset(Frame *frame, const HomogenousMatrix4 *flippedCamera_T_world, const AnyCamera *anyCamera, const Triangle3 *triangles, const uint8_t *color, const unsigned int firstTriangle, const unsigned int numberTriangles)
Projects and paints a subset of 3D triangles into a given frame with sub-pixel accuracy.
Definition: tracking/Utilities.h:1230
static void paintImagePoints(Frame &frame, const Vector2 *imagePoints, const size_t size, const uint8_t *color, Worker *worker=nullptr)
Paints a set of 2D image points into a given frame with sub-pixel accuracy.
Definition: tracking/Utilities.h:974
static bool writeDatabase(const Database &database, IO::OutputBitstream &outputStream)
Writes the information of a database to a given output stream as binary information.
static bool paintCorrespondencesHomography(const Frame &frame0, const Frame &frame1, const SquareMatrix3 &points1_H_points0, const Vector2 *points0, const Vector2 *points1, const size_t numberPoints, const bool fullCoverage, Frame &result, const uint8_t *foregroundColor=nullptr, const uint8_t *backgroundColor=nullptr, const uint8_t *startColor=nullptr, Worker *worker=nullptr)
Joins two corresponding frames by application of a homography and paints a set of given feature corre...
static void paintBoundingBoxIF(Frame &frame, const HomogenousMatrix4 &flippedCamera_T_world, const AnyCamera &anyCamera, const Box3 &boundingBox, const uint8_t *foregroundColor, const uint8_t *backgroundColor, const bool edgesOnly=true)
Paints a (projected) 3D axis aligned bounding box into a given frame.
static void paintCoordinateSystemIF(Frame &frame, const HomogenousMatrix4 &flippedCamera_T_world, const AnyCamera &anyCamera, const HomogenousMatrix4 &world_T_coordinateSystem, const Scalar length)
Paints a 3D coordinate system (projected) into a frame.
static void paintFeaturePoints(Frame &frame, const Vector2 *positions, const Scalar *radii, const Scalar *orientations, const size_t size, const uint8_t *color, const uint8_t *shadowColor, const Vector2 &explicitOffset=Vector2(0, 0), Worker *worker=nullptr)
Paints feature points having a radius (a scale) and orientation.
static Frame paintCorrespondencesHorizontal(const Frame &frame0, const Frame &frame1, const Vector2 *points0, const Vector2 *points1, const size_t numberPoints, const uint8_t *color=nullptr, Worker *worker=nullptr)
Joins two corresponding frames horizontally and paints a set of given feature correspondences.
static bool paintCorrespondencesOrientations(const PinholeCamera &pinholeCamera, const Frame &frame0, const Frame &frame1, const SquareMatrix3 &orientation0, const SquareMatrix3 &orientation1, const Vector2 *points0, const Vector2 *points1, const size_t numberPoints, Frame &result, const uint8_t *foregroundColor=nullptr, const uint8_t *backgroundColor=nullptr, const uint8_t *startColor=nullptr, Worker *worker=nullptr)
Joins two corresponding frames by application of their orientations and paints a set of given feature...
static void paintTriangle(Frame &frame, const Triangle2 &triangle, const uint8_t *color=nullptr)
Paints a 2D triangle into a given frame with sub-pixel accuracy.
Definition: tracking/Utilities.h:950
static Frame paintCorrespondencesVertical(const Frame &frame0, const Frame &frame1, const Vector2 *points0, const Vector2 *points1, const size_t numberPoints, const uint8_t *color=nullptr, Worker *worker=nullptr)
Joins two corresponding frames vertically and paints a set of given feature correspondences.
static void paintTrianglesSubset(Frame *frame, const Triangle2 *triangles, const uint8_t *color, const unsigned int firstTriangle, const unsigned int numberTriangles)
Paints a subset of 2D triangles into a given frame with sub-pixel accuracy.
Definition: tracking/Utilities.h:1212
static bool writeCamera(const PinholeCamera &pinholeCamera, IO::OutputBitstream &outputStream)
Writes a camera profile to a binary output stream.
static void paintWireframeCylinderIF(Frame &frame, const HomogenousMatrix4 &flippedCamera_T_cylinder, const PinholeCamera &pinholeCamera, const Cylinder3 &cylinder, const bool distortProjectedObjectPoints=true, Worker *worker=nullptr, const uint8_t *color=CV::Canvas::yellow(), const unsigned int numCircles=6u, const unsigned int numVerticalLines=4u, const unsigned int numSamples=72u)
Paints a (projected) wire-frame cylinder into a given frame.
static void paintFeaturePoints8BitPerChannelSubset(uint8_t *frame, const unsigned int width, const unsigned int height, const Vector2 *positions, const Scalar *radii, const Scalar *orientations, const uint8_t *color, const uint8_t *shadowColor, const Scalar offsetX, const Scalar offsetY, const unsigned int framePaddingElements, const unsigned int firstFeaturePoint, const unsigned int numberFeaturePoints)
Paints a subset of feature points having a radius (a scale) and orientation.
Definition: tracking/Utilities.h:1283
static void paintTriangleIF(Frame &frame, const HomogenousMatrix4 &flippedCamera_T_world, const AnyCamera &anyCamera, const Triangle3 &triangle, const uint8_t *color=nullptr)
Paints a (projected) 3D triangle into a given frame.
Definition: tracking/Utilities.h:1107
static void paintCorrespondencesSubset(Frame *frame, const AnyCamera *camera, const HomogenousMatrix4 *flippedCamera_T_model, const Vector3 *objectPoints, const Vector2 *imagePoints, const Scalar maxSqrError, const uint8_t *colorValidObjectPoints, const uint8_t *colorValidImagePoints, const uint8_t *colorInvalidObjectPoints, const uint8_t *colorInvalidImagePoints, const bool drawObjectPoints, const bool drawImagePoints, const bool drawConnections, const unsigned int firstCorrespondence, const unsigned int numberCorrespondences)
Paints a subset of a set of correspondences between 2D image points and 3D object points (rather thei...
Definition: tracking/Utilities.h:1295
static void paintPointsIF(Frame &frame, const HomogenousMatrix4 &flippedCamera_T_world, const PinholeCamera &pinholeCamera, const Vector3 *objectPoints, const size_t numberObjectPoints, const Vector2 *imagePoints, const size_t numberImagePoints, const bool distortProjectedObjectPoints, const unsigned int radiusObjectPoints, const unsigned int radiusImagePoints, const uint8_t *colorObjectPoints=nullptr, const uint8_t *colorImagePoints=nullptr)
Paints (projected) object points and image points into a given frame.
static Maintenance::Buffer encodeEnvironment(const Frame &frame, const Vectors2 &frameImagePoints, const Vectors3 &frameObjectPoints, const HomogenousMatrix4 &framePose, const Vectors3 &objectPoints)
Encodes the tracking environment composes of a frame mesh (a frame with correspondences of 2D image p...
This class implements a 2D triangle with Cartesian coordinates.
Definition: Triangle2.h:81
const VectorT2< T > & point2() const
Returns the third triangle corner.
Definition: Triangle2.h:415
const VectorT2< T > & point0() const
Returns the first triangle corner.
Definition: Triangle2.h:403
const VectorT2< T > & point1() const
Returns the second triangle corner.
Definition: Triangle2.h:409
bool isValid() const
Returns whether this triangle can provide valid barycentric coordinates (for 64 bit floating point va...
Definition: Triangle2.h:806
This class implements a 3D triangle.
Definition: Triangle3.h:80
const T & x() const noexcept
Returns the x value.
Definition: Vector2.h:698
const T & y() const noexcept
Returns the y value.
Definition: Vector2.h:710
T sqrDistance(const VectorT2< T > &right) const
Returns the square distance between this 2D position and a second 2D position.
Definition: Vector2.h:633
const T & y() const noexcept
Returns the y value.
Definition: Vector3.h:812
const T & x() const noexcept
Returns the x value.
Definition: Vector3.h:800
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
bool executeFunction(const Function &function, const unsigned int first, const unsigned int size, const unsigned int firstIndex=(unsigned int)(-1), const unsigned int sizeIndex=(unsigned int)(-1), const unsigned int minimalIterations=1u, const unsigned int threadIndex=(unsigned int)(-1))
Executes a callback function separable by two function parameters.
unsigned int sqrDistance(const char first, const char second)
Returns the square distance between two values.
Definition: base/Utilities.h:1089
uint32_t Index32
Definition of a 32 bit index value.
Definition: Base.h:84
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< Triangle2 > Triangles2
Definition of a vector holding 2D triangles.
Definition: Triangle2.h:57
VectorT3< Scalar > Vector3
Definition of a 3D vector.
Definition: Vector3.h:22
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition: Vector2.h:64
std::vector< Vector3 > Vectors3
Definition of a vector holding Vector3 objects.
Definition: Vector3.h:65
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition: Vector2.h:21
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15