Ocean
Loading...
Searching...
No Matches
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"
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
24#include "ocean/math/Box3.h"
25#include "ocean/math/Cone3.h"
30#include "ocean/math/Vector2.h"
31#include "ocean/math/Vector3.h"
32
34
35namespace Ocean
36{
37
38namespace 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 */
45class 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 outline 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 outline 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 triangle into a given frame.
483 * This function is using a triangle projection checker allowing to avoid re-projection issues when drawing triangles with camera profiles with strong distortions.
484 * @param frame The frame in which the triangles will be painted, must be valid
485 * @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
486 * @param cameraProjectionChecker The camera projection checker to be used to project the 3D triangle, must be valid
487 * @param triangle The 3D triangle to point, must be valid
488 * @param segments The number of segments each triangle edge will be composed of, with range [1, infinity)
489 * @param color The color to be used to paint the triangle edges, nullptr to use black
490 * @tparam tSize The thickness of the triangle outline in pixels, must be odd with range [1, infinity)
491 */
492 template <unsigned int tSize = 1u>
493 static void paintTriangleIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const CameraProjectionChecker& cameraProjectionChecker, const Triangle3& triangle, const size_t segments = 3, const uint8_t* color = nullptr);
494
495 /**
496 * Paints a (projected) 3D line into a given frame.
497 * @param frame The frame in which the triangle will be painted, must be valid
498 * @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
499 * @param anyCamera The camera profile defining the projection, must be valid
500 * @param objectPoint0 The start 3D object point of the 3D line, defined in world
501 * @param objectPoint1 The end 3D object point of the 3D line, defined in world
502 * @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)
503 * @param foregroundColor The foreground color of the plane, nullptr to skip the painting with the foreground color
504 * @param backgroundColor The background color of the plane, nullptr to skip the painting with the background color
505 */
506 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);
507
508 /**
509 * Paints a 3D coordinate system (projected) into a frame.
510 * 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>
511 * @param frame The frame in which the coordinate system is painted, must be valid
512 * @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
513 * @param anyCamera The camera profile that is used to render the coordinate system
514 * @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
515 * @param length The length of the three axis of the coordinate system, defined in the units of the local coordinate system (coordinateSystem)
516 */
517 static void paintCoordinateSystemIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const HomogenousMatrix4& world_T_coordinateSystem, const Scalar length);
518
519 /**
520 * Paints a 3D plane into the frame, further the origin of the plane is painted.
521 * This function determines a worthwhile expansion of the plane best matching with the scene.
522 * @param frame The frame in which the plane is painted
523 * @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
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 bins The number of bins in both direction that will be painted, with range [1, infinity)
527 * @param foregroundColor The foreground color of the plane, nullptr to skip the painting with the foreground color
528 * @param backgroundColor The background color of the plane, nullptr to skip the painting with the background color
529 * @param expansion Optional resulting plane's expansion in the scene in x-axis and y-axis defined in world coordinates, with range (0, infinity)
530 * @return True, if the plane is perpendicular to the given camera frame
531 */
532 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);
533
534 /**
535 * Paints a 3D plane into the frame, further the origin of the plane is painted.
536 * @param frame The frame in which the plane is painted
537 * @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
538 * @param camera The camera profile defining the project, must be valid
539 * @param planeTransformation The transformation having the origin on the plane and the z-axis parallel to the plane's normal
540 * @param expansion The plane's expansion for the scene in x-axis and y-axis defined in world coordinates, with range (0, infinity)
541 * @param bins The number of bins in both direction that will be painted, with range [1, infinity)
542 * @param foregroundColor The foreground color of the plane, nullptr to skip the painting with the foreground color
543 * @param backgroundColor The background color of the plane, nullptr to skip the painting with the background color
544 * @return True, if the plane is perpendicular to the given camera frame
545 */
546 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);
547
548 /**
549 * Paints quads that are located on a 3D plane into a given frame.
550 * @param frame The frame receiving the points
551 * @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
552 * @param camera The camera profile defining the projection, with dimension equal to the frame dimension
553 * @param quadOrigin Origin of the upper left quad position, defined in world
554 * @param quadHorizontal Vector starting at the quad origin and defining the horizontal direction of the quads, defined in world
555 * @param quadVertical Vector starting at the quad origin and defining the vertical direction of the quads, defined in world
556 * @param horizontalBins Number of horizontal bins that will be painted
557 * @param verticalBins Number of vertical bins that will be painted
558 * @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
559 */
560 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);
561
562 /**
563 * Paints quads that are located on a 3D plane into a given frame.
564 * @see paintQuads().
565 */
566 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);
567
568 /**
569 * Paints / blends a binary 8 bit mask into a given frame with identical frame dimension.
570 * @param frame The frame in which the mask will be painted, must be valid
571 * @param mask The binary mask frame, with frame dimension matching with the given frame, must be valid
572 * @param maskValue The mask value defining pixels which will be painted as masked, may be 0x00 or 0xFF
573 * @param worker Optional worker object to distribute the computation
574 * @return The resulting frame with blended mask
575 */
576 static Frame paintMask(const Frame& frame, const Frame& mask, const uint8_t maskValue = uint8_t(0xFFu), Worker* worker = nullptr);
577
578 /**
579 * Paints / blends a bounding box into a given frame.
580 * @param frame The frame in which the bounding box will be painted, must be valid
581 * @param boundingBox The bounding box, must be valid and must be defined inside the frame
582 * @param worker Optional worker object to distribute the computation
583 * @return The resulting frame with blended mask
584 */
585 static Frame paintBoundingBox(const Frame& frame, const CV::PixelBoundingBox& boundingBox, Worker* worker = nullptr);
586
587 /**
588 * 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).
589 * @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
590 * @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
591 * @param dynamic_H_fixed The homography transforming points defined in the fixed frame to points defined in the dynamic frame, must be valid
592 * @param result The resulting frame with aligned frames, the frame type will be adjusted/set internally
593 * @param blend True, to blend both frames; False, to overwrite each pixel for which a corresponding pixel in the dynamic frame exist
594 * @param worker Optional worker object to distribute the computation
595 * @return True, if succeeded
596 */
597 static bool alignFramesHomography(const Frame& fixedFrame, const Frame& dynamicFrame, const SquareMatrix3& dynamic_H_fixed, Frame& result, const bool blend, Worker* worker = nullptr);
598
599 /**
600 * Aligns two frames connected by a given homography into one frame entirely covering the frame content of both images.
601 * @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
602 * @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
603 * @param dynamic_H_fixed The homography transforming points defined in the fixed frame to points defined in the dynamic frame, must be valid
604 * @param result The resulting frame with aligned frames converting the image content of both frames, the frame type will be adjusted/set internally
605 * @param blend True, to blend both frames; False, to overwrite each pixel for which a corresponding pixel in the dynamic frame exist
606 * @param worker Optional worker object to distribute the computation
607 * @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)
608 * @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)
609 * @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()]
610 * @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()]
611 * @param dynamicFrameLeft Optional resulting horizontal location of the top left pixel of the dynamic frame in relation to 'fixedFrameLeft', with range (-infinity, infinity)
612 * @param dynamicFrameTop Optional resulting horizontal location of the top left pixel of the dynamic frame in relation to 'fixedFrameTop', with range (-infinity, infinity)
613 * @param fullFixedFrame Optional resulting frame covering the fixed frame only, but with same frame dimension as the resulting aligned frame
614 * @param fullDynamicFrame Optional resulting frame covering the transformed dynamic frame only, but with same frame dimension as the resulting aligned frame
615 * @return True, if succeeded
616 */
617 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);
618
619 /**
620 * Visualizes image point information of a tracking database for a specific pose id.
621 * @param database The database holding the tracking information to be visualized
622 * @param poseId The id of the pose for which the visualization will be created
623 * @param frame The frame receiving the visualization of the database
624 * @param colorImagePoints The color for feature points, ensure that one value is provided for each frame channel
625 * @param colorImagePointsInstable The color for instable paths, ensure that one value is provided for each frame channel
626 * @param colorImagePointsStable The color for stable paths, ensure that one value is provided for each frame channel
627 * @param maximalPathLength The maximal length (number of concurrent frames) of paths of feature points that will be visualized, with range [0, infinity)
628 * @param stablePathLength The length (number of concurrent frames) of paths so that they count as stable, with range [1, infinity)
629 * @param transformation The transformation matrix which will be applied to each feature point position before the position is visualized
630 * @param worker Optional worker to distribute the computation
631 */
632 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);
633
634 /**
635 * Writes a camera profile to a binary output stream.
636 * @param pinholeCamera The pinhole camera profile to be written
637 * @param outputStream The output stream receiving the information
638 * @return True, if succeeded
639 * @see readCamera().
640 */
641 static bool writeCamera(const PinholeCamera& pinholeCamera, IO::OutputBitstream& outputStream);
642
643 /**
644 * Reads a camera profile from a binary input stream.
645 * @param inputStream The input stream providing the information
646 * @param pinholeCamera The resulting pinhole camera profile
647 * @see writeCamera().
648 */
649 static bool readCamera(IO::InputBitstream& inputStream, PinholeCamera& pinholeCamera);
650
651 /**
652 * Writes the information of a database to a given output stream as binary information.
653 * @param database The database to be written
654 * @param outputStream The output stream receiving the information
655 * @return True, if succeeded
656 * @see readDatabase(), writeCamera().
657 */
658 static bool writeDatabase(const Database& database, IO::OutputBitstream& outputStream);
659
660 /**
661 * Reads a database information from a binary input stream.
662 * @param inputStream The input stream providing the information
663 * @param database The database receiving the information, the given database will cleared before the information is assigned
664 * @return True, if succeeded
665 * @see writeDatabase(), readCamera().
666 */
667 static bool readDatabase(IO::InputBitstream& inputStream, Database& database);
668
669 /**
670 * 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>
671 * @param frame The frame to encode
672 * @param frameImagePoints The image points located in the given frame
673 * @param frameObjectPoints The object points, one object point for each image point
674 * @param framePose The camera pose to encode
675 * @param objectPoints The independent object points to encode
676 * @return The encoded buffer
677 */
678 static Maintenance::Buffer encodeEnvironment(const Frame& frame, const Vectors2& frameImagePoints, const Vectors3& frameObjectPoints, const HomogenousMatrix4& framePose, const Vectors3& objectPoints);
679
680 protected:
681
682 /**
683 * Paints a subset of a set of lines into a given frame.
684 * @param frame The frame in which is drawn
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 subPixel True, to paint the lines with sub-pixel accuracy; False, to paint the lines with pixel accuracy
689 * @param offsetStartPositions The offset which will be added to each start position before painting the line, with range (-infinity, infinity)x(-infinity, infinity)
690 * @param offsetStopPositions The offset which will be added to each stop position before painting the line, with range (-infinity, infinity)x(-infinity, infinity)
691 * @param firstLine First line to be handled
692 * @param numberLines The number of lines to be handled
693 */
694 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);
695
696 /**
697 * Paints a subset of a set of lines into a given frame with sub-pixel accuracy.
698 * @param frame The frame in which is drawn, must be valid
699 * @param startPositions Start positions of the lines
700 * @param stopPositions Stop positions of the lines, each end position must have a corresponding start position
701 * @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
702 * @param firstLine First line to be handled
703 * @param numberLines The number of lines to be handled
704 * @tparam tSize The thickness of the lines in pixel, must be odd with range [1, infinity)
705 */
706 template <unsigned int tSize>
707 static inline void paintLinesSubset(Frame* frame, const Vector2* startPositions, const Vector2* stopPositions, const uint8_t* color, const unsigned int firstLine, const unsigned int numberLines);
708
709 /**
710 * Paints a subset of a set of lines into a given frame with sub-pixel accuracy.
711 * @param frame The frame in which is drawn, must be valid
712 * @param startPositions Start positions of the lines
713 * @param stopPositions Stop positions of the lines, each end position must have a corresponding start position
714 * @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
715 * @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
716 * @param firstLine First line to be handled
717 * @param numberLines The number of lines to be handled
718 * @tparam tSizeForeground The thickness of the foreground lines in pixel, must be odd with range [1, infinity)
719 * @tparam tSizeBackground The thickness of the background lines in pixel, must be odd with range (tSizeForeground, infinity)
720 */
721 template <unsigned int tSizeForeground, unsigned int tSizeBackground>
722 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);
723
724 /**
725 * Paints a subset of several paths into a given frame with sub-pixel accuracy.
726 * @param frame The frame in which the paths will be painted
727 * @param paths The individual paths to be painted
728 * @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
729 * @param firstPath The first path to handled
730 * @param numberPaths The number of paths to handle
731 * @tparam tSize The thickness of the paths in pixel, must be odd with range [1, infinity)
732 * @see paintPaths().
733 */
734 template <unsigned int tSize>
735 static inline void paintPathsSubset(Frame* frame, const Vectors2* paths, const uint8_t* color, const unsigned int firstPath, const unsigned int numberPaths);
736
737 /**
738 * Paints a subset of several paths into a given frame with sub-pixel accuracy.
739 * The colors of the paths are determined by an interpolation between two separate color values.
740 * @param frame The frame in which the paths will be painted
741 * @param paths The individual paths to be painted
742 * @param color0 The first color value, ensure that one value is provided for each frame channel
743 * @param color1 The second color value, ensure that one value is provided for each frame channel
744 * @param factors The interpolation factor, one factor for each path, with range [0, 1]
745 * @param firstPath The first path to handled
746 * @param numberPaths The number of paths to handle
747 * @tparam tSize The thickness of the paths in pixel, must be odd with range [1, infinity)
748 * @see paintPaths().
749 */
750 template <unsigned int tSize>
751 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);
752
753 /**
754 * Paints a subset of 2D triangles into a given frame with sub-pixel accuracy.
755 * @param frame The frame receiving the triangles
756 * @param triangles The triangles that will be painted
757 * @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
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 paintTrianglesSubset(Frame* frame, const Triangle2* triangles, const uint8_t* color, const unsigned int firstTriangle, const unsigned int numberTriangles);
764
765 /**
766 * Projects and paints a subset of 3D triangles into a given frame with sub-pixel accuracy.
767 * @param frame The frame in which the triangle will be painted, must be valid
768 * @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
769 * @param anyCamera The camera profile defining the projection, must be valid
770 * @param triangles The triangles that will be painted, defined in world, must be valid
771 * @param color The color to be used to paint the triangle edges, nullptr to use black
772 * @param firstTriangle The first triangle to handled
773 * @param numberTriangles The number of triangle to handle
774 * @tparam tSize The thickness of the triangle edges in pixels, must be odd with range [1, infinity)
775 */
776 template <unsigned int tSize = 1u>
777 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);
778
779 /**
780 * Paints subset of a set of 2D image points into a given frame with sub-pixel accuracy.
781 * @param frame The frame in which the image points will be painted
782 * @param imagePoints The image points which will be painted
783 * @param color The color for the image points
784 * @param firstImagePoint The first image point to handle
785 * @param numberImagePoints The number of image points to handle
786 * @tparam tPointSize The radius of the image points, must be odd with range [1, infinity)
787 */
788 template <unsigned int tPointSize>
789 static inline void paintImagePointsSubset(Frame* frame, const Vector2* imagePoints, const uint8_t* color, const unsigned int firstImagePoint, const unsigned int numberImagePoints);
790
791 /**
792 * Paints a subset of set of 3D object points (rather their projected 2D counterparts respectively) into a given frame with sub-pixel accuracy.
793 * @param frame The frame in which the projected object points will be painted
794 * @param anyCamera The camera profile defining the projection between 3D object points and camera plane, must be valid
795 * @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
796 * @param objectPoints The object points which will be projected into the camera frame
797 * @param color The color for the object points
798 * @param firstObjectPoint The first object point to handle
799 * @param numberObjectPoints The number of object points to handle
800 * @tparam tPointSize The radius of the object points, must be odd with range [1, infinity)
801 */
802 template <unsigned int tPointSize>
803 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);
804
805 /**
806 * Paints a subset of feature points having a radius (a scale) and orientation.
807 * @param frame The frame in which the feature points will be painted, must be valid
808 * @param width The width of the frame in pixel, with range (0, infinity)
809 * @param height The height of the frame in pixel, with range (0, infinity)
810 * @param positions The positions of the feature points defined in the pixel domain of the given frame, with range (-infinity, infinity)x(-infinity, infinity)
811 * @param radii The radii (scale) of the feature points in pixel, with range (0, infinity), one for each position
812 * @param orientations The orientations of the feature points as CCW angle in radian, with range [0, 2PI), one for each position
813 * @param color The color for the feature point, one value for each frame data channel
814 * @param shadowColor The outer color for the object points, one value for each frame data channel or nullptr to skip painting the shadow
815 * @param offsetX Explicit horizontal offset which will be added to every feature point location before the point is painted, with range (-infinity, infinity)
816 * @param offsetY Explicit vertical offset which will be added to every feature point location before the point is painted, with range (-infinity, infinity)
817 * @param framePaddingElements The number of padding elements at the end of each frame row, in elements, with range [0, infinity)
818 * @param firstFeaturePoint The first feature point to be handled, with range [0, 'size')
819 * @param numberFeaturePoints The number of feature points to be handled, with range [1, 'size']
820 * @tparam tChannels The number of data channels, with range [1, infinity)
821 */
822 template <unsigned int tChannels>
823 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);
824
825 /**
826 * 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.
827 * The projected object points will be painted first, followed by their corresponding image points.<br>
828 * 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.
829 * @param frame The frame in which the projected object points and image points will be painted
830 * @param camera The camera profile defining the projection between 3D object points and camera plane
831 * @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
832 * @param objectPoints The object points which will be projected into the camera frame
833 * @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
834 * @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)
835 * @param colorValidObjectPoints The color for valid object points
836 * @param colorValidImagePoints The color for valid object points
837 * @param colorInvalidObjectPoints The color for invalid object points
838 * @param colorInvalidImagePoints The color for invalid image points
839 * @param drawObjectPoints True, to draw the object points
840 * @param drawImagePoints True, to draw the image points
841 * @param drawConnections True, to draw the connections between projected object points and the corresponding image points
842 * @param firstCorrespondence The first correspondence to handle
843 * @param numberCorrespondences The number of correspondences to handle
844 * @tparam tObjectPointSize The radius of the object points, must be odd with range [tImagePointSize, infinity)
845 * @tparam tImagePointSize The radius of the image points, must be odd, with range [1, infinity)
846 * @see paintCorrespondences().
847 */
848 template <unsigned int tObjectPointSize, unsigned int tImagePointSize>
849 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);
850
851 /**
852 * Paints / blends a binary 8 bit mask pixel into a given pixel with 8 bit per channel.
853 * @param pixel The pixel data which will receive the mask
854 * @param blendFactor The blend factor for the given pixel
855 * @tparam tBlendChannel The index of the data channel which will be blended, with range [0, tChannels)
856 * @tparam tChannels The number of data channels of the given pixel
857 */
858 template <unsigned int tBlendChannel, unsigned int tChannels>
859 static inline void blendPixel(uint8_t* pixel, const uint8_t blendFactor);
860};
861
862inline void Utilities::paintLine(Frame& frame, const Vector2& startPosition, const Vector2& stopPosition, const uint8_t* color, const bool subPixel)
863{
864 if (subPixel)
865 {
866 CV::Canvas::line<1u>(frame, startPosition.x(), startPosition.y(), stopPosition.x(), stopPosition.y(), color);
867 }
868 else
869 {
870 CV::Canvas::line(frame, Numeric::round32(startPosition.x()), Numeric::round32(startPosition.y()), Numeric::round32(stopPosition.x()), Numeric::round32(stopPosition.y()), color);
871 }
872}
873
874inline 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)
875{
876 if (numberLines == 0)
877 {
878 return;
879 }
880
881 if (worker)
882 {
883 worker->executeFunction(Worker::Function::createStatic(&paintLinesSubset, &frame, startPositions, stopPositions, color, subPixel, &offsetStartPositions, &offsetStopPositions, 0u, 0u), 0u, (unsigned int)(numberLines));
884 }
885 else
886 {
887 paintLinesSubset(&frame, startPositions, stopPositions, color, subPixel, &offsetStartPositions, &offsetStopPositions, 0u, (unsigned int)(numberLines));
888 }
889}
890
891template <unsigned int tSize>
892inline void Utilities::paintLines(Frame& frame, const Vector2* startPositions, const Vector2* stopPositions, const size_t numberLines, const uint8_t* color, Worker* worker)
893{
894 if (numberLines == 0)
895 {
896 return;
897 }
898
899 if (worker)
900 {
901 worker->executeFunction(Worker::Function::createStatic(&paintLinesSubset<tSize>, &frame, startPositions, stopPositions, color, 0u, 0u), 0u, (unsigned int)numberLines);
902 }
903 else
904 {
905 paintLinesSubset<tSize>(&frame, startPositions, stopPositions, color, 0u, (unsigned int)numberLines);
906 }
907}
908
909template <unsigned int tSizeForeground, unsigned int tSizeBackground>
910inline 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)
911{
912 if (numberLines == 0)
913 {
914 return;
915 }
916
917 if (worker)
918 {
919 worker->executeFunction(Worker::Function::createStatic(&paintLinesSubset<tSizeForeground, tSizeBackground>, &frame, startPositions, stopPositions, foregroundColor, backgroundColor, 0u, 0u), 0u, (unsigned int)numberLines);
920 }
921 else
922 {
923 paintLinesSubset<tSizeForeground, tSizeBackground>(&frame, startPositions, stopPositions, foregroundColor, backgroundColor, 0u, (unsigned int)numberLines);
924 }
925}
926
927template <unsigned int tSize>
928inline void Utilities::paintPaths(Frame& frame, const Vectors2* paths, const size_t size, const uint8_t* color, Worker* worker)
929{
930 if (size == 0)
931 {
932 return;
933 }
934
935 if (worker)
936 {
937 worker->executeFunction(Worker::Function::createStatic(&paintPathsSubset<tSize>, &frame, paths, color, 0u, 0u), 0u, (unsigned int)size);
938 }
939 else
940 {
941 paintPathsSubset<tSize>(&frame, paths, color, 0u, (unsigned int)size);
942 }
943}
944
945template <unsigned int tSize>
946inline 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)
947{
948 if (size == 0)
949 {
950 return;
951 }
952
953 if (worker)
954 {
955 worker->executeFunction(Worker::Function::createStatic(&paintPathsAdvancedSubset<tSize>, &frame, paths, color0, color1, factors, 0u, 0u), 0u, (unsigned int)size);
956 }
957 else
958 {
959 paintPathsAdvancedSubset<tSize>(&frame, paths, color0, color1, factors, 0u, (unsigned int)size);
960 }
961}
962
963template <unsigned int tSize>
964void Utilities::paintTriangle(Frame& frame, const Triangle2& triangle, const uint8_t* color)
965{
966 paintTrianglesSubset<tSize>(&frame, &triangle, color, 0u, 1u);
967}
968
969template <unsigned int tSize>
970void Utilities::paintTriangles(Frame& frame, const Triangles2& triangles, const uint8_t* color, Worker* worker)
971{
972 if (triangles.empty())
973 {
974 return;
975 }
976
977 if (worker)
978 {
979 worker->executeFunction(Worker::Function::createStatic(&paintTrianglesSubset<tSize>, &frame, triangles.data(), color, 0u, 0u), 0u, (unsigned int)triangles.size());
980 }
981 else
982 {
983 paintTrianglesSubset<tSize>(&frame, triangles.data(), color, 0u, (unsigned int)triangles.size());
984 }
985}
986
987template <unsigned int tPointSize>
988inline void Utilities::paintImagePoints(Frame& frame, const Vector2* imagePoints, const size_t size, const uint8_t* color, Worker* worker)
989{
990 static_assert(tPointSize % 2u == 1u, "Invalid point size!");
991
992 if (size == 0)
993 {
994 return;
995 }
996
997 if (worker)
998 {
999 worker->executeFunction(Worker::Function::createStatic(&paintImagePointsSubset<tPointSize>, &frame, imagePoints, color, 0u, 0u), 0u, (unsigned int)size);
1000 }
1001 else
1002 {
1003 paintImagePointsSubset<tPointSize>(&frame, imagePoints, color, 0u, (unsigned int)size);
1004 }
1005}
1006
1007template <unsigned int tPointSize>
1008inline 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)
1009{
1010 static_assert(tPointSize % 2u == 1u, "Invalid point size!");
1011
1012 ocean_assert(frame.isValid() && anyCamera.isValid());
1013 ocean_assert(frame.width() == anyCamera.width() && frame.height() == anyCamera.height());
1014
1015 if (size == 0)
1016 {
1017 return;
1018 }
1019
1020 const HomogenousMatrix4 flippedCamera_T_world(AnyCamera::standard2InvertedFlipped(world_T_camera));
1021
1022 if (worker)
1023 {
1024 worker->executeFunction(Worker::Function::createStatic(&paintObjectPointsSubset<tPointSize>, &frame, &anyCamera, &flippedCamera_T_world, objectPoints, color, 0u, 0u), 0u, (unsigned int)(size));
1025 }
1026 else
1027 {
1028 paintObjectPointsSubset<tPointSize>(&frame, &anyCamera, &flippedCamera_T_world, objectPoints, color, 0u, (unsigned int)(size));
1029 }
1030}
1031
1032template <unsigned int tChannels>
1033void 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)
1034{
1035 ocean_assert(frame && width != 0u && height != 0u && color);
1036 ocean_assert(radius >= Numeric::eps() && orientation >= 0 && orientation <= Numeric::pi2());
1037
1038 const Quaternion rotation(Vector3(0, 0, 1), orientation);
1039
1040 const Vector3 direction = rotation * Vector3(radius, 0, 0);
1041 const Vector3 leftTop = rotation * Vector3(-radius, -radius, 0);
1042 const Vector3 rightTop = rotation * Vector3(radius, -radius, 0);
1043 const Vector3 rightBottom = rotation * Vector3(radius, radius, 0);
1044 const Vector3 leftBottom = rotation * Vector3(-radius, radius, 0);
1045
1046 if (shadowColor)
1047 {
1048 CV::Canvas::line8BitPerChannel<tChannels, 3u>(frame, width, height, position.x(), position.y(), position.x() + direction.x(), position.y() + direction.y(), shadowColor, framePaddingElements);
1049
1050 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);
1051 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);
1052 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);
1053 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);
1054 }
1055
1056 CV::Canvas::line8BitPerChannel<tChannels, 1u>(frame, width, height, position.x(), position.y(), position.x() + direction.x(), position.y() + direction.y(), color, framePaddingElements);
1057
1058 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);
1059 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);
1060 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);
1061 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);
1062}
1063
1064template <unsigned int tChannels>
1065inline 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)
1066{
1067 static_assert(tChannels != 0u, "Invalid channel number!");
1068
1069 ocean_assert(frame && width != 0u && height != 0u);
1070
1071 if (size == 0)
1072 {
1073 return;
1074 }
1075
1076 if (worker)
1077 {
1078 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);
1079 }
1080 else
1081 {
1082 paintFeaturePoints8BitPerChannelSubset<tChannels>(frame, width, height, positions, radii, orientations, color, shadowColor, explicitOffset.x(), explicitOffset.y(), framePaddingElements, 0u, (unsigned int)(size));
1083 }
1084}
1085
1086template <unsigned int tObjectPointSize, unsigned int tImagePointSize>
1087inline 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)
1088{
1089 static_assert(tObjectPointSize >= tImagePointSize, "Invalid point size!");
1090 static_assert(tObjectPointSize % 2u == 1u, "Invalid point size!");
1091 static_assert(tImagePointSize % 2u == 1u, "Invalid point size!");
1092
1093 if (correspondences == 0)
1094 {
1095 return;
1096 }
1097
1098 const HomogenousMatrix4 flippedCamera_T_model(AnyCamera::standard2InvertedFlipped(model_T_camera));
1099
1100 if (worker)
1101 {
1102 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);
1103 }
1104 else
1105 {
1106 paintCorrespondencesSubset<tObjectPointSize, tImagePointSize>(&frame, &camera, &flippedCamera_T_model, objectPoints, imagePoints, maxSqrError, colorValidObjectPoints, colorValidImagePoints, colorInvalidObjectPoints, colorInvalidImagePoints, drawObjectPoints, drawImagePoints, drawConnections, 0u, (unsigned int)correspondences);
1107 }
1108}
1109
1110inline 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)
1111{
1112 paintPointsIF(frame, PinholeCamera::standard2InvertedFlipped(world_T_camera), pinholeCamera, objectPoints, numberObjectPoints, imagePoints, numberImagePoints, distortProjectedObjectPoints, radiusObjectPoints, radiusImagePoints, colorObjectPoints, colorImagePoints);
1113}
1114
1115inline 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)
1116{
1117 paintQuadsIF(frame, AnyCamera::standard2InvertedFlipped(world_T_camera), camera, quadOrigin, quadHorizontal, quadVertical, horizontalBins, verticalBins, color);
1118}
1119
1120template <unsigned int tSize>
1121void inline Utilities::paintTriangleIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const AnyCamera& anyCamera, const Triangle3& triangle, const uint8_t* color)
1122{
1123 paintTrianglesIFSubset<tSize>(&frame, &flippedCamera_T_world, &anyCamera, &triangle, color, 0u, 1u);
1124}
1125
1126template <unsigned int tSize>
1127void 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)
1128{
1129 if (numberTriangles == 0)
1130 {
1131 return;
1132 }
1133
1134 if (worker)
1135 {
1136 worker->executeFunction(Worker::Function::createStatic(&paintTrianglesIFSubset<tSize>, &frame, &flippedCamera_T_world, &anyCamera, triangles, color, 0u, 0u), 0u, (unsigned int)(numberTriangles));
1137 }
1138 else
1139 {
1140 paintTrianglesIFSubset<tSize>(&frame, &flippedCamera_T_world, &anyCamera, triangles, color, 0u, (unsigned int)(numberTriangles));
1141 }
1142}
1143
1144template <unsigned int tSize>
1145void Utilities::paintTriangleIF(Frame& frame, const HomogenousMatrix4& flippedCamera_T_world, const CameraProjectionChecker& cameraProjectionChecker, const Triangle3& triangle, const size_t segments, const uint8_t* color)
1146{
1147 ocean_assert(frame.isValid());
1148 ocean_assert(flippedCamera_T_world.isValid());
1149 ocean_assert(cameraProjectionChecker.isValid());
1150 ocean_assert(triangle.isValid());
1151 ocean_assert(segments >= 1);
1152
1153 for (unsigned int nSide = 0u; nSide < 3u; ++nSide)
1154 {
1155 const Vector3& point0 = triangle[nSide];
1156 const Vector3& point1 = triangle[(nSide + 1u) % 3u];
1157
1158 Vector2 previousImagePoint = Vector2::minValue();
1159
1160 if (!cameraProjectionChecker.projectToImageIF(flippedCamera_T_world, point0, &previousImagePoint))
1161 {
1162 ocean_assert(previousImagePoint == Vector2::minValue());
1163 }
1164
1165 for (size_t nSegment = 0; nSegment < segments; ++nSegment)
1166 {
1167 const Scalar factor = Scalar(nSegment + 1) / Scalar(segments);
1168
1169 const Vector3 currentPoint = point0 * (Scalar(1) - factor) + point1 * factor;
1170
1171 Vector2 currentImagePoint = Vector2::minValue();
1172 if (cameraProjectionChecker.projectToImageIF(flippedCamera_T_world, currentPoint, &currentImagePoint))
1173 {
1174 if (previousImagePoint != Vector2::minValue())
1175 {
1176 CV::Canvas::line<tSize>(frame, previousImagePoint, currentImagePoint, color);
1177 }
1178 }
1179
1180 previousImagePoint = currentImagePoint;
1181 }
1182 }
1183}
1184
1185inline 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)
1186{
1187 ocean_assert(frame != nullptr);
1188 ocean_assert(startPositions != nullptr && stopPositions != nullptr);
1189 ocean_assert(offsetStartPositions != nullptr && offsetStopPositions != nullptr);
1190
1191 for (unsigned int n = firstLine; n < firstLine + numberLines; ++n)
1192 {
1193 paintLine(*frame, startPositions[n] + *offsetStartPositions, stopPositions[n] + *offsetStopPositions, color, subPixel);
1194 }
1195}
1196
1197template <unsigned int tSize>
1198inline void Utilities::paintLinesSubset(Frame* frame, const Vector2* startPositions, const Vector2* stopPositions, const uint8_t* color, const unsigned int firstLine, const unsigned int numberLines)
1199{
1200 ocean_assert(frame && startPositions && stopPositions);
1201
1202 for (unsigned int n = firstLine; n < firstLine + numberLines; ++n)
1203 {
1204 CV::Canvas::line<tSize>(*frame, startPositions[n].x(), startPositions[n].y(), stopPositions[n].x(), stopPositions[n].y(), color);
1205 }
1206}
1207
1208template <unsigned int tSizeForeground, unsigned int tSizeBackground>
1209inline 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)
1210{
1211 static_assert(tSizeForeground < tSizeBackground, "Invalid line size");
1212 ocean_assert(frame && startPositions && stopPositions);
1213
1214 for (unsigned int n = firstLine; n < firstLine + numberLines; ++n)
1215 {
1216 CV::Canvas::line<tSizeBackground>(*frame, startPositions[n].x(), startPositions[n].y(), stopPositions[n].x(), stopPositions[n].y(), colorBackground);
1217 CV::Canvas::line<tSizeForeground>(*frame, startPositions[n].x(), startPositions[n].y(), stopPositions[n].x(), stopPositions[n].y(), colorForeground);
1218 }
1219}
1220
1221template <unsigned int tSize>
1222inline void Utilities::paintPathsSubset(Frame* frame, const Vectors2* paths, const uint8_t* color, const unsigned int firstPath, const unsigned int numberPaths)
1223{
1224 static_assert(tSize % 2u == 1u, "Invalid size parameter.");
1225
1226 ocean_assert(frame != nullptr);
1227
1228 for (unsigned int n = firstPath; n < firstPath + numberPaths; ++n)
1229 {
1230 const Vectors2& path = paths[n];
1231
1232 for (size_t i = 1; i < path.size(); ++i)
1233 {
1234 CV::Canvas::line<tSize>(*frame, path[i - 1], path[i], color);
1235 }
1236 }
1237}
1238
1239template <unsigned int tSize>
1240inline 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)
1241{
1242 static_assert(tSize % 2u == 1u, "Invalid size parameter.");
1243
1244 ocean_assert(frame != nullptr);
1245
1246 std::vector<uint8_t> color(frame->channels());
1247
1248 for (unsigned int n = firstPath; n < firstPath + numberPaths; ++n)
1249 {
1250 Numeric::isInsideRange(0, factors[n], 1);
1251
1252 for (unsigned int c = 0u; c < frame->channels(); ++c)
1253 {
1254 color[c] = uint8_t(Scalar(color0[c]) * (1 - factors[n]) + Scalar(color1[c]) * factors[n]);
1255 }
1256
1257 const Vectors2& path = paths[n];
1258
1259 for (size_t i = 1; i < path.size(); ++i)
1260 {
1261 CV::Canvas::line<tSize>(*frame, path[i - 1], path[i], color.data());
1262 }
1263 }
1264}
1265
1266template <unsigned int tSize>
1267inline void Utilities::paintTrianglesSubset(Frame* frame, const Triangle2* triangles, const uint8_t* color, const unsigned int firstTriangle, const unsigned int numberTriangles)
1268{
1269 static_assert(tSize % 2u == 1u, "Invalid line width!");
1270
1271 ocean_assert(frame && triangles);
1272
1273 for (unsigned int n = firstTriangle; n < firstTriangle + numberTriangles; ++n)
1274 {
1275 const Triangle2& triangle = triangles[n];
1276 ocean_assert(triangle.isValid());
1277
1278 CV::Canvas::line<tSize>(*frame, triangle.point0().x(), triangle.point0().y(), triangle.point1().x(), triangle.point1().y(), color);
1279 CV::Canvas::line<tSize>(*frame, triangle.point1().x(), triangle.point1().y(), triangle.point2().x(), triangle.point2().y(), color);
1280 CV::Canvas::line<tSize>(*frame, triangle.point2().x(), triangle.point2().y(), triangle.point0().x(), triangle.point0().y(), color);
1281 }
1282}
1283
1284template <unsigned int tSize>
1285inline 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)
1286{
1287 static_assert(tSize % 2u == 1u, "Invalid line width!");
1288
1289 ocean_assert(frame != nullptr && flippedCamera_T_world != nullptr && anyCamera != nullptr && triangles != nullptr);
1290
1291 for (unsigned int n = firstTriangle; n < firstTriangle + numberTriangles; ++n)
1292 {
1293 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()))
1294 {
1295 const Vector2 imagePoint0 = anyCamera->projectToImageIF(*flippedCamera_T_world, triangles[n][0]);
1296 const Vector2 imagePoint1 = anyCamera->projectToImageIF(*flippedCamera_T_world, triangles[n][1]);
1297 const Vector2 imagePoint2 = anyCamera->projectToImageIF(*flippedCamera_T_world, triangles[n][2]);
1298
1299 CV::Canvas::line<tSize>(*frame, imagePoint0.x(), imagePoint0.y(), imagePoint1.x(), imagePoint1.y(), color);
1300 CV::Canvas::line<tSize>(*frame, imagePoint1.x(), imagePoint1.y(), imagePoint2.x(), imagePoint2.y(), color);
1301 CV::Canvas::line<tSize>(*frame, imagePoint2.x(), imagePoint2.y(), imagePoint0.x(), imagePoint0.y(), color);
1302 }
1303 }
1304}
1305
1306template <unsigned int tPointSize>
1307inline void Utilities::paintImagePointsSubset(Frame* frame, const Vector2* imagePoints, const uint8_t* color, const unsigned int firstImagePoint, const unsigned int numberImagePoints)
1308{
1309 static_assert(tPointSize % 2u == 1u, "Invalid point size!");
1310
1311 ocean_assert(frame != nullptr && imagePoints != nullptr);
1312
1313 for (unsigned int n = firstImagePoint; n < firstImagePoint + numberImagePoints; ++n)
1314 {
1315 CV::Canvas::point<tPointSize>(*frame, imagePoints[n], color);
1316 }
1317}
1318
1319template <unsigned int tPointSize>
1320inline 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)
1321{
1322 static_assert(tPointSize % 2u == 1u, "Invalid point size!");
1323
1324 ocean_assert(frame != nullptr && anyCamera != nullptr && flippedCamera_T_world != nullptr && objectPoints != nullptr);
1325
1326 for (unsigned int n = firstObjectPoint; n < firstObjectPoint + numberObjectPoints; ++n)
1327 {
1328 if (AnyCamera::isObjectPointInFrontIF(*flippedCamera_T_world, objectPoints[n]))
1329 {
1330 const Vector2 projectedObjectPoint(anyCamera->projectToImageIF(*flippedCamera_T_world, objectPoints[n]));
1331
1332 CV::Canvas::point<tPointSize>(*frame, projectedObjectPoint, color);
1333 }
1334 }
1335}
1336
1337template <unsigned int tChannels>
1338inline 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)
1339{
1340 ocean_assert(frame && width != 0u && height != 0u);
1341 ocean_assert(positions && radii && orientations && color);
1342
1343 for (unsigned int n = firstFeaturePoint; n < firstFeaturePoint + numberFeaturePoints; ++n)
1344 {
1345 paintFeaturePoint8BitPerChannel<tChannels>(frame, width, height, positions[n] + Vector2(offsetX, offsetY), radii[n], orientations[n], color, shadowColor, framePaddingElements);
1346 }
1347}
1348
1349template <unsigned int tObjectPointSize, unsigned int tImagePointSize>
1350void 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)
1351{
1352 static_assert(tObjectPointSize >= tImagePointSize, "Invalid point size!");
1353 static_assert(tObjectPointSize % 2u == 1u, "Invalid point size!");
1354 static_assert(tImagePointSize % 2u == 1u, "Invalid point size!");
1355
1356 ocean_assert(frame != nullptr && camera != nullptr && flippedCamera_T_model != nullptr && objectPoints != nullptr && imagePoints != nullptr );
1357
1358 for (unsigned int n = firstCorrespondence; n < firstCorrespondence + numberCorrespondences; ++n)
1359 {
1360 const Vector2 projectedObjectPoint(camera->projectToImageIF(*flippedCamera_T_model, objectPoints[n]));
1361
1362 const Scalar sqrDistance = imagePoints[n].sqrDistance(projectedObjectPoint);
1363
1364 const uint8_t* colorObjectPoint = (sqrDistance <= maxSqrError) ? colorValidObjectPoints : colorInvalidObjectPoints;
1365 const uint8_t* colorImagePoint = (sqrDistance <= maxSqrError) ? colorValidImagePoints : colorInvalidImagePoints;
1366
1367 if (drawObjectPoints)
1368 {
1369 CV::Canvas::point<tObjectPointSize>(*frame, projectedObjectPoint, colorObjectPoint);
1370 }
1371
1372 if (drawConnections && sqrDistance > 2 * 2)
1373 {
1374 CV::Canvas::line<1u>(*frame, projectedObjectPoint, imagePoints[n], colorImagePoint);
1375 }
1376
1377 if (drawImagePoints)
1378 {
1379 CV::Canvas::point<tImagePointSize>(*frame, imagePoints[n], colorImagePoint);
1380 }
1381 }
1382}
1383
1384template <unsigned int tBlendChannel, unsigned int tChannels>
1385inline void Utilities::blendPixel(uint8_t* pixel, const uint8_t blendFactor)
1386{
1387 static_assert(tBlendChannel < tChannels, "Invalid blend channel!");
1388
1389 ocean_assert(pixel);
1390
1391 if (blendFactor == 0xFF)
1392 {
1393 for (unsigned int n = 0u; n < tChannels; ++n)
1394 {
1395 if (n == tBlendChannel)
1396 {
1397 pixel[n] = 0xFF;
1398 }
1399 else
1400 {
1401 pixel[n] >>= 1;
1402 }
1403 }
1404 }
1405}
1406
1407}
1408
1409}
1410
1411#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 unsigned int height() const =0
Returns the height of the camera image.
virtual VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const =0
Projects a 3D object point into the camera frame.
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 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:2877
This class implements a helper class allowing to check whether a 3D object point projects into the ca...
Definition AnyCamera.h:516
bool isValid() const
Returns whether this checker holds a valid camera model and is ready to be used.
Definition AnyCamera.h:1748
bool projectToImageIF(const HomogenousMatrixT4< T > &flippedCamera_T_world, const VectorT3< T > &objectPoint, VectorT2< T > *imagePoint=nullptr) const
Returns whether a 3D object point is located in front of the camera and projects into the camera imag...
Definition AnyCamera.h:1703
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:1808
T * data(const unsigned int planeIndex=0u)
Returns a pointer to the pixel data of a specific plane.
Definition Frame.h:4242
bool isValid() const
Returns whether this frame is valid.
Definition Frame.h:4531
PixelFormat
Definition of all pixel formats available in the Ocean framework.
Definition Frame.h:183
unsigned int width() const
Returns the width of the frame format in pixel.
Definition Frame.h:3170
unsigned int height() const
Returns the height of the frame in pixel.
Definition Frame.h:3175
unsigned int channels() const
Returns the number of individual channels the frame has.
Definition Frame.h:3200
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition HomogenousMatrix4.h:1806
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:2875
static constexpr int32_t round32(const T value)
Returns the rounded 32 bit integer value of a given value.
Definition Numeric.h:2067
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:970
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:928
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:1127
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:1240
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:1008
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:1307
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:1185
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:874
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:1320
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:1385
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:1033
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:1222
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:1115
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:1065
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:862
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:1087
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:1285
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:988
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:964
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:1267
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:1338
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:1121
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:1350
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
bool isValid() const
Returns whether this triangle is valid.
Definition Triangle3.h:580
const T & x() const noexcept
Returns the x value.
Definition Vector2.h:710
const T & y() const noexcept
Returns the y value.
Definition Vector2.h:722
static VectorT2< Scalar > minValue()
Returns a 2D vector with all elements set to NumericT::minValue().
Definition Vector2.h:926
T sqrDistance(const VectorT2< T > &right) const
Returns the square distance between this 2D position and a second 2D position.
Definition Vector2.h:645
const T & y() const noexcept
Returns the y value.
Definition Vector3.h:824
const T & x() const noexcept
Returns the x value.
Definition Vector3.h:812
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:1113
uint32_t Index32
Definition of a 32 bit index value.
Definition Base.h:84
float Scalar
Definition of a scalar type.
Definition Math.h:129
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:29
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:28
The namespace covering the entire Ocean framework.
Definition Accessor.h:15