Ocean
FrameRectification.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_CV_ADVANCED_FRAME_RECTIFICATION_H
9 #define META_OCEAN_CV_ADVANCED_FRAME_RECTIFICATION_H
10 
12 
13 #include "ocean/base/DataType.h"
14 #include "ocean/base/Frame.h"
15 #include "ocean/base/Worker.h"
16 
18 
20 #include "ocean/math/Lookup2.h"
22 #include "ocean/math/Triangle2.h"
23 #include "ocean/math/Triangle3.h"
24 
25 namespace Ocean
26 {
27 
28 namespace CV
29 {
30 
31 namespace Advanced
32 {
33 
34 /**
35  * This class implements functions creating rectified images from frame areas or objects located in a frame.
36  * @ingroup cvadvanced
37  */
38 class OCEAN_CV_ADVANCED_EXPORT FrameRectification
39 {
40  public:
41 
42  /**
43  * Definition of a lookup table storing 2D vectors as elements.
44  */
46 
47  /**
48  * The following comfort class provides comfortable functions simplifying prototyping applications but also increasing binary size of the resulting applications.
49  * Best practice is to avoid using these functions if binary size matters,<br>
50  * as for every comfort function a corresponding function exists with specialized functionality not increasing binary size significantly.<br>
51  */
52  class OCEAN_CV_ADVANCED_EXPORT Comfort
53  {
54  public:
55 
56  /**
57  * Given a camera image, a planar 3D rectangle defined in world, and a sampling resolution on the rectangle, projects the camera image onto the rectangle to create a resampled 'rectified image'.
58  * Rectified pixels lying outside the camera image will be assigned with a unique color value which can be specified.
59  * @param cameraFrame The frame that captures the 3D plane, must be valid
60  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
61  * @param world_T_camera The transformation between camera and world, with camera pointing towards the negative z-space with y-axis up, must be valid
62  * @param rectangleOrigin Origin of the planar rectangle object, defined in world
63  * @param rectangleHorizontal Vector defining the horizontal edge of the rectangle object (beginning at the origin), defined in world
64  * @param rectangleVertical Vector defining the vertical edge of the rectangle object (beginning at the origin and perpendicular to the rectangleHorizontal vector), defined in world
65  * @param rectifiedFrame The resulting rectified image, with same pixel format as 'cameraFrame', must be valid
66  * @param worker Optional worker object to distribute the computation
67  * @param outsideFrameColor Optional color that is assigned to pixels that map outside the camera frame, if nullptr is used 0x00 will be assigned to each frame channel
68  * @param approximationBinSize Optional width (and height) of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
69  * @return True, if succeeded
70  * @see arbitraryRectangleObject(), planarRectangleObjectIF8BitPerChannel().
71  */
72  static bool planarRectangleObject(const Frame& cameraFrame, const AnyCamera& camera, const HomogenousMatrix4& world_T_camera, const Vector3& rectangleOrigin, const Vector3& rectangleHorizontal, const Vector3& rectangleVertical, Frame& rectifiedFrame, Worker* worker = nullptr, const uint8_t* outsideFrameColor = nullptr, const unsigned int approximationBinSize = 0u);
73 
74  /**
75  * Given a camera image, an arbitrary 3D rectangle defined in world, and a sampling resolution on the rectangle, projects the camera image onto the rectangle to create a resampled 'rectified image'.
76  * Rectified pixels lying outside the camera image will be assigned with a unique color value which can be specified.
77  * @param cameraFrame The frame that captures the 3D plane, must be valid
78  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
79  * @param world_T_camera The transformation between camera and world, with camera pointing towards the negative z-space with y-axis up, must be valid
80  * @param rectangle0 3D position of the rectangle corresponding to the upper left corner of the resulting rectified frame, in world
81  * @param rectangle1 3D position of the rectangle corresponding to the lower left corner of the resulting rectified frame, in world
82  * @param rectangle2 3D position of the rectangle corresponding to the lower right corner of the resulting rectified frame, in world
83  * @param rectangle3 3D position of the rectangle corresponding to the upper right corner of the resulting rectified frame, in world
84  * @param rectifiedFrame The resulting rectified image, with same pixel format as 'cameraFrame', must be valid
85  * @param worker Optional worker object to distribute the computation
86  * @param outsideFrameColor Optional color that is assigned to pixels that map outside the camera frame, if nullptr is used 0x00 will be assigned to each frame channel
87  * @param approximationBinSize Optional width (and height) of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
88  * @return True, if succeeded
89  * @see planarRectangleObject(), planarRectangleObjectIF8BitPerChannel().
90  */
91  static bool arbitraryRectangleObject(const Frame& cameraFrame, const AnyCamera& camera, const HomogenousMatrix4& world_T_camera, const Vector3& rectangle0, const Vector3& rectangle1, const Vector3& rectangle2, const Vector3& rectangle3, Frame& rectifiedFrame, Worker* worker = nullptr, const uint8_t* outsideFrameColor = nullptr, const unsigned int approximationBinSize = 0u);
92 
93  /**
94  * Draws a 2D triangle into an image of a 3D triangle as seen in a camera image.
95  * Pixels lying outside the camera frame will be assigned with a unique color value which can be specified.
96  * @param cameraFrame The frame in which the triangle is visible, must be valid
97  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
98  * @param world_T_camera The transformation between camera and world, with camera pointing towards the negative z-space with y-axis up, must be valid
99  * @param triangle2 2D triangle defined in the target frame, must be valid
100  * @param triangle3 3D triangle defined in the world coordinate system, must be valid
101  * @param targetFrame The target image in which the triangle will be drawn, with same pixel format as 'cameraFrame', must be valid
102  * @param worker Optional worker object to distribute the computation
103  * @param outsideFrameColor Optional color that is assigned to pixels that map outside the camera frame, if nullptr is used 0x00 will be assigned to each frame channel
104  * @param approximationBinSize Optional width (and height) of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
105  * @return True, if succeeded
106  * @see planarRectangleObjectIF8BitPerChannel().
107  */
108  static bool triangleObject(const Frame& cameraFrame, const AnyCamera& camera, const HomogenousMatrix4& world_T_camera, const Triangle2& triangle2, const Triangle3& triangle3, Frame& targetFrame, Worker* worker = nullptr, const uint8_t* outsideFrameColor = nullptr, const unsigned int approximationBinSize = 0u);
109 
110  /**
111  * Given a camera image, a planar 3D rectangle defined in world, and a sampling resolution on the rectangle, projects the camera image onto the rectangle to create a resampled 'rectified image'.
112  * Rectified pixels lying outside the camera will be masked in the resulting mask frame.
113  * @param cameraFrame The frame that captures the 3D plane, must be valid
114  * @param camera The camera object that defines the projection and must have the same dimension as the given frame, must be valid
115  * @param world_T_camera The camera pose transforming camera to world, must be valid
116  * @param rectangleOrigin Origin of the planar rectangle object in world units
117  * @param rectangleHorizontal Vector defining the horizontal edge of the rectangle object (beginning at the origin) in world units
118  * @param rectangleVertical Vector defining the vertical edge of the rectangle object (beginning at the origin and perpendicular to the rectangleHorizontal vector) in world units
119  * @param targetFrame The resulting target image, with same pixel format as 'cameraFrame', must be valid
120  * @param targetMask The resulting mask separating target pixels which do not have corresponding camera image pixels
121  * @param worker Optional worker object to distribute the computation
122  * @param maskValue The mask value for pixels lying inside the given camera frame, pixels lying outside the camera frame will be assigned with (0xFF - maskValue)
123  * @param approximationBinSize Optional width (and height) of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
124  * @return True, if succeeded
125  * @see arbitraryRectangleObjectMask(), planarRectangleObjectMaskIF8BitPerChannel().
126  */
127  static bool planarRectangleObjectMask(const Frame& cameraFrame, const AnyCamera& camera, const HomogenousMatrix4& world_T_camera, const Vector3& rectangleOrigin, const Vector3& rectangleHorizontal, const Vector3& rectangleVertical, Frame& targetFrame, Frame& targetMask, Worker* worker = nullptr, const uint8_t maskValue = 0xFFu, const unsigned int approximationBinSize = 0u);
128 
129  /**
130  * Given a camera image, an arbitrary 3D rectangle defined in world, and a sampling resolution on the rectangle, projects the camera image onto the rectangle to create a resampled 'rectified image'.
131  * Rectified pixels lying outside the camera will be masked in the resulting mask frame.
132  * @param cameraFrame The frame that captures the 3D plane, must be valid
133  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
134  * @param world_T_camera The transformation between camera and world, with camera pointing towards the negative z-space with y-axis up, must be valid
135  * @param rectangle0 3D position of the rectangle corresponding to the upper left corner of the resulting target frame
136  * @param rectangle1 3D position of the rectangle corresponding to the lower left corner of the resulting target frame
137  * @param rectangle2 3D position of the rectangle corresponding to the lower right corner of the resulting target frame
138  * @param rectangle3 3D position of the rectangle corresponding to the upper right corner of the resulting target frame
139  * @param targetFrame The resulting target image, with same pixel format as 'cameraFrame', must be valid
140  * @param targetMask The resulting mask separating target pixels which do not have corresponding camera image pixels
141  * @param worker Optional worker object to distribute the computation
142  * @param maskValue The mask value for pixels lying inside the given camera frame, pixels lying outside the camera frame will be assigned with (0xFF - maskValue)
143  * @param approximationBinSize Optional width (and height) of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
144  * @return True, if succeeded
145  * @see planarRectangleObjectMask(), arbitraryRectangleObjectMaskIF8BitPerChannel().
146  */
147  static bool arbitraryRectangleObjectMask(const Frame& cameraFrame, const AnyCamera& camera, const HomogenousMatrix4& world_T_camera, const Vector3& rectangle0, const Vector3& rectangle1, const Vector3& rectangle2, const Vector3& rectangle3, Frame& targetFrame, Frame& targetMask, Worker* worker = nullptr, const uint8_t maskValue = 0xFFu, const unsigned int approximationBinSize = 0u);
148 
149  /**
150  * Draws a 2D triangle into an image of a 3D triangle as seen in a camera image.
151  * Pixels lying outside the camera will be masked in the resulting mask frame.
152  * @param cameraFrame The frame that captures the 3D plane, must be valid
153  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
154  * @param world_T_camera The transformation between camera and world, with camera pointing towards the negative z-space with y-axis up, must be valid
155  * @param triangle2 The 2D triangle defined in the target frame, must be valid
156  * @param triangle3 The 3D triangle defined in the world coordinate system, must be valid
157  * @param targetFrame The target image in which the triangle will be drawn, with same pixel format as 'cameraFrame', must be valid
158  * @param targetMask The resulting mask separating target pixels which do not have corresponding camera image pixels
159  * @param worker Optional worker object to distribute the computation
160  * @param maskValue The mask value for pixels lying inside the given camera frame, pixels lying outside the camera frame will be assigned with (0xFF - maskValue)
161  * @param approximationBinSize Optional width (and height) of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
162  * @return True, if succeeded
163  * @see planarRetangleObjectMaskIF8BitPerChannel().
164  */
165  static bool triangleObjectMask(const Frame& cameraFrame, const AnyCamera& camera, const HomogenousMatrix4& world_T_camera, const Triangle2& triangle2, const Triangle3& triangle3, Frame& targetFrame, Frame& targetMask, Worker* worker = nullptr, const uint8_t maskValue = 0xFFu, const unsigned int approximationBinSize = 0u);
166  };
167 
168  public:
169 
170  /**
171  * Converts the pixel position defined in the rectified frame to the pixel position defined in the camera frame inside the planar rectangle 3D object.
172  * Beware: The actual center of a pixel is located at the upper left corner of the individual pixels' squares.
173  * @param anyCamera The camera profile to be applied
174  * @param flippedCamera_T_world The inverted and flipped extrinsic camera matrix, must be valid
175  * @param rectangleOrigin Origin of the planar rectangle object in world units
176  * @param rectangleHorizontal Vector defining the horizontal edge of the 3D rectangle object (beginning at the origin) in world units
177  * @param rectangleVertical Vector defining the vertical edge of the 3D rectangle object (beginning at the origin and perpendicular to the rectangleHorizontal vector) in world units
178  * @param rectifiedWidth The width of the rectified frame in pixel, with range [1, infinity)
179  * @param rectifiedHeight The height of the rectified frame in pixel, with range [1, infinity)
180  * @param rectifiedPosition The pixel position in the rectified frame, with range [0, rectifiedWidth)x[0, rectifiedHeight)
181  * @return Resulting pixel position defined in the camera frame space, may be outside the actual frame dimension
182  * @tparam tPixelOriginUpperLeft True, if the pixel origin of the camera frame and rectified frame is in the upper left corner; False if the pixel origin is in the lower left corner
183  * @see PinholeCamera::standard2InvertedFlipped().
184  */
185  template <bool tPixelOriginUpperLeft>
186  static Vector2 planarRectangleObjectRectifiedPosition2cameraPositionIF(const AnyCamera& anyCamera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangleOrigin, const Vector3& rectangleHorizontal, const Vector3& rectangleVertical, const unsigned int rectifiedWidth, const unsigned int rectifiedHeight, const Vector2& rectifiedPosition);
187 
188  /**
189  * Given a camera image, a planar 3D rectangle defined in world, and a sampling resolution on the rectangle, projects the camera image onto the rectangle to create a resampled 'rectified image'.
190  * Rectified pixels lying outside the camera image will be assigned with a unique color value which can be specified.
191  * @param cameraFrame The frame that captures the 3D plane, must be valid
192  * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
193  * @param pixelOrigin The pixel origin of the given frame (and the resulting rectified frame)
194  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
195  * @param flippedCamera_T_world The transformation between world and flipped camera, with flipped camera pointing towards the positive z-space with y-axis down, must be valid
196  * @param rectangleOrigin Origin of the planar rectangle object in world units
197  * @param rectangleHorizontal Vector defining the horizontal edge of the 2D rectified object (beginning at the origin) in world units
198  * @param rectangleVertical Vector defining the vertical edge of the 2D rectified object (beginning at the origin and perpendicular to the rectangleHorizontal vector) in world units
199  * @param rectifiedFrame The resulting rectified image, must be valid
200  * @param rectifiedFrameWidth Width of the rectified image, in pixel, with range [1, infinity)
201  * @param rectifiedFrameHeight Height of the rectified image, in pixel, with range [1, infinity)
202  * @param rectifiedFramePaddingElements The number of padding elements at the end of each rectified frame row, in elements, with range [0, infinity)
203  * @param worker Optional worker object to distribute the computation
204  * @param outsideFrameColor Color that is assigned to pixels that map outside the camera frame, if nullptr is used 0x00 will be assigned to each frame channel
205  * @param approximationBinSize Optional width (and height) of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
206  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
207  * @see planarRectangleObject().
208  */
209  template <unsigned int tChannels>
210  static inline void planarRectangleObjectIF8BitPerChannel(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera& camera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangleOrigin, const Vector3& rectangleHorizontal, const Vector3& rectangleVertical, uint8_t* rectifiedFrame, const unsigned int rectifiedFrameWidth, const unsigned int rectifiedFrameHeight, const unsigned int rectifiedFramePaddingElements, Worker* worker = nullptr, const uint8_t* outsideFrameColor = nullptr, const unsigned int approximationBinSize = 0u);
211 
212  /**
213  * Given a camera image, an arbitrary 3D rectangle defined in world, and a sampling resolution on the rectangle, projects the camera image onto the rectangle to create a resampled 'rectified image'.
214  * Rectified pixels lying outside the camera image will be assigned with a unique color value which can be specified.
215  * @param cameraFrame The frame that captures the 3D plane, must be valid
216  * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
217  * @param pixelOrigin The pixel origin of the given frame (and the resulting rectified frame)
218  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
219  * @param flippedCamera_T_world The transformation between world and flipped camera, with flipped camera pointing towards the positive z-space with y-axis down, must be valid
220  * @param rectangle0 3D position of the rectangle corresponding to the upper left corner of the resulting rectified frame, in world
221  * @param rectangle1 3D position of the rectangle corresponding to the lower left corner of the resulting rectified frame, in world
222  * @param rectangle2 3D position of the rectangle corresponding to the lower right corner of the resulting rectified frame, in world
223  * @param rectangle3 3D position of the rectangle corresponding to the upper right corner of the resulting rectified frame, in world
224  * @param rectifiedFrame The resulting rectified image, must be valid
225  * @param rectifiedFrameWidth Width of the rectified image, in pixel, with range [1, infinity)
226  * @param rectifiedFrameHeight Height of the rectified image, in pixel, with range [1, infinity)
227  * @param rectifiedFramePaddingElements The number of padding elements at the end of each rectified frame row, in elements, with range [0, infinity)
228  * @param worker Optional worker object to distribute the computation
229  * @param outsideFrameColor Color that is assigned to pixels that map outside the camera frame, if nullptr is used 0x00 will be assigned to each frame channel
230  * @param approximationBinSize Optional width (and height) of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
231  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
232  * @see arbitraryRectangleObject().
233  */
234  template <unsigned int tChannels>
235  static inline void arbitraryRectangleObjectIF8BitPerChannel(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera& camera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangle0, const Vector3& rectangle1, const Vector3& rectangle2, const Vector3& rectangle3, uint8_t* rectifiedFrame, const unsigned int rectifiedFrameWidth, const unsigned int rectifiedFrameHeight, const unsigned int rectifiedFramePaddingElements, Worker* worker = nullptr, const uint8_t* outsideFrameColor = nullptr, const unsigned int approximationBinSize = 0u);
236 
237  /**
238  * Draws a 2D triangle into an image of a 3D triangle as seen in a camera image.
239  * Pixels lying outside the camera frame will be assigned with a unique color value which can be specified.
240  * @param cameraFrame The frame that captures the 3D plane, must be valid
241  * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
242  * @param pixelOrigin The pixel origin of the given frame (and the resulting rectified frame)
243  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
244  * @param flippedCamera_T_world The transformation between world and flipped camera, with flipped camera pointing towards the positive z-space with y-axis down, must be valid
245  * @param triangle2 2D triangle defined in the rectified frame
246  * @param triangle3 3D triangle defined in the world coordinate system
247  * @param targetFrame The target image in which the triangle will be drawn, must be valid
248  * @param targetWidth The width of the target image, in pixel, with range [1, infinity)
249  * @param targetHeight The height of the target image, in pixel, with range [1, infinity)
250  * @param targetPaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
251  * @param worker Optional worker object to distribute the computation
252  * @param outsideFrameColor Color that is assigned to pixels that map outside the camera frame, if nullptr is used 0x00 will be assigned to each frame channel
253  * @param approximationBinSize Optional width (and height) of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
254  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
255  * @see planarRectangleObject().
256  */
257  template <unsigned int tChannels>
258  static inline void triangleObjectIF8BitPerChannel(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera& camera, const HomogenousMatrix4& flippedCamera_T_world, const Triangle2& triangle2, const Triangle3& triangle3, uint8_t* targetFrame, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetPaddingElements, Worker* worker = nullptr, const uint8_t* outsideFrameColor = nullptr, const unsigned int approximationBinSize = 0u);
259 
260  /**
261  * Given a camera image, a planar 3D rectangle defined in world, and a sampling resolution on the rectangle, projects the camera image onto the rectangle to create a resampled 'rectified image'.
262  * Rectified pixels lying outside the camera will be masked in the resulting mask frame.
263  * @param cameraFrame The frame that captures the 3D plane, must be valid
264  * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
265  * @param pixelOrigin The pixel origin of the given frame (and the resulting rectified frame)
266  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
267  * @param flippedCamera_T_world The transformation between world and flipped camera, with flipped camera pointing towards the positive z-space with y-axis down, must be valid
268  * @param rectangleOrigin Origin of the planar rectangle object in world units
269  * @param rectangleHorizontal Vector defining the horizontal edge of the 2D rectified object (beginning at the origin) in world units
270  * @param rectangleVertical Vector defining the vertical edge of the 2D rectified object (beginning at the origin and perpendicular to the rectangleHorizontal vector) in world units
271  * @param targetFrame The resulting target image, must be valid
272  * @param targetMask The resulting mask, must be valid
273  * @param targetWidth Width of the target image, in pixel, with range [1, infinity)
274  * @param targetHeight Height of the target image, in pixel, with range [1, infinity)
275  * @param targetFramePaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
276  * @param targetMaskPaddingElements The number of padding elements at the end of each row target mask row, in elements, with range [0, infinity)
277  * @param worker Optional worker object to distribute the computation
278  * @param maskValue The mask value for pixels lying inside the given camera frame, pixels lying outside the camera frame will be assigned with (0xFF - maskValue)
279  * @param approximationBinSize Optional width (and height) of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
280  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
281  * @see planarRectangleObjectMask().
282  */
283  template <unsigned int tChannels>
284  static inline void planarRectangleObjectMaskIF8BitPerChannel(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera& camera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangleOrigin, const Vector3& rectangleHorizontal, const Vector3& rectangleVertical, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, Worker* worker = nullptr, const uint8_t maskValue = 0xFFu, const unsigned int approximationBinSize = 0u);
285 
286  /**
287  * Given a camera image, an arbitrary 3D rectangle defined in world, and a sampling resolution on the rectangle, projects the camera image onto the rectangle to create a resampled 'rectified image'.
288  * Rectified pixels lying outside the camera will be masked in the resulting mask frame.
289  * @param cameraFrame The frame that captures the 3D plane, must be valid
290  * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
291  * @param pixelOrigin The pixel origin of the given frame (and the resulting rectified frame)
292  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
293  * @param flippedCamera_T_world The transformation between world and flipped camera, with flipped camera pointing towards the positive z-space with y-axis down, must be valid
294  * @param rectangle0 3D position of the rectangle corresponding to the upper left corner of the resulting target frame
295  * @param rectangle1 3D position of the rectangle corresponding to the lower left corner of the resulting target frame
296  * @param rectangle2 3D position of the rectangle corresponding to the lower right corner of the resulting target frame
297  * @param rectangle3 3D position of the rectangle corresponding to the upper right corner of the resulting target frame
298  * @param targetFrame The resulting target image, must be valid
299  * @param targetMask The resulting mask, must be valid
300  * @param targetWidth Width of the target image, in pixel, with range [1, infinity)
301  * @param targetHeight Height of the target image, in pixel, with range [1, infinity)
302  * @param targetFramePaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
303  * @param targetMaskPaddingElements The number of padding elements at the end of each row target mask row, in elements, with range [0, infinity)
304  * @param worker Optional worker object to distribute the computation
305  * @param maskValue 8 bit mask values for rectified pixels lying inside the given camera frame, rectified pixels lying outside the camera frame will be assigned with (0xFF - maskValue)
306  * @param approximationBinSize Optional width (and height) of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
307  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
308  * @see planarRectangleObjectMask().
309  */
310  template <unsigned int tChannels>
311  static inline void arbitraryRectangleObjectMaskIF8BitPerChannel(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera& camera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangle0, const Vector3& rectangle1, const Vector3& rectangle2, const Vector3& rectangle3, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, Worker* worker = nullptr, const uint8_t maskValue = 0xFFu, const unsigned int approximationBinSize = 0u);
312 
313  /**
314  * Draws a 2D triangle into an image of a 3D triangle as seen in a camera image.
315  * Target pixels lying outside the camera will be masked in the resulting mask frame.
316  * @param cameraFrame The frame that captures the 3D plane, must be valid
317  * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
318  * @param pixelOrigin The pixel origin of the given frame (and the resulting rectified frame)
319  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
320  * @param flippedCamera_T_world The transformation between world and flipped camera, with flipped camera pointing towards the positive z-space with y-axis down, must be valid
321  * @param triangle2 2D triangle defined in the target frame, must be valid
322  * @param triangle3 3D triangle defined in the world coordinate system, must be valid
323  * @param targetFrame The resulting target image, must be valid
324  * @param targetMask The resulting mask, must be valid
325  * @param targetWidth Width of the target image, in pixel, with range [1, infinity)
326  * @param targetHeight Height of the target image, in pixel, with range [1, infinity)
327  * @param targetFramePaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
328  * @param targetMaskPaddingElements The number of padding elements at the end of each row target mask row, in elements, with range [0, infinity)
329  * @param worker Optional worker object to distribute the computation
330  * @param maskValue 8 bit mask values for rectified pixels lying inside the given camera frame, rectified pixels lying outside the camera frame will be assigned with (0xFF - maskValue)
331  * @param approximationBinSize Optional width (and height) of a bin in a lookup table to speedup the in interpolation in pixel, 0u to avoid the application of a lookup table
332  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
333  * @see planarRectangleObjectMask().
334  */
335  template <unsigned int tChannels>
336  static inline void triangleObjectMaskIF8BitPerChannel(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera& camera, const HomogenousMatrix4& flippedCamera_T_world, const Triangle2& triangle2, const Triangle3& triangle3, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, Worker* worker = nullptr, const uint8_t maskValue = 0xFFu, const unsigned int approximationBinSize = 0u);
337 
338  private:
339 
340  /**
341  * Creates an interpolation lookup table for a rectification of a planar rectangle object (a 2D texture in 3D place).
342  * @param anyCamera The camera profile to be applied
343  * @param flippedCamera_T_world The inverted and flipped camera matrix of the standard camera matrix defining the camera pose, must be valid
344  * @param rectangleOrigin Origin of the planar rectangle object in world units
345  * @param rectangleHorizontal Vector defining the horizontal edge of the 3D rectified object (beginning at the origin) in world units
346  * @param rectangleVertical Vector defining the vertical edge of the 3D rectified object (beginning at the origin and perpendicular to the rectangleHorizontal vector) in world units
347  * @param lookupTable The resulting lookup table, must be defined (size and number of bins) before this function can be called
348  * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the rectified frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
349  */
350  template <bool tPixelOriginUpperLeft>
351  static void planarRectangleObjectIFLookupTable(const AnyCamera& anyCamera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangleOrigin, const Vector3& rectangleHorizontal, const Vector3& rectangleVertical, LookupTable& lookupTable);
352 
353  /**
354  * Creates an interpolation lookup table for a rectification of an arbitrary rectangle object (a 2D texture in 3D place).
355  * @param anyCamera The camera profile to be applied, must be valid
356  * @param flippedCamera_T_world The transformation between world and the flipped camera, must be valid
357  * @param rectangle0 3D position of the rectangle corresponding to the upper left corner of the resulting frame
358  * @param rectangle1 3D position of the rectangle corresponding to the lower left corner of the resulting frame
359  * @param rectangle2 3D position of the rectangle corresponding to the lower right corner of the resulting frame
360  * @param rectangle3 3D position of the rectangle corresponding to the upper right corner of the resulting frame
361  * @param lookupTable The resulting lookup table, must be defined (size and number of bins) before this function can be called
362  * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the rectified frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
363  */
364  template <bool tPixelOriginUpperLeft>
365  static void arbitraryRectangleObjectIFLookupTable(const AnyCamera& anyCamera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangle0, const Vector3& rectangle1, const Vector3& rectangle2, const Vector3& rectangle3, LookupTable& lookupTable);
366 
367  /**
368  * Creates an interpolation lookup table for a triangle object (a 2D texture in 3D place).
369  * @param anyCamera The camera profile to be applied, must be valid
370  * @param flippedCamera_T_world The transformation between world and the flipped camera, must be valid
371  * @param triangle2 The triangle defined in the rectified frame, must be valid
372  * @param triangle3 The triangle defined in the 3D space, must be valid
373  * @param lookupTable The resulting lookup table, must be defined (size and number of bins) before this function can be called
374  * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the rectified frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
375  */
376  template <bool tPixelOriginUpperLeft>
377  static void triangleObjectIFLookupTable(const AnyCamera& anyCamera, const HomogenousMatrix4& flippedCamera_T_world, const Triangle2& triangle2, const Triangle3& triangle3, LookupTable& lookupTable);
378 
379  /**
380  * Creates a subset of the rectangular image of an area on a 3D plane as seen in a camera image.
381  * @param cameraFrame The frame that captures the 3D plane, must be valid
382  * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
383  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
384  * @param flippedCamera_T_world The transformation between world and flipped camera, with flipped camera pointing towards the positive z-space with y-axis down, must be valid
385  * @param rectangleOrigin Origin of the planar rectangle object in world units
386  * @param rectangleHorizontal Vector defining the horizontal edge of the 2D rectified object (beginning at the origin) in world units
387  * @param rectangleVertical Vector defining the vertical edge of the 2D rectified object (beginning at the origin and perpendicular to the rectangleHorizontal vector) in world units
388  * @param rectifiedFrame The resulting rectified image, must be valid
389  * @param rectifiedFrameWidth Width of the rectified image, in pixel, with range [1, infinity)
390  * @param rectifiedFrameHeight Height of the rectified image, in pixel, with range [1, infinity)
391  * @param rectifiedFramePaddingElements The number of padding elements at the end of each rectified frame row, in elements, with range [0, infinity)
392  * @param outsideFrameColor Color that is assigned to pixels that map outside the camera frame, if nullptr is used 0x00 will be assigned to each frame channel
393  * @param firstRectifiedFrameRow First rectified row to be handled, with range [0, rectifiedFrameHeight - 1]
394  * @param numberRectifiedFrameRows The number of rectified rows to be handled, with range [1, rectifiedFrameHeight - firstRectifiedFrameRow]
395  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
396  * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the rectified frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
397  */
398  template <unsigned int tChannels, bool tPixelOriginUpperLeft>
399  static void planarRectangleObjectIF8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_world, const Vector3* rectangleOrigin, const Vector3* rectangleHorizontal, const Vector3* rectangleVertical, uint8_t* rectifiedFrame, const unsigned int rectifiedFrameWidth, const unsigned int rectifiedFrameHeight, const unsigned int rectifiedFramePaddingElements, const uint8_t* outsideFrameColor, const unsigned int firstRectifiedFrameRow, const unsigned int numberRectifiedFrameRows);
400 
401  /**
402  * Creates a subset of the rectangle image from a specific position in 3D space.
403  * @param cameraFrame The frame that captures the 3D plane, must be valid
404  * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
405  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
406  * @param flippedCamera_T_world The transformation between world and flipped camera, with flipped camera pointing towards the positive z-space with y-axis down, must be valid
407  * @param rectangle The four 3D positions of the rectangle corresponding to the resulting rectified frame, with order top left, bottom left, bottom right, top right, must be valid
408  * @param rectifiedFrame The resulting rectified image, must be valid
409  * @param rectifiedFrameWidth Width of the rectified image, in pixel, with range [1, infinity)
410  * @param rectifiedFrameHeight Height of the rectified image, in pixel, with range [1, infinity)
411  * @param rectifiedFramePaddingElements The number of padding elements at the end of each rectified frame row, in elements, with range [0, infinity)
412  * @param outsideFrameColor Color that is assigned to pixels that map outside the camera frame, if nullptr is used 0x00 will be assigned to each frame channel
413  * @param firstRectifiedFrameRow First rectified row to be handled, with range [0, rectifiedFrameHeight - 1]
414  * @param numberRectifiedFrameRows The number of rectified rows to be handled, with range [1, rectifiedFrameHeight - firstRectifiedFrameRow]
415  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
416  * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the rectified frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
417  */
418  template <unsigned int tChannels, bool tPixelOriginUpperLeft>
419  static void arbitraryRectangleObjectIF8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_world, const Vector3* rectangle, uint8_t* rectifiedFrame, const unsigned int rectifiedFrameWidth, const unsigned int rectifiedFrameHeight, const unsigned int rectifiedFramePaddingElements, const uint8_t* outsideFrameColor, const unsigned int firstRectifiedFrameRow, const unsigned int numberRectifiedFrameRows);
420 
421  /**
422  * Draws a subset of a 2D triangle into a target frame.
423  * @param cameraFrame The frame that captures the 3D plane, must be valid
424  * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
425  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
426  * @param flippedCamera_T_world The transformation between world and flipped camera, with flipped camera pointing towards the positive z-space with y-axis down, must be valid
427  * @param triangle2 2D triangle defined in the rectified frame
428  * @param triangle3 3D triangle defined in the world coordinate system
429  * @param targetFrame The target image in which the triangle will be drawn, must be valid
430  * @param targetWidth Width of the target image in pixel, with range [1, infinity)
431  * @param targetHeight Height of the target image in pixel, with range [1, infinity)
432  * @param targetFramePaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
433  * @param outsideFrameColor Color that is assigned to pixels that map outside the camera frame, if nullptr is used 0x00 will be assigned to each frame channel
434  * @param firstTargetRow First target row to be handled
435  * @param numberTargetRows Number of target rows to be handled
436  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
437  * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the rectified frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
438  */
439  template <unsigned int tChannels, bool tPixelOriginUpperLeft>
440  static void triangleObjectIF8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_world, const Triangle2* triangle2, const Triangle3* triangle3, uint8_t* targetFrame, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const uint8_t* outsideFrameColor, const unsigned int firstTargetRow, const unsigned int numberTargetRows);
441 
442  /**
443  * Draws a subset of a 2D triangle into an image of a 3D triangle as seen in a camera image.
444  * @param cameraFrame The frame in which the triangle is visible, must be valid
445  * @param cameraFrameWidth The width of the camera frame, in pixel, with range [1, infinity)
446  * @param cameraFrameHeight The height of the camera frame, in pixel, with range [1, infinity)
447  * @param cameraFramePaddingElements The number of padding elements at the end of each frame row, in elements, with range [0, infinity)
448  * @param lookupTable The lookup table allowing to approximate the triangle positions
449  * @param triangle2 2D triangle defined in the target frame, must be valid
450  * @param targetFrame The target frame in which the triangle will be drawn, must be valid
451  * @param targetFramePaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
452  * @param outsideFrameColor Color that is assigned to pixels that map outside the camera frame, if nullptr is used 0x00 will be assigned to each frame channel
453  * @param firstTargetRow First target row to be handled
454  * @param numberTargetRows Number of target rows to be handled
455  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
456  */
457  template <unsigned int tChannels>
458  static void triangleObjectLookup8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFrameWidth, const unsigned int cameraFrameHeight, const unsigned int cameraFramePaddingElements, const LookupTable* lookupTable, const Triangle2* triangle2, uint8_t* targetFrame, const unsigned int targetFramePaddingElements, const uint8_t* outsideFrameColor, const unsigned int firstTargetRow, const unsigned int numberTargetRows);
459 
460  /**
461  * Creates a subset of the rectangular image of an area on a 3D plane as seen in a camera image.
462  * @param cameraFrame The frame that captures the 3D plane, must be valid
463  * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
464  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
465  * @param flippedCamera_T_world The transformation between world and flipped camera, with flipped camera pointing towards the positive z-space with y-axis down, must be valid
466  * @param rectangleOrigin Origin of the planar rectangle object in world units
467  * @param rectangleHorizontal Vector defining the horizontal edge of the rectangle object (beginning at the origin) in world units
468  * @param rectangleVertical Vector defining the vertical edge of the rectangle object (beginning at the origin and perpendicular to the rectangleHorizontal vector) in world units
469  * @param targetFrame The resulting target image, must be valid
470  * @param targetMask The resulting mask, must be valid
471  * @param targetWidth Width of the target image, in pixel, with range [1, infinity)
472  * @param targetHeight Height of the target image, in pixel, with range [1, infinity)
473  * @param targetFramePaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
474  * @param targetMaskPaddingElements The number of padding elements at the end of each row target mask row, in elements, with range [0, infinity)
475  * @param maskValue The mask value for pixels lying inside the given camera frame, pixels lying outside the camera frame will be assigned with (0xFF - maskValue)
476  * @param firstTargetRow First target row to be handled
477  * @param numberTargetRows Number of target rows to be handled
478  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
479  * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the target frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
480  */
481  template <unsigned int tChannels, bool tPixelOriginUpperLeft>
482  static void planarRectangleObjectMaskIF8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_world, const Vector3* rectangleOrigin, const Vector3* rectangleHorizontal, const Vector3* rectangleVertical, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, const uint8_t maskValue, const unsigned int firstTargetRow, const unsigned int numberTargetRows);
483 
484  /**
485  * Creates a subset of the rectangular image from a specific position in 3D space.
486  * @param cameraFrame The frame that captures the 3D plane, must be valid
487  * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
488  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
489  * @param flippedCamera_T_world The transformation between world and flipped camera, with flipped camera pointing towards the positive z-space with y-axis down, must be valid
490  * @param rectangle The four 3D positions of the rectangle corresponding to the resulting rectified frame, with order top left, bottom left, bottom right, top right, must be valid
491  * @param targetFrame The resulting target image, must be valid
492  * @param targetMask The resulting mask, must be valid
493  * @param targetWidth Width of the target image, in pixel, with range [1, infinity)
494  * @param targetHeight Height of the target image, in pixel, with range [1, infinity)
495  * @param targetFramePaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
496  * @param targetMaskPaddingElements The number of padding elements at the end of each row target mask row, in elements, with range [0, infinity)
497  * @param maskValue The mask value for pixels lying inside the given camera frame, pixels lying outside the camera frame will be assigned with (0xFF - maskValue)
498  * @param firstTargetRow First target row to be handled, with range [0, targetHeight - 1]
499  * @param numberTargetRows The number of target rows to be handled, with range [1, targetHeight - firstTargetRow]
500  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
501  * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the target frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
502  */
503  template <unsigned int tChannels, bool tPixelOriginUpperLeft>
504  static void arbitraryRectangleObjectMaskIF8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_world, const Vector3* rectangle, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, const uint8_t maskValue, const unsigned int firstTargetRow, const unsigned int numberTargetRows);
505 
506  /**
507  * Creates a subset of a 2D triangle in a target image from a specific 3D triangle on a 3D plane.
508  * @param cameraFrame The frame that captures the 3D plane, must be valid
509  * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
510  * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
511  * @param flippedCamera_T_world The transformation between world and flipped camera, with flipped camera pointing towards the positive z-space with y-axis down, must be valid
512  * @param triangle2 2D triangle defined in the target frame, must be valid
513  * @param triangle3 3D triangle defined in the world coordinate system, must be valid
514  * @param targetFrame The resulting target image, must be valid
515  * @param targetMask The resulting mask, must be valid
516  * @param targetWidth Width of the target image, in pixel, with range [1, infinity)
517  * @param targetHeight Height of the target image, in pixel, with range [1, infinity)
518  * @param targetFramePaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
519  * @param targetMaskPaddingElements The number of padding elements at the end of each row target mask row, in elements, with range [0, infinity)
520  * @param maskValue The mask value for pixels lying inside the given camera frame, pixels lying outside the camera frame will be assigned with (0xFF - maskValue)
521  * @param firstTargetRow First target row to be handled, with range [0, targetHeight - 1]
522  * @param numberTargetRows The number of target rows to be handled, with range [1, targetHeight - firstTargetRow]
523  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
524  * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the target frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
525  */
526  template <unsigned int tChannels, bool tPixelOriginUpperLeft>
527  static void triangleObjectMaskIF8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_world, const Triangle2* triangle2, const Triangle3* triangle3, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, const uint8_t maskValue, const unsigned int firstTargetRow, const unsigned int numberTargetRows);
528 
529  /**
530  * Creates a subset of a 2D triangle in a target image from a specific 3D triangle on a 3D plane and applies a lookup table.
531  * @param cameraFrame The frame that captures the 3D plane, must be valid
532  * @param cameraFrameWidth The width of the camera frame, in pixels, with range [1, infinity)
533  * @param cameraFrameHeight The height of the camera frame, in pixels, with range [1, infinity)
534  * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
535  * @param lookupTable The lookup table allowing to approximate the triangle positions
536  * @param triangle2 2D triangle defined in the target frame
537  * @param targetFrame The resulting target image, must be valid
538  * @param targetMask The resulting mask, must be valid
539  * @param targetFramePaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
540  * @param targetMaskPaddingElements The number of padding elements at the end of each row target mask row, in elements, with range [0, infinity)
541  * @param maskValue The mask value for pixels lying inside the given camera frame, pixels lying outside the camera frame will be assigned with (0xFF - maskValue)
542  * @param firstTargetRow First target row to be handled, with range [0, targetHeight - 1]
543  * @param numberTargetRows The number of target rows to be handled, with range [1, targetHeight - firstTargetRow]
544  * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
545  */
546  template <unsigned int tChannels>
547  static void triangleObjectMaskLookup8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFrameWidth, const unsigned int cameraFrameHeight, const unsigned int cameraFramePaddingElements, const LookupTable* lookupTable, const Triangle2* triangle2, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, const uint8_t maskValue, const unsigned int firstTargetRow, const unsigned int numberTargetRows);
548 };
549 
550 template <bool tPixelOriginUpperLeft>
551 Vector2 FrameRectification::planarRectangleObjectRectifiedPosition2cameraPositionIF(const AnyCamera& anyCamera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangleOrigin, const Vector3& rectangleHorizontal, const Vector3& rectangleVertical, const unsigned int rectifiedWidth, const unsigned int rectifiedHeight, const Vector2& rectifiedPosition)
552 {
553  ocean_assert(anyCamera.isValid() && flippedCamera_T_world.isValid());
554  ocean_assert(rectifiedWidth != 0u && rectifiedHeight != 0u);
555 
556  ocean_assert(rectifiedPosition.x() >= 0 && rectifiedPosition.x() < Scalar(rectifiedWidth));
557  ocean_assert(rectifiedPosition.y() >= 0 && rectifiedPosition.y() < Scalar(rectifiedHeight));
558 
559  const Scalar yCorrected = tPixelOriginUpperLeft ? rectifiedPosition.y() : (Scalar(rectifiedHeight - 1u) - rectifiedPosition.y());
560 
561  // the actual pixel position is located at the upper left corner of each individual pixel
562  const Vector3 objectPoint(rectangleOrigin + rectangleHorizontal * (rectifiedPosition.x() / Scalar(rectifiedWidth)) + rectangleVertical * (yCorrected / Scalar(rectifiedHeight)));
563  const Vector2 cameraPoint(anyCamera.projectToImageIF(flippedCamera_T_world, objectPoint));
564 
565  const Vector2 correctedCameraPoint(cameraPoint.x(), tPixelOriginUpperLeft ? cameraPoint.y() : (Scalar(anyCamera.height() - 1u) - cameraPoint.y()));
566 
567  return correctedCameraPoint;
568 }
569 
570 template <unsigned int tChannels>
571 inline void FrameRectification::planarRectangleObjectIF8BitPerChannel(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera& camera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangleOrigin, const Vector3& rectangleHorizontal, const Vector3& rectangleVertical, uint8_t* rectifiedFrame, const unsigned int rectifiedFrameWidth, const unsigned int rectifiedFrameHeight, const unsigned int rectifiedFramePaddingElements, Worker* worker, const uint8_t* outsideFrameColor, const unsigned int approximationBinSize)
572 {
573  static_assert(tChannels > 0u, "Invalid frame channel number!");
574 
575  const uint8_t zeroValue[tChannels] = {0x00};
576 
577  if (approximationBinSize == 0u)
578  {
579  if (worker)
580  {
581  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
582  {
583  worker->executeFunction(Worker::Function::createStatic(planarRectangleObjectIF8BitPerChannelSubset<tChannels, true>, cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &rectangleOrigin, &rectangleHorizontal, &rectangleVertical, rectifiedFrame, rectifiedFrameWidth, rectifiedFrameHeight, rectifiedFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, 0u), 0u, rectifiedFrameHeight, 12u, 13u, 20u);
584  }
585  else
586  {
587  worker->executeFunction(Worker::Function::createStatic(planarRectangleObjectIF8BitPerChannelSubset<tChannels, false>, cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &rectangleOrigin, &rectangleHorizontal, &rectangleVertical, rectifiedFrame, rectifiedFrameWidth, rectifiedFrameHeight, rectifiedFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, 0u), 0u, rectifiedFrameHeight, 12u, 13u, 20u);
588  }
589  }
590  else
591  {
592  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
593  {
594  planarRectangleObjectIF8BitPerChannelSubset<tChannels, true>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &rectangleOrigin, &rectangleHorizontal, &rectangleVertical, rectifiedFrame, rectifiedFrameWidth, rectifiedFrameHeight, rectifiedFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, rectifiedFrameHeight);
595  }
596  else
597  {
598  planarRectangleObjectIF8BitPerChannelSubset<tChannels, false>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &rectangleOrigin, &rectangleHorizontal, &rectangleVertical, rectifiedFrame, rectifiedFrameWidth, rectifiedFrameHeight, rectifiedFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, rectifiedFrameHeight);
599  }
600  }
601  }
602  else
603  {
604  const unsigned int binsX = minmax(1u, rectifiedFrameWidth / approximationBinSize, rectifiedFrameWidth / 4u);
605  const unsigned int binsY = minmax(1u, rectifiedFrameHeight / approximationBinSize, rectifiedFrameHeight / 4u);
606  LookupTable lookupTable(rectifiedFrameWidth, rectifiedFrameHeight, binsX, binsY);
607 
608  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
609  {
610  planarRectangleObjectIFLookupTable<true>(camera, flippedCamera_T_world, rectangleOrigin, rectangleHorizontal, rectangleVertical, lookupTable);
611  }
612  else
613  {
614  planarRectangleObjectIFLookupTable<false>(camera, flippedCamera_T_world, rectangleOrigin, rectangleHorizontal, rectangleVertical, lookupTable);
615  }
616 
617  CV::FrameInterpolatorBilinear::lookup<uint8_t, tChannels>(cameraFrame, camera.width(), camera.height(), lookupTable, false, outsideFrameColor ? outsideFrameColor : zeroValue, rectifiedFrame, cameraFramePaddingElements, rectifiedFramePaddingElements, worker);
618  }
619 }
620 
621 template <unsigned int tChannels>
622 inline void FrameRectification::arbitraryRectangleObjectIF8BitPerChannel(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera& camera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangle0, const Vector3& rectangle1, const Vector3& rectangle2, const Vector3& rectangle3, uint8_t* rectifiedFrame, const unsigned int rectifiedFrameWidth, const unsigned int rectifiedFrameHeight, const unsigned int rectifiedFramePaddingElements, Worker* worker, const uint8_t* outsideFrameColor, const unsigned int approximationBinSize)
623 {
624  static_assert(tChannels > 0u, "Invalid frame channel number!");
625 
626  const uint8_t zeroValue[tChannels] = {0x00};
627 
628  if (approximationBinSize == 0u)
629  {
630  const Vector3 rectangle[4] = {rectangle0, rectangle1, rectangle2, rectangle3};
631 
632  if (worker)
633  {
634  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
635  {
636  worker->executeFunction(Worker::Function::createStatic(arbitraryRectangleObjectIF8BitPerChannelSubset<tChannels, true>, cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, rectangle, rectifiedFrame, rectifiedFrameWidth, rectifiedFrameHeight, rectifiedFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, 0u), 0u, rectifiedFrameHeight, 10u, 11u, 20u);
637  }
638  else
639  {
640  worker->executeFunction(Worker::Function::createStatic(arbitraryRectangleObjectIF8BitPerChannelSubset<tChannels, false>, cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, rectangle, rectifiedFrame, rectifiedFrameWidth, rectifiedFrameHeight, rectifiedFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, 0u), 0u, rectifiedFrameHeight, 10u, 11u, 20u);
641  }
642  }
643  else
644  {
645  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
646  {
647  arbitraryRectangleObjectIF8BitPerChannelSubset<tChannels, true>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, rectangle, rectifiedFrame, rectifiedFrameWidth, rectifiedFrameHeight, rectifiedFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, rectifiedFrameHeight);
648  }
649  else
650  {
651  arbitraryRectangleObjectIF8BitPerChannelSubset<tChannels, false>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, rectangle, rectifiedFrame, rectifiedFrameWidth, rectifiedFrameHeight, rectifiedFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, rectifiedFrameHeight);
652  }
653  }
654  }
655  else
656  {
657  const unsigned int binsX = minmax(1u, rectifiedFrameWidth / approximationBinSize, rectifiedFrameWidth / 4u);
658  const unsigned int binsY = minmax(1u, rectifiedFrameHeight / approximationBinSize, rectifiedFrameHeight / 4u);
659  LookupTable lookupTable(rectifiedFrameWidth, rectifiedFrameHeight, binsX, binsY);
660 
661  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
662  {
663  arbitraryRectangleObjectIFLookupTable<true>(camera, flippedCamera_T_world, rectangle0, rectangle1, rectangle2, rectangle3, lookupTable);
664  }
665  else
666  {
667  arbitraryRectangleObjectIFLookupTable<false>(camera, flippedCamera_T_world, rectangle0, rectangle1, rectangle2, rectangle3, lookupTable);
668  }
669 
670  CV::FrameInterpolatorBilinear::lookup<uint8_t, tChannels>(cameraFrame, camera.width(), camera.height(), lookupTable, false, outsideFrameColor ? outsideFrameColor : zeroValue, rectifiedFrame, cameraFramePaddingElements, rectifiedFramePaddingElements, worker);
671  }
672 }
673 
674 template <unsigned int tChannels>
675 inline void FrameRectification::triangleObjectIF8BitPerChannel(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera& camera, const HomogenousMatrix4& flippedCamera_T_world, const Triangle2& triangle2, const Triangle3& triangle3, uint8_t* targetFrame, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, Worker* worker, const uint8_t* outsideFrameColor, const unsigned int approximationBinSize)
676 {
677  static_assert(tChannels > 0u, "Invalid frame channel number!");
678 
679  const uint8_t zeroValue[tChannels] = {0x00};
680 
681  if (approximationBinSize == 0u)
682  {
683  if (worker)
684  {
685  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
686  {
687  worker->executeFunction(Worker::Function::createStatic(triangleObjectIF8BitPerChannelSubset<tChannels, true>, cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &triangle2, &triangle3, targetFrame, targetWidth, targetHeight, targetFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, 0u), 0u, targetHeight, 11u, 12u, 20u);
688  }
689  else
690  {
691  worker->executeFunction(Worker::Function::createStatic(triangleObjectIF8BitPerChannelSubset<tChannels, false>, cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &triangle2, &triangle3, targetFrame, targetWidth, targetHeight, targetFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, 0u), 0u, targetHeight, 11u, 12u, 20u);
692  }
693  }
694  else
695  {
696  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
697  {
698  triangleObjectIF8BitPerChannelSubset<tChannels, true>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &triangle2, &triangle3, targetFrame, targetWidth, targetHeight, targetFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, targetHeight);
699  }
700  else
701  {
702  triangleObjectIF8BitPerChannelSubset<tChannels, false>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &triangle2, &triangle3, targetFrame, targetWidth, targetHeight, targetFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, targetHeight);
703  }
704  }
705  }
706  else
707  {
708  const unsigned int binsX = minmax(1u, targetWidth / approximationBinSize, targetWidth / 4u);
709  const unsigned int binsY = minmax(1u, targetHeight / approximationBinSize, targetHeight / 4u);
710  LookupTable lookupTable(targetWidth, targetHeight, binsX, binsY);
711 
712  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
713  {
714  triangleObjectIFLookupTable<true>(camera, flippedCamera_T_world, triangle2, triangle3, lookupTable);
715  }
716  else
717  {
718  triangleObjectIFLookupTable<false>(camera, flippedCamera_T_world, triangle2, triangle3, lookupTable);
719  }
720 
721  if (worker)
722  {
723  worker->executeFunction(Worker::Function::createStatic(triangleObjectLookup8BitPerChannelSubset<tChannels>, cameraFrame, camera.width(), camera.height(), cameraFramePaddingElements, (const LookupTable*)(&lookupTable), &triangle2, targetFrame, targetFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, 0u), 0u, targetHeight, 9u, 10u, 20u);
724  }
725  else
726  {
727  triangleObjectLookup8BitPerChannelSubset<tChannels>(cameraFrame, camera.width(), camera.height(), cameraFramePaddingElements, &lookupTable, &triangle2, targetFrame, targetFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, targetHeight);
728  }
729  }
730 }
731 
732 template <unsigned int tChannels>
733 inline void FrameRectification::planarRectangleObjectMaskIF8BitPerChannel(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera& camera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangleOrigin, const Vector3& rectangleHorizontal, const Vector3& rectangleVertical, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, Worker* worker, const uint8_t maskValue, const unsigned int approximationBinSize)
734 {
735  static_assert(tChannels > 0u, "Invalid frame channel number!");
736 
737  if (approximationBinSize == 0u)
738  {
739  if (worker)
740  {
741  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
742  {
743  worker->executeFunction(Worker::Function::createStatic(planarRectangleObjectMaskIF8BitPerChannelSubset<tChannels, true>, cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &rectangleOrigin, &rectangleHorizontal, &rectangleVertical, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, 0u), 0u, targetHeight, 14u, 15u, 20u);
744  }
745  else
746  {
747  worker->executeFunction(Worker::Function::createStatic(planarRectangleObjectMaskIF8BitPerChannelSubset<tChannels, false>, cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &rectangleOrigin, &rectangleHorizontal, &rectangleVertical, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, 0u), 0u, targetHeight, 14u, 15u, 20u);
748  }
749  }
750  else
751  {
752  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
753  {
754  planarRectangleObjectMaskIF8BitPerChannelSubset<tChannels, true>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &rectangleOrigin, &rectangleHorizontal, &rectangleVertical, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
755  }
756  else
757  {
758  planarRectangleObjectMaskIF8BitPerChannelSubset<tChannels, false>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &rectangleOrigin, &rectangleHorizontal, &rectangleVertical, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
759  }
760  }
761  }
762  else
763  {
764  const unsigned int binsX = minmax(1u, targetWidth / approximationBinSize, targetWidth / 4u);
765  const unsigned int binsY = minmax(1u, targetHeight / approximationBinSize, targetHeight / 4u);
766  LookupTable lookupTable(targetWidth, targetHeight, binsX, binsY);
767 
768  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
769  {
770  planarRectangleObjectIFLookupTable<true>(camera, flippedCamera_T_world, rectangleOrigin, rectangleHorizontal, rectangleVertical, lookupTable);
771  }
772  else
773  {
774  planarRectangleObjectIFLookupTable<false>(camera, flippedCamera_T_world, rectangleOrigin, rectangleHorizontal, rectangleVertical, lookupTable);
775  }
776 
777  CV::FrameInterpolatorBilinear::lookupMask8BitPerChannel<tChannels>(cameraFrame, camera.width(), camera.height(), lookupTable, false, targetFrame, targetMask, cameraFramePaddingElements, targetFramePaddingElements, targetMaskPaddingElements, worker, maskValue);
778  }
779 }
780 
781 template <unsigned int tChannels>
782 inline void FrameRectification::arbitraryRectangleObjectMaskIF8BitPerChannel(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera& camera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangle0, const Vector3& rectangle1, const Vector3& rectangle2, const Vector3& rectangle3, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, Worker* worker, const uint8_t maskValue, const unsigned int approximationBinSize)
783 {
784  static_assert(tChannels > 0u, "Invalid frame channel number!");
785 
786  if (approximationBinSize == 0u)
787  {
788  const Vector3 rectangle[4] = {rectangle0, rectangle1, rectangle2, rectangle3};
789 
790  if (worker)
791  {
792  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
793  {
794  worker->executeFunction(Worker::Function::createStatic(arbitraryRectangleObjectMaskIF8BitPerChannelSubset<tChannels, true>, cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, rectangle, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, 0u), 0u, targetHeight, 12u, 13u, 20u);
795  }
796  else
797  {
798  worker->executeFunction(Worker::Function::createStatic(arbitraryRectangleObjectMaskIF8BitPerChannelSubset<tChannels, false>, cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, rectangle, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, 0u), 0u, targetHeight, 12u, 13u, 20u);
799  }
800  }
801  else
802  {
803  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
804  {
805  arbitraryRectangleObjectMaskIF8BitPerChannelSubset<tChannels, true>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, rectangle, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
806  }
807  else
808  {
809  arbitraryRectangleObjectMaskIF8BitPerChannelSubset<tChannels, false>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, rectangle, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
810  }
811  }
812  }
813  else
814  {
815  const unsigned int binsX = minmax(1u, targetWidth / approximationBinSize, targetWidth / 4u);
816  const unsigned int binsY = minmax(1u, targetHeight / approximationBinSize, targetHeight / 4u);
817  LookupTable lookupTable(targetWidth, targetHeight, binsX, binsY);
818 
819  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
820  {
821  arbitraryRectangleObjectIFLookupTable<true>(camera, flippedCamera_T_world, rectangle0, rectangle1, rectangle2, rectangle3, lookupTable);
822  }
823  else
824  {
825  arbitraryRectangleObjectIFLookupTable<false>(camera, flippedCamera_T_world, rectangle0, rectangle1, rectangle2, rectangle3, lookupTable);
826  }
827 
828  CV::FrameInterpolatorBilinear::lookupMask8BitPerChannel<tChannels>(cameraFrame, camera.width(), camera.height(), lookupTable, false, targetFrame, targetMask, cameraFramePaddingElements, targetFramePaddingElements, targetMaskPaddingElements, worker, maskValue);
829  }
830 }
831 
832 template <unsigned int tChannels>
833 inline void FrameRectification::triangleObjectMaskIF8BitPerChannel(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera& camera, const HomogenousMatrix4& flippedCamera_T_world, const Triangle2& triangle2, const Triangle3& triangle3, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, Worker* worker, const uint8_t maskValue, const unsigned int approximationBinSize)
834 {
835  static_assert(tChannels > 0u, "Invalid frame channel number!");
836 
837  if (approximationBinSize == 0u)
838  {
839  if (worker)
840  {
841  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
842  {
843  worker->executeFunction(Worker::Function::createStatic(triangleObjectMaskIF8BitPerChannelSubset<tChannels, true>, cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &triangle2, &triangle3, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, 0u), 0u, targetHeight, 13u, 14u, 20u);
844  }
845  else
846  {
847  worker->executeFunction(Worker::Function::createStatic(triangleObjectMaskIF8BitPerChannelSubset<tChannels, false>, cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &triangle2, &triangle3, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, 0u), 0u, targetHeight, 13u, 14u, 20u);
848  }
849  }
850  else
851  {
852  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
853  {
854  triangleObjectMaskIF8BitPerChannelSubset<tChannels, true>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &triangle2, &triangle3, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
855  }
856  else
857  {
858  triangleObjectMaskIF8BitPerChannelSubset<tChannels, false>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &triangle2, &triangle3, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
859  }
860  }
861  }
862  else
863  {
864  const unsigned int binsX = minmax(1u, targetWidth / approximationBinSize, targetWidth / 4u);
865  const unsigned int binsY = minmax(1u, targetHeight / approximationBinSize, targetHeight / 4u);
866  LookupTable lookupTable(targetWidth, targetHeight, binsX, binsY);
867 
868  if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
869  {
870  triangleObjectIFLookupTable<true>(camera, flippedCamera_T_world, triangle2, triangle3, lookupTable);
871  }
872  else
873  {
874  triangleObjectIFLookupTable<false>(camera, flippedCamera_T_world, triangle2, triangle3, lookupTable);
875  }
876 
877  if (worker)
878  {
879  worker->executeFunction(Worker::Function::createStatic(triangleObjectMaskLookup8BitPerChannelSubset<tChannels>, cameraFrame, camera.width(), camera.height(), cameraFramePaddingElements, (const LookupTable*)&lookupTable, &triangle2, targetFrame, targetMask, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, 0u), 0u, targetHeight, 11u, 12u, 20u);
880  }
881  else
882  {
883  triangleObjectMaskLookup8BitPerChannelSubset<tChannels>(cameraFrame, camera.width(), camera.height(), cameraFramePaddingElements, (const LookupTable*)(&lookupTable), &triangle2, targetFrame, targetMask, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
884  }
885  }
886 }
887 
888 template <bool tPixelOriginUpperLeft>
889 void FrameRectification::planarRectangleObjectIFLookupTable(const AnyCamera& anyCamera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangleOrigin, const Vector3& rectangleHorizontal, const Vector3& rectangleVertical, LookupTable& lookupTable)
890 {
891  ocean_assert(anyCamera.isValid() && flippedCamera_T_world.isValid());
892 
893  const Scalar frameHeight1 = Scalar(anyCamera.height() - 1u);
894 
895  const Scalar invRectifiedWidth = Scalar(1) / Scalar(lookupTable.sizeX());
896  const Scalar invRectifiedHeight = Scalar(1) / Scalar(lookupTable.sizeY());
897 
898  Vectors3 objectPoints(lookupTable.binsX() + 1u);
899  Vectors2 imagePoints(lookupTable.binsX() + 1u);
900 
901  for (unsigned int yBin = 0u; yBin <= lookupTable.binsY(); ++yBin)
902  {
903  const Scalar y = lookupTable.binTopLeftCornerPositionY(yBin);
904  const Scalar yCorrected = tPixelOriginUpperLeft ? y : (Scalar(lookupTable.sizeY() - 1) - Scalar(y));
905 
906  for (unsigned int xBin = 0u; xBin <= lookupTable.binsX(); ++xBin)
907  {
908  const Scalar x = lookupTable.binTopLeftCornerPositionX(xBin);
909 
910  objectPoints[xBin] = Vector3(rectangleOrigin + rectangleHorizontal * (Scalar(x) * invRectifiedWidth) + rectangleVertical * (yCorrected * invRectifiedHeight));
911  }
912 
913  anyCamera.projectToImageIF(flippedCamera_T_world, objectPoints.data(), objectPoints.size(), imagePoints.data());
914 
915  for (unsigned int xBin = 0u; xBin <= lookupTable.binsX(); ++xBin)
916  {
917  const Vector2& imagePoint = imagePoints[xBin];
918 
919  const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
920 
921  lookupTable.setBinTopLeftCornerValue(xBin, yBin, correctedImagePoint);
922  }
923  }
924 }
925 
926 template <bool tPixelOriginUpperLeft>
927 void FrameRectification::arbitraryRectangleObjectIFLookupTable(const AnyCamera& anyCamera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangle0, const Vector3& rectangle1, const Vector3& rectangle2, const Vector3& rectangle3, LookupTable& lookupTable)
928 {
929  ocean_assert(anyCamera.isValid() && flippedCamera_T_world.isValid());
930 
931  const Scalar frameHeight1 = Scalar(anyCamera.height() - 1u);
932 
933  const Scalar invRectifiedWidth = Scalar(1) / Scalar(lookupTable.sizeX());
934  const Scalar invRectifiedHeight = Scalar(1) / Scalar(lookupTable.sizeY());
935 
936  for (unsigned int yBin = 0u; yBin <= lookupTable.binsY(); ++yBin)
937  {
938  const Scalar y = lookupTable.binTopLeftCornerPositionY(yBin);
939  const Scalar yCorrected = tPixelOriginUpperLeft ? y : (Scalar(lookupTable.sizeY() - 1) - Scalar(y));
940 
941  const Vector3 left(rectangle0 + (rectangle1 - rectangle0) * (Scalar(yCorrected) * invRectifiedHeight));
942  const Vector3 right(rectangle3 + (rectangle2 - rectangle3) * (Scalar(yCorrected) * invRectifiedHeight));
943 
944  for (unsigned int xBin = 0u; xBin <= lookupTable.binsX(); ++xBin)
945  {
946  const Scalar x = lookupTable.binTopLeftCornerPositionX(xBin);
947 
948  const Vector3 objectPoint(left + (right - left) * (Scalar(x) * invRectifiedWidth));
949  const Vector2 imagePoint(anyCamera.projectToImageIF(flippedCamera_T_world, objectPoint));
950 
951  const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
952 
953  lookupTable.setBinTopLeftCornerValue(xBin, yBin, correctedImagePoint);
954  }
955  }
956 }
957 
958 template <bool tPixelOriginUpperLeft>
959 void FrameRectification::triangleObjectIFLookupTable(const AnyCamera& anyCamera, const HomogenousMatrix4& flippedCamera_T_world, const Triangle2& triangle2, const Triangle3& triangle3, LookupTable& lookupTable)
960 {
961  ocean_assert(anyCamera.isValid() && flippedCamera_T_world.isValid());
962 
963  const Scalar frameHeight1 = Scalar(anyCamera.height() - 1u);
964 
965  for (unsigned int yBin = 0u; yBin <= lookupTable.binsY(); ++yBin)
966  {
967  const Scalar y = lookupTable.binTopLeftCornerPositionY(yBin);
968  const Scalar yCorrected = tPixelOriginUpperLeft ? y : (Scalar(lookupTable.sizeY() - 1) - Scalar(y));
969 
970  for (unsigned int xBin = 0u; xBin <= lookupTable.binsX(); ++xBin)
971  {
972  const Scalar x = lookupTable.binTopLeftCornerPositionX(xBin);
973 
974  const Vector3 barycentricTargetPosition(triangle2.cartesian2barycentric(Vector2(x, yCorrected)));
975 
976  const Vector3 objectPoint(triangle3.barycentric2cartesian(barycentricTargetPosition));
977  const Vector2 imagePoint(anyCamera.projectToImageIF(flippedCamera_T_world, objectPoint));
978 
979  const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
980 
981  lookupTable.setBinTopLeftCornerValue(xBin, yBin, correctedImagePoint);
982  }
983  }
984 }
985 
986 template <unsigned int tChannels, bool tPixelOriginUpperLeft>
987 void FrameRectification::planarRectangleObjectIF8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_world, const Vector3* rectangleOrigin, const Vector3* rectangleHorizontal, const Vector3* rectangleVertical, uint8_t* rectifiedFrame, const unsigned int rectifiedFrameWidth, const unsigned int rectifiedFrameHeight, const unsigned int rectifiedFramePaddingElements, const uint8_t* outsideFrameColor, const unsigned int firstRectifiedFrameRow, const unsigned int numberRectifiedFrameRows)
988 {
989  static_assert(tChannels >= 1u, "Invalid channel number!");
990 
991  ocean_assert(cameraFrame != nullptr && rectifiedFrame != nullptr && rectangleOrigin != nullptr && rectangleHorizontal != nullptr && rectangleVertical != nullptr);
992  ocean_assert(camera != nullptr && camera->isValid() && flippedCamera_T_world != nullptr && flippedCamera_T_world->isValid());
993  ocean_assert(rectifiedFrameWidth >= 1u && rectifiedFrameHeight >= 1u);
994 
995  ocean_assert(firstRectifiedFrameRow + numberRectifiedFrameRows <= rectifiedFrameHeight);
996 
997  const Scalar frameWidth1 = Scalar(camera->width() - 1u);
998  const Scalar frameHeight1 = Scalar(camera->height() - 1u);
999 
1000  const Scalar invRectifiedFrameWidth = Scalar(1) / Scalar(rectifiedFrameWidth);
1001  const Scalar invRectifiedFrameHeight = Scalar(1) / Scalar(rectifiedFrameHeight);
1002 
1003  const unsigned int rectifiedFrameStrideElements = rectifiedFrameWidth * tChannels + rectifiedFramePaddingElements;
1004 
1005  uint8_t* rectifiedPixel = rectifiedFrame + firstRectifiedFrameRow * rectifiedFrameStrideElements;
1006 
1007  for (unsigned int y = firstRectifiedFrameRow; y < firstRectifiedFrameRow + numberRectifiedFrameRows; ++y)
1008  {
1009  const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar(rectifiedFrameHeight - 1u) - Scalar(y));
1010 
1011  for (unsigned int x = 0u; x < rectifiedFrameWidth; ++x)
1012  {
1013  const Vector3 objectPoint(*rectangleOrigin + *rectangleHorizontal * (Scalar(x) * invRectifiedFrameWidth) + *rectangleVertical * (yCorrected * invRectifiedFrameHeight));
1014  const Vector2 imagePoint(camera->projectToImageIF(*flippedCamera_T_world, objectPoint));
1015 
1016  const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
1017 
1018  if (correctedImagePoint.x() >= 0 && correctedImagePoint.y() >= 0 && correctedImagePoint.x() <= frameWidth1 && correctedImagePoint.y() <= frameHeight1)
1019  {
1020  CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, camera->width(), camera->height(), cameraFramePaddingElements, correctedImagePoint, rectifiedPixel);
1021  }
1022  else
1023  {
1024  memcpy(rectifiedPixel, outsideFrameColor, sizeof(uint8_t) * tChannels);
1025  }
1026 
1027  rectifiedPixel += tChannels;
1028  }
1029 
1030  rectifiedPixel += rectifiedFramePaddingElements;
1031  }
1032 }
1033 
1034 template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1035 void FrameRectification::arbitraryRectangleObjectIF8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_world, const Vector3* rectangle, uint8_t* rectifiedFrame, const unsigned int rectifiedFrameWidth, const unsigned int rectifiedFrameHeight, const unsigned int rectifiedFramePaddingElements, const uint8_t* outsideFrameColor, const unsigned int firstRectifiedFrameRow, const unsigned int numberRectifiedFrameRows)
1036 {
1037  static_assert(tChannels >= 1u, "Invalid channel number!");
1038 
1039  ocean_assert(cameraFrame != nullptr && rectifiedFrame != nullptr && rectangle != nullptr);
1040  ocean_assert(camera != nullptr && camera->isValid() && flippedCamera_T_world != nullptr && flippedCamera_T_world->isValid());
1041  ocean_assert(rectifiedFrameWidth >= 1u && rectifiedFrameHeight >= 1u);
1042 
1043  ocean_assert(firstRectifiedFrameRow + numberRectifiedFrameRows <= rectifiedFrameHeight);
1044 
1045  const Scalar frameWidth1 = Scalar(camera->width() - 1u);
1046  const Scalar frameHeight1 = Scalar(camera->height() - 1u);
1047 
1048  const Scalar invRectifiedFrameWidth = Scalar(1) / Scalar(rectifiedFrameWidth);
1049  const Scalar invRectifiedFrameHeight = Scalar(1) / Scalar(rectifiedFrameHeight);
1050 
1051  const unsigned int rectifiedFrameStrideElements = rectifiedFrameWidth * tChannels + rectifiedFramePaddingElements;
1052 
1053  uint8_t* rectifiedPixel = rectifiedFrame + firstRectifiedFrameRow * rectifiedFrameStrideElements;
1054 
1055  const Vector3 direction10 = rectangle[1] - rectangle[0];
1056  const Vector3 direction23 = rectangle[2] - rectangle[3];
1057 
1058  for (unsigned int y = firstRectifiedFrameRow; y < firstRectifiedFrameRow + numberRectifiedFrameRows; ++y)
1059  {
1060  const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar(rectifiedFrameHeight - 1u) - Scalar(y));
1061 
1062  const Vector3 left(rectangle[0] + direction10 * (Scalar(yCorrected) * invRectifiedFrameHeight));
1063  const Vector3 right(rectangle[3] + direction23 * (Scalar(yCorrected) * invRectifiedFrameHeight));
1064 
1065  for (unsigned int x = 0u; x < rectifiedFrameWidth; ++x)
1066  {
1067  const Vector3 objectPoint(left + (right - left) * (Scalar(x) * invRectifiedFrameWidth));
1068  const Vector2 imagePoint(camera->projectToImageIF(*flippedCamera_T_world, objectPoint));
1069 
1070  const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
1071 
1072  if (correctedImagePoint.x() >= 0 && correctedImagePoint.y() >= 0 && correctedImagePoint.x() <= frameWidth1 && correctedImagePoint.y() <= frameHeight1)
1073  {
1074  CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, camera->width(), camera->height(), cameraFramePaddingElements, correctedImagePoint, rectifiedPixel);
1075  }
1076  else
1077  {
1078  memcpy(rectifiedPixel, outsideFrameColor, sizeof(uint8_t) * tChannels);
1079  }
1080 
1081  rectifiedPixel += tChannels;
1082  }
1083 
1084  rectifiedPixel += rectifiedFramePaddingElements;
1085  }
1086 }
1087 
1088 template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1089 void FrameRectification::triangleObjectIF8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_world, const Triangle2* triangle2, const Triangle3* triangle3, uint8_t* targetFrame, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const uint8_t* outsideFrameColor, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
1090 {
1091  static_assert(tChannels >= 1u, "Invalid channel number!");
1092 
1093  ocean_assert(cameraFrame != nullptr && targetFrame != nullptr && triangle2 != nullptr && triangle3 != nullptr);
1094  ocean_assert(camera != nullptr && camera->isValid() && flippedCamera_T_world != nullptr && flippedCamera_T_world->isValid());
1095  ocean_assert(targetWidth >= 0u &&targetHeight >= 0u);
1096 
1097  ocean_assert(firstTargetRow + numberTargetRows <= targetHeight);
1098 
1099  const Scalar frameWidth1 = Scalar(camera->width() - 1u);
1100  const Scalar frameHeight1 = Scalar(camera->height() - 1u);
1101 
1102  const unsigned int targetStrideElements = targetWidth * tChannels + targetFramePaddingElements;
1103 
1104  typedef typename DataType<uint8_t, tChannels>::Type PixelType;
1105 
1106  for (unsigned int y = firstTargetRow; y < firstTargetRow + numberTargetRows; ++y)
1107  {
1108  const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar(targetHeight - 1u) - Scalar(y));
1109 
1110  uint8_t* targetPixel = targetFrame + y * targetStrideElements;
1111 
1112  for (unsigned int x = 0u; x < targetWidth; ++x)
1113  {
1114  const Vector3 barycentricTargetPosition(triangle2->cartesian2barycentric(Vector2(Scalar(x), yCorrected)));
1115 
1116  if (triangle2->isBarycentricInside(barycentricTargetPosition))
1117  {
1118  const Vector3 objectPoint(triangle3->barycentric2cartesian(barycentricTargetPosition));
1119  const Vector2 imagePoint(camera->projectToImageIF(*flippedCamera_T_world, objectPoint));
1120 
1121  const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
1122 
1123  if (correctedImagePoint.x() >= 0 && correctedImagePoint.y() >= 0 && correctedImagePoint.x() <= frameWidth1 && correctedImagePoint.y() <= frameHeight1)
1124  {
1125  CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, camera->width(), camera->height(), cameraFramePaddingElements, correctedImagePoint, targetPixel);
1126  }
1127  else
1128  {
1129  *((PixelType*)(targetPixel)) = *((const PixelType*)(outsideFrameColor));
1130  }
1131  }
1132 
1133  targetPixel += tChannels;
1134  }
1135  }
1136 }
1137 
1138 template <unsigned int tChannels>
1139 void FrameRectification::triangleObjectLookup8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFrameWidth, const unsigned int cameraFrameHeight, const unsigned int cameraFramePaddingElements, const LookupTable* lookupTable, const Triangle2* triangle2, uint8_t* targetFrame, const unsigned int targetFramePaddingElements, const uint8_t* outsideFrameColor, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
1140 {
1141  static_assert(tChannels >= 1u, "Invalid channel number!");
1142 
1143  ocean_assert(cameraFrame != nullptr && targetFrame != nullptr && triangle2 != nullptr && lookupTable && !lookupTable->isEmpty());
1144  ocean_assert(cameraFrameWidth >= 1u && cameraFrameHeight >= 1u);
1145 
1146  ocean_assert(firstTargetRow + numberTargetRows <= (unsigned int)(lookupTable->sizeY()));
1147 
1148  const Scalar cameraFrameWidth1 = Scalar(cameraFrameWidth - 1u);
1149  const Scalar cameraFrameHeight1 = Scalar(cameraFrameHeight - 1u);
1150 
1151  const unsigned int targetFrameWidth = (unsigned int)(lookupTable->sizeX());
1152 
1153  const unsigned int targetFrameStrideElements = targetFrameWidth * tChannels + targetFramePaddingElements;
1154 
1155  typedef typename DataType<uint8_t, tChannels>::Type PixelType;
1156 
1157  for (unsigned int y = firstTargetRow; y < firstTargetRow + numberTargetRows; ++y)
1158  {
1159  uint8_t* targetPixel = targetFrame + y * targetFrameStrideElements;
1160 
1161  for (unsigned int x = 0u; x < targetFrameWidth; ++x)
1162  {
1163  if (triangle2->isInside(Vector2(Scalar(x), Scalar(y))))
1164  {
1165  const Vector2 inputPosition(lookupTable->bilinearValue(Scalar(x), Scalar(y)));
1166 
1167  if (inputPosition.x() >= 0 && inputPosition.y() >= 0 && inputPosition.x() <= cameraFrameWidth1 && inputPosition.y() <= cameraFrameHeight1)
1168  {
1169  CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, cameraFrameWidth, cameraFrameHeight, cameraFramePaddingElements, inputPosition, targetPixel);
1170  }
1171  else
1172  {
1173  *((PixelType*)(targetPixel)) = *((PixelType*)(outsideFrameColor));
1174  }
1175  }
1176 
1177  targetPixel += tChannels;
1178  }
1179  }
1180 }
1181 
1182 template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1183 void FrameRectification::planarRectangleObjectMaskIF8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_world, const Vector3* rectangleOrigin, const Vector3* rectangleHorizontal, const Vector3* rectangleVertical, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, const uint8_t maskValue, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
1184 {
1185  static_assert(tChannels >= 1u, "Invalid channel number!");
1186 
1187  ocean_assert(cameraFrame != nullptr);
1188  ocean_assert(camera != nullptr && camera->isValid());
1189  ocean_assert(flippedCamera_T_world != nullptr && flippedCamera_T_world->isValid());
1190  ocean_assert(rectangleOrigin != nullptr && rectangleHorizontal != nullptr && rectangleVertical != nullptr);
1191  ocean_assert(targetFrame != nullptr && targetMask != nullptr);
1192  ocean_assert(targetWidth > 0u && targetHeight > 0u);
1193 
1194  ocean_assert(firstTargetRow + numberTargetRows <= targetHeight);
1195 
1196  const unsigned int targetFrameStrideElements = targetWidth * tChannels + targetFramePaddingElements;
1197  const unsigned int targetMaskStrideElements = targetWidth + targetMaskPaddingElements;
1198 
1199  const Scalar frameWidth1 = Scalar(camera->width() - 1u);
1200  const Scalar frameHeight1 = Scalar(camera->height() - 1u);
1201 
1202  const Scalar invTargetWidth = Scalar(1) / Scalar(targetWidth);
1203  const Scalar invTargetHeight = Scalar(1) / Scalar(targetHeight);
1204 
1205  uint8_t* targetPixel = targetFrame + firstTargetRow * targetFrameStrideElements;
1206 
1207  targetMask += firstTargetRow * targetMaskStrideElements;
1208 
1209  Vectors3 objectPoints(targetWidth);
1210  Vectors2 imagePoints(targetWidth);
1211 
1212  for (unsigned int y = firstTargetRow; y < firstTargetRow + numberTargetRows; ++y)
1213  {
1214  const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar(targetHeight - 1u) - Scalar(y));
1215 
1216  for (unsigned int x = 0u; x < targetWidth; ++x)
1217  {
1218  objectPoints[x] = Vector3(*rectangleOrigin + *rectangleHorizontal * (Scalar(x) * invTargetWidth) + *rectangleVertical * (Scalar(yCorrected) * invTargetHeight));
1219  }
1220 
1221  camera->projectToImageIF(*flippedCamera_T_world, objectPoints.data(), objectPoints.size(), imagePoints.data());
1222 
1223  for (unsigned int x = 0u; x < targetWidth; ++x)
1224  {
1225  const Vector2& imagePoint = imagePoints[x];
1226 
1227  const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
1228 
1229  if (correctedImagePoint.x() >= 0 && correctedImagePoint.y() >= 0 && correctedImagePoint.x() <= frameWidth1 && correctedImagePoint.y() <= frameHeight1)
1230  {
1231  CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, camera->width(), camera->height(), cameraFramePaddingElements, correctedImagePoint, targetPixel);
1232  *targetMask = maskValue;
1233  }
1234  else
1235  {
1236  *targetMask = 0xFF - maskValue;
1237  }
1238 
1239  targetPixel += tChannels;
1240  ++targetMask;
1241  }
1242 
1243  targetPixel += targetFramePaddingElements;
1244  targetMask += targetMaskPaddingElements;
1245  }
1246 }
1247 
1248 template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1249 void FrameRectification::arbitraryRectangleObjectMaskIF8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_world, const Vector3* rectangle, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, const uint8_t maskValue, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
1250 {
1251  static_assert(tChannels >= 1u, "Invalid channel number!");
1252 
1253  ocean_assert(cameraFrame != nullptr);
1254  ocean_assert(camera != nullptr && camera->isValid());
1255  ocean_assert(flippedCamera_T_world != nullptr && flippedCamera_T_world->isValid());
1256  ocean_assert(rectangle != nullptr);
1257  ocean_assert(targetFrame != nullptr && targetMask != nullptr);
1258  ocean_assert(targetWidth > 0u && targetHeight > 0u);
1259 
1260  ocean_assert(firstTargetRow + numberTargetRows <= targetHeight);
1261 
1262  const unsigned int targetFrameStrideElements = targetWidth * tChannels + targetFramePaddingElements;
1263  const unsigned int targetMaskStrideElements = targetWidth + targetMaskPaddingElements;
1264 
1265  const Scalar frameWidth1 = Scalar(camera->width() - 1u);
1266  const Scalar frameHeight1 = Scalar(camera->height() - 1u);
1267 
1268  const Scalar invTargetWidth = Scalar(1) / Scalar(targetWidth);
1269  const Scalar invTargetHeight = Scalar(1) / Scalar(targetHeight);
1270 
1271  uint8_t* targetPixel = targetFrame + firstTargetRow * targetFrameStrideElements;
1272 
1273  targetMask += firstTargetRow * targetMaskStrideElements;
1274 
1275  Vectors3 objectPoints(targetWidth);
1276  Vectors2 imagePoints(targetWidth);
1277 
1278  const Vector3 direction10 = rectangle[1] - rectangle[0];
1279  const Vector3 direction23 = rectangle[2] - rectangle[3];
1280 
1281  for (unsigned int y = firstTargetRow; y < firstTargetRow + numberTargetRows; ++y)
1282  {
1283  const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar(targetHeight - 1u) - Scalar(y));
1284 
1285  const Vector3 left(rectangle[0] + direction10 * (Scalar(yCorrected) * invTargetHeight));
1286  const Vector3 right(rectangle[3] + direction23 * (Scalar(yCorrected) * invTargetHeight));
1287 
1288  for (unsigned int x = 0u; x < targetWidth; ++x)
1289  {
1290  objectPoints[x] = left + (right - left) * (Scalar(x) * invTargetWidth);
1291  }
1292 
1293  camera->projectToImageIF(*flippedCamera_T_world, objectPoints.data(), objectPoints.size(), imagePoints.data());
1294 
1295  for (unsigned int x = 0u; x < targetWidth; ++x)
1296  {
1297  const Vector2& imagePoint = imagePoints[x];
1298 
1299  const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
1300 
1301  if (correctedImagePoint.x() >= 0 && correctedImagePoint.y() >= 0 && correctedImagePoint.x() <= frameWidth1 && correctedImagePoint.y() <= frameHeight1)
1302  {
1303  CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, camera->width(), camera->height(), cameraFramePaddingElements, correctedImagePoint, targetPixel);
1304  *targetMask = maskValue;
1305  }
1306  else
1307  {
1308  *targetMask = 0xFF - maskValue;
1309  }
1310 
1311  targetPixel += tChannels;
1312  ++targetMask;
1313  }
1314 
1315  targetPixel += targetFramePaddingElements;
1316  targetMask += targetMaskPaddingElements;
1317  }
1318 }
1319 
1320 template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1321 void FrameRectification::triangleObjectMaskIF8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera* camera, const HomogenousMatrix4* flippedCamera_T_world, const Triangle2* triangle2, const Triangle3* triangle3, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, const uint8_t maskValue, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
1322 {
1323  static_assert(tChannels >= 1u, "Invalid channel number!");
1324 
1325  ocean_assert(cameraFrame != nullptr && camera != nullptr && camera->isValid());
1326  ocean_assert(flippedCamera_T_world != nullptr && flippedCamera_T_world->isValid());
1327 
1328  ocean_assert(triangle2 != nullptr && triangle2->isValid());
1329  ocean_assert(triangle3 != nullptr && triangle2->isValid());
1330 
1331  ocean_assert(targetFrame != nullptr && targetMask != nullptr);
1332 
1333  ocean_assert(targetWidth > 0u && targetHeight > 0u);
1334  ocean_assert(firstTargetRow + numberTargetRows <= targetHeight);
1335 
1336  const Scalar frameWidth1 = Scalar(camera->width() - 1u);
1337  const Scalar frameHeight1 = Scalar(camera->height() - 1u);
1338 
1339  const unsigned int targetFrameStrideElements = targetWidth * tChannels + targetFramePaddingElements;
1340  const unsigned int targetMaskStrideElements = targetWidth + targetMaskPaddingElements;
1341 
1342  uint8_t* targetPixel = targetFrame + firstTargetRow * targetFrameStrideElements;
1343 
1344  targetMask += firstTargetRow * targetMaskStrideElements;
1345 
1346  for (unsigned int y = firstTargetRow; y < firstTargetRow + numberTargetRows; ++y)
1347  {
1348  const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar(targetHeight - 1u) - Scalar(y));
1349 
1350  for (unsigned int x = 0u; x < targetWidth; ++x)
1351  {
1352  const Vector3 barycentricTargetPosition(triangle2->cartesian2barycentric(Vector2(Scalar(x), yCorrected)));
1353 
1354  if (triangle2->isBarycentricInside(barycentricTargetPosition))
1355  {
1356  const Vector3 objectPoint(triangle3->barycentric2cartesian(barycentricTargetPosition));
1357  const Vector2 imagePoint(camera->projectToImageIF(*flippedCamera_T_world, objectPoint));
1358 
1359  const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
1360 
1361  if (correctedImagePoint.x() >= 0 && correctedImagePoint.y() >= 0 && correctedImagePoint.x() <= frameWidth1 && correctedImagePoint.y() <= frameHeight1)
1362  {
1363  CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, camera->width(), camera->height(), cameraFramePaddingElements, correctedImagePoint, targetPixel);
1364  *targetMask = maskValue;
1365  }
1366  else
1367  {
1368  *targetMask = 0xFF - maskValue;
1369  }
1370  }
1371 
1372  targetPixel += tChannels;
1373  ++targetMask;
1374  }
1375 
1376  targetPixel += targetFramePaddingElements;
1377  targetMask += targetMaskPaddingElements;
1378  }
1379 }
1380 
1381 template <unsigned int tChannels>
1382 void FrameRectification::triangleObjectMaskLookup8BitPerChannelSubset(const uint8_t* cameraFrame, const unsigned int cameraFrameWidth, const unsigned int cameraFrameHeight, const unsigned int cameraFramePaddingElements, const LookupTable* lookupTable, const Triangle2* triangle2, uint8_t* targetFrame, uint8_t* targetMask, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, const uint8_t maskValue, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
1383 {
1384  static_assert(tChannels >= 1u, "Invalid channel number!");
1385 
1386  ocean_assert(cameraFrame != nullptr && cameraFrameWidth >= 1u && cameraFrameHeight >= 1u);
1387  ocean_assert(triangle2 != nullptr && lookupTable && !lookupTable->isEmpty());
1388 
1389  ocean_assert(targetFrame != nullptr && targetMask != nullptr);
1390 
1391  ocean_assert(firstTargetRow + numberTargetRows <= (unsigned int)(lookupTable->sizeY()));
1392 
1393  const unsigned int targetFrameStrideElements = (unsigned int)(lookupTable->sizeX()) * tChannels + targetFramePaddingElements;
1394  const unsigned int targetMaskStrideElements = (unsigned int)(lookupTable->sizeX()) + targetMaskPaddingElements;
1395 
1396  const Scalar cameraFrameWidth1 = Scalar(cameraFrameWidth - 1u);
1397  const Scalar cameraFrameHeight1 = Scalar(cameraFrameHeight - 1u);
1398 
1399  uint8_t* targetPixel = targetFrame + firstTargetRow * targetFrameStrideElements;
1400 
1401  targetMask += firstTargetRow * targetMaskStrideElements;
1402 
1403  for (unsigned int y = firstTargetRow; y < firstTargetRow + numberTargetRows; ++y)
1404  {
1405  for (unsigned int x = 0u; x < (unsigned int)(lookupTable->sizeX()); ++x)
1406  {
1407  if (triangle2->isInside(Vector2(Scalar(x), Scalar(y))))
1408  {
1409  const Vector2 inputPosition(lookupTable->bilinearValue(Scalar(x), Scalar(y)));
1410 
1411  if (inputPosition.x() >= 0 && inputPosition.y() >= 0 && inputPosition.x() <= cameraFrameWidth1 && inputPosition.y() <= cameraFrameHeight1)
1412  {
1413  CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, cameraFrameWidth, cameraFrameHeight, cameraFramePaddingElements, inputPosition, targetPixel);
1414  *targetMask = maskValue;
1415  }
1416  else
1417  {
1418  *targetMask = 0xFFu - maskValue;
1419  }
1420  }
1421 
1422  targetPixel += tChannels;
1423  ++targetMask;
1424  }
1425 
1426  targetPixel += targetFramePaddingElements;
1427  targetMask += targetMaskPaddingElements;
1428  }
1429 }
1430 
1431 }
1432 
1433 }
1434 
1435 }
1436 
1437 #endif // META_OCEAN_CV_ADVANCED_FRAME_RECTIFICATION_H
This class implements the abstract base class for all AnyCamera objects.
Definition: AnyCamera.h:130
virtual unsigned int width() const =0
Returns the width of the camera image.
virtual VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const =0
Projects a 3D object point into the camera frame.
virtual unsigned int height() const =0
Returns the height of the camera image.
virtual bool isValid() const =0
Returns whether this camera is valid.
The following comfort class provides comfortable functions simplifying prototyping applications but a...
Definition: FrameRectification.h:53
static bool triangleObject(const Frame &cameraFrame, const AnyCamera &camera, const HomogenousMatrix4 &world_T_camera, const Triangle2 &triangle2, const Triangle3 &triangle3, Frame &targetFrame, Worker *worker=nullptr, const uint8_t *outsideFrameColor=nullptr, const unsigned int approximationBinSize=0u)
Draws a 2D triangle into an image of a 3D triangle as seen in a camera image.
static bool arbitraryRectangleObject(const Frame &cameraFrame, const AnyCamera &camera, const HomogenousMatrix4 &world_T_camera, const Vector3 &rectangle0, const Vector3 &rectangle1, const Vector3 &rectangle2, const Vector3 &rectangle3, Frame &rectifiedFrame, Worker *worker=nullptr, const uint8_t *outsideFrameColor=nullptr, const unsigned int approximationBinSize=0u)
Given a camera image, an arbitrary 3D rectangle defined in world, and a sampling resolution on the re...
static bool arbitraryRectangleObjectMask(const Frame &cameraFrame, const AnyCamera &camera, const HomogenousMatrix4 &world_T_camera, const Vector3 &rectangle0, const Vector3 &rectangle1, const Vector3 &rectangle2, const Vector3 &rectangle3, Frame &targetFrame, Frame &targetMask, Worker *worker=nullptr, const uint8_t maskValue=0xFFu, const unsigned int approximationBinSize=0u)
Given a camera image, an arbitrary 3D rectangle defined in world, and a sampling resolution on the re...
static bool planarRectangleObject(const Frame &cameraFrame, const AnyCamera &camera, const HomogenousMatrix4 &world_T_camera, const Vector3 &rectangleOrigin, const Vector3 &rectangleHorizontal, const Vector3 &rectangleVertical, Frame &rectifiedFrame, Worker *worker=nullptr, const uint8_t *outsideFrameColor=nullptr, const unsigned int approximationBinSize=0u)
Given a camera image, a planar 3D rectangle defined in world, and a sampling resolution on the rectan...
static bool planarRectangleObjectMask(const Frame &cameraFrame, const AnyCamera &camera, const HomogenousMatrix4 &world_T_camera, const Vector3 &rectangleOrigin, const Vector3 &rectangleHorizontal, const Vector3 &rectangleVertical, Frame &targetFrame, Frame &targetMask, Worker *worker=nullptr, const uint8_t maskValue=0xFFu, const unsigned int approximationBinSize=0u)
Given a camera image, a planar 3D rectangle defined in world, and a sampling resolution on the rectan...
static bool triangleObjectMask(const Frame &cameraFrame, const AnyCamera &camera, const HomogenousMatrix4 &world_T_camera, const Triangle2 &triangle2, const Triangle3 &triangle3, Frame &targetFrame, Frame &targetMask, Worker *worker=nullptr, const uint8_t maskValue=0xFFu, const unsigned int approximationBinSize=0u)
Draws a 2D triangle into an image of a 3D triangle as seen in a camera image.
This class implements functions creating rectified images from frame areas or objects located in a fr...
Definition: FrameRectification.h:39
static void arbitraryRectangleObjectIF8BitPerChannelSubset(const uint8_t *cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera *camera, const HomogenousMatrix4 *flippedCamera_T_world, const Vector3 *rectangle, uint8_t *rectifiedFrame, const unsigned int rectifiedFrameWidth, const unsigned int rectifiedFrameHeight, const unsigned int rectifiedFramePaddingElements, const uint8_t *outsideFrameColor, const unsigned int firstRectifiedFrameRow, const unsigned int numberRectifiedFrameRows)
Creates a subset of the rectangle image from a specific position in 3D space.
Definition: FrameRectification.h:1035
static void planarRectangleObjectIF8BitPerChannelSubset(const uint8_t *cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera *camera, const HomogenousMatrix4 *flippedCamera_T_world, const Vector3 *rectangleOrigin, const Vector3 *rectangleHorizontal, const Vector3 *rectangleVertical, uint8_t *rectifiedFrame, const unsigned int rectifiedFrameWidth, const unsigned int rectifiedFrameHeight, const unsigned int rectifiedFramePaddingElements, const uint8_t *outsideFrameColor, const unsigned int firstRectifiedFrameRow, const unsigned int numberRectifiedFrameRows)
Creates a subset of the rectangular image of an area on a 3D plane as seen in a camera image.
Definition: FrameRectification.h:987
static void triangleObjectMaskIF8BitPerChannelSubset(const uint8_t *cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera *camera, const HomogenousMatrix4 *flippedCamera_T_world, const Triangle2 *triangle2, const Triangle3 *triangle3, uint8_t *targetFrame, uint8_t *targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, const uint8_t maskValue, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
Creates a subset of a 2D triangle in a target image from a specific 3D triangle on a 3D plane.
Definition: FrameRectification.h:1321
static Vector2 planarRectangleObjectRectifiedPosition2cameraPositionIF(const AnyCamera &anyCamera, const HomogenousMatrix4 &flippedCamera_T_world, const Vector3 &rectangleOrigin, const Vector3 &rectangleHorizontal, const Vector3 &rectangleVertical, const unsigned int rectifiedWidth, const unsigned int rectifiedHeight, const Vector2 &rectifiedPosition)
Converts the pixel position defined in the rectified frame to the pixel position defined in the camer...
Definition: FrameRectification.h:551
static void arbitraryRectangleObjectIF8BitPerChannel(const uint8_t *cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera &camera, const HomogenousMatrix4 &flippedCamera_T_world, const Vector3 &rectangle0, const Vector3 &rectangle1, const Vector3 &rectangle2, const Vector3 &rectangle3, uint8_t *rectifiedFrame, const unsigned int rectifiedFrameWidth, const unsigned int rectifiedFrameHeight, const unsigned int rectifiedFramePaddingElements, Worker *worker=nullptr, const uint8_t *outsideFrameColor=nullptr, const unsigned int approximationBinSize=0u)
Given a camera image, an arbitrary 3D rectangle defined in world, and a sampling resolution on the re...
Definition: FrameRectification.h:622
static void planarRectangleObjectIF8BitPerChannel(const uint8_t *cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera &camera, const HomogenousMatrix4 &flippedCamera_T_world, const Vector3 &rectangleOrigin, const Vector3 &rectangleHorizontal, const Vector3 &rectangleVertical, uint8_t *rectifiedFrame, const unsigned int rectifiedFrameWidth, const unsigned int rectifiedFrameHeight, const unsigned int rectifiedFramePaddingElements, Worker *worker=nullptr, const uint8_t *outsideFrameColor=nullptr, const unsigned int approximationBinSize=0u)
Given a camera image, a planar 3D rectangle defined in world, and a sampling resolution on the rectan...
Definition: FrameRectification.h:571
static void triangleObjectIF8BitPerChannel(const uint8_t *cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera &camera, const HomogenousMatrix4 &flippedCamera_T_world, const Triangle2 &triangle2, const Triangle3 &triangle3, uint8_t *targetFrame, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetPaddingElements, Worker *worker=nullptr, const uint8_t *outsideFrameColor=nullptr, const unsigned int approximationBinSize=0u)
Draws a 2D triangle into an image of a 3D triangle as seen in a camera image.
Definition: FrameRectification.h:675
static void triangleObjectIF8BitPerChannelSubset(const uint8_t *cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera *camera, const HomogenousMatrix4 *flippedCamera_T_world, const Triangle2 *triangle2, const Triangle3 *triangle3, uint8_t *targetFrame, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const uint8_t *outsideFrameColor, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
Draws a subset of a 2D triangle into a target frame.
Definition: FrameRectification.h:1089
static void arbitraryRectangleObjectIFLookupTable(const AnyCamera &anyCamera, const HomogenousMatrix4 &flippedCamera_T_world, const Vector3 &rectangle0, const Vector3 &rectangle1, const Vector3 &rectangle2, const Vector3 &rectangle3, LookupTable &lookupTable)
Creates an interpolation lookup table for a rectification of an arbitrary rectangle object (a 2D text...
Definition: FrameRectification.h:927
static void planarRectangleObjectMaskIF8BitPerChannel(const uint8_t *cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera &camera, const HomogenousMatrix4 &flippedCamera_T_world, const Vector3 &rectangleOrigin, const Vector3 &rectangleHorizontal, const Vector3 &rectangleVertical, uint8_t *targetFrame, uint8_t *targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, Worker *worker=nullptr, const uint8_t maskValue=0xFFu, const unsigned int approximationBinSize=0u)
Given a camera image, a planar 3D rectangle defined in world, and a sampling resolution on the rectan...
Definition: FrameRectification.h:733
LookupCorner2< Vector2 > LookupTable
Definition of a lookup table storing 2D vectors as elements.
Definition: FrameRectification.h:45
static void planarRectangleObjectIFLookupTable(const AnyCamera &anyCamera, const HomogenousMatrix4 &flippedCamera_T_world, const Vector3 &rectangleOrigin, const Vector3 &rectangleHorizontal, const Vector3 &rectangleVertical, LookupTable &lookupTable)
Creates an interpolation lookup table for a rectification of a planar rectangle object (a 2D texture ...
Definition: FrameRectification.h:889
static void planarRectangleObjectMaskIF8BitPerChannelSubset(const uint8_t *cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera *camera, const HomogenousMatrix4 *flippedCamera_T_world, const Vector3 *rectangleOrigin, const Vector3 *rectangleHorizontal, const Vector3 *rectangleVertical, uint8_t *targetFrame, uint8_t *targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, const uint8_t maskValue, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
Creates a subset of the rectangular image of an area on a 3D plane as seen in a camera image.
Definition: FrameRectification.h:1183
static void triangleObjectIFLookupTable(const AnyCamera &anyCamera, const HomogenousMatrix4 &flippedCamera_T_world, const Triangle2 &triangle2, const Triangle3 &triangle3, LookupTable &lookupTable)
Creates an interpolation lookup table for a triangle object (a 2D texture in 3D place).
Definition: FrameRectification.h:959
static void triangleObjectLookup8BitPerChannelSubset(const uint8_t *cameraFrame, const unsigned int cameraFrameWidth, const unsigned int cameraFrameHeight, const unsigned int cameraFramePaddingElements, const LookupTable *lookupTable, const Triangle2 *triangle2, uint8_t *targetFrame, const unsigned int targetFramePaddingElements, const uint8_t *outsideFrameColor, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
Draws a subset of a 2D triangle into an image of a 3D triangle as seen in a camera image.
Definition: FrameRectification.h:1139
static void triangleObjectMaskLookup8BitPerChannelSubset(const uint8_t *cameraFrame, const unsigned int cameraFrameWidth, const unsigned int cameraFrameHeight, const unsigned int cameraFramePaddingElements, const LookupTable *lookupTable, const Triangle2 *triangle2, uint8_t *targetFrame, uint8_t *targetMask, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, const uint8_t maskValue, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
Creates a subset of a 2D triangle in a target image from a specific 3D triangle on a 3D plane and app...
Definition: FrameRectification.h:1382
static void arbitraryRectangleObjectMaskIF8BitPerChannelSubset(const uint8_t *cameraFrame, const unsigned int cameraFramePaddingElements, const AnyCamera *camera, const HomogenousMatrix4 *flippedCamera_T_world, const Vector3 *rectangle, uint8_t *targetFrame, uint8_t *targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, const uint8_t maskValue, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
Creates a subset of the rectangular image from a specific position in 3D space.
Definition: FrameRectification.h:1249
static void arbitraryRectangleObjectMaskIF8BitPerChannel(const uint8_t *cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera &camera, const HomogenousMatrix4 &flippedCamera_T_world, const Vector3 &rectangle0, const Vector3 &rectangle1, const Vector3 &rectangle2, const Vector3 &rectangle3, uint8_t *targetFrame, uint8_t *targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, Worker *worker=nullptr, const uint8_t maskValue=0xFFu, const unsigned int approximationBinSize=0u)
Given a camera image, an arbitrary 3D rectangle defined in world, and a sampling resolution on the re...
Definition: FrameRectification.h:782
static void triangleObjectMaskIF8BitPerChannel(const uint8_t *cameraFrame, const unsigned int cameraFramePaddingElements, const FrameType::PixelOrigin pixelOrigin, const AnyCamera &camera, const HomogenousMatrix4 &flippedCamera_T_world, const Triangle2 &triangle2, const Triangle3 &triangle3, uint8_t *targetFrame, uint8_t *targetMask, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetFramePaddingElements, const unsigned int targetMaskPaddingElements, Worker *worker=nullptr, const uint8_t maskValue=0xFFu, const unsigned int approximationBinSize=0u)
Draws a 2D triangle into an image of a 3D triangle as seen in a camera image.
Definition: FrameRectification.h:833
static Caller< void > createStatic(typename StaticFunctionPointerMaker< void, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass >::Type function)
Creates a new caller container for a static function with no function parameter.
Definition: Caller.h:2876
Template class allowing to define an array of data types.
Definition: DataType.h:27
This class implements Ocean's image class.
Definition: Frame.h:1760
PixelOrigin
Defines different types of frame origin positions.
Definition: Frame.h:1014
@ ORIGIN_UPPER_LEFT
The first pixel lies in the upper left corner, the last pixel in the lower right corner.
Definition: Frame.h:1018
const T * data() const
Returns a pointer to the internal values.
Definition: HomogenousMatrix4.h:1843
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition: HomogenousMatrix4.h:1806
size_t sizeY() const
Returns the vertical dimension of this lookup object.
Definition: Lookup2.h:947
size_t sizeX() const
Returns the horizontal dimension of this lookup object.
Definition: Lookup2.h:941
bool isEmpty() const
Returns whether this lookup object does not hold any lookup bin.
Definition: Lookup2.h:1009
size_t binsY() const
Returns the number of vertical bins of this lookup object.
Definition: Lookup2.h:959
size_t binsX() const
Returns the number of horizontal bins of this lookup object.
Definition: Lookup2.h:953
This class implements a 2D lookup object with values at the bins' corners defining the individual loo...
Definition: Lookup2.h:636
void setBinTopLeftCornerValue(const size_t binX, const size_t binY, const T &value)
Sets the value of one specific lookup bin's top left corner.
Definition: Lookup2.h:2128
T bilinearValue(const TScalar x, const TScalar y) const
Applies a lookup for a specific position in this lookup object.
Definition: Lookup2.h:1815
TScalar binTopLeftCornerPositionY(const size_t binY) const
Returns the vertical corner position of a specific bin corner (the top left corner) in relation to th...
Definition: Lookup2.h:1775
TScalar binTopLeftCornerPositionX(const size_t binX) const
Returns the horizontal corner position of a specific bin corner (the top left corner) in relation to ...
Definition: Lookup2.h:1764
This class implements a 2D triangle with Cartesian coordinates.
Definition: Triangle2.h:81
VectorT3< T > cartesian2barycentric(const VectorT2< T > &cartesian) const
Returns the barycentric coordinate of a given 2D Cartesian coordinate defined in relation to this tri...
Definition: Triangle2.h:767
bool isInside(const VectorT2< T > &point) const
Returns whether a given point lies inside this triangle.
Definition: Triangle2.h:730
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
VectorT3< T > barycentric2cartesian(const VectorT3< T > &barycentric) const
Returns the 3D cartesian coordinate of a given barycentric coordinate defined in relation to this tri...
Definition: Triangle3.h:296
static bool isBarycentricInside(const VectorT3< T > &barycentricPoint)
Returns whether a given point, specified as barycentric coordinate, lies inside a triangle.
Definition: Triangle.h:69
const T & x() const noexcept
Returns the x value.
Definition: Vector2.h:698
const T & y() const noexcept
Returns the y value.
Definition: Vector2.h:710
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.
T minmax(const T &lowerBoundary, const T &value, const T &upperBoundary)
This function fits a given parameter into a specified value range.
Definition: base/Utilities.h:903
float Scalar
Definition of a scalar type.
Definition: Math.h:128
VectorT3< Scalar > Vector3
Definition of a 3D vector.
Definition: Vector3.h:22
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition: Vector2.h:64
std::vector< Vector3 > Vectors3
Definition of a vector holding Vector3 objects.
Definition: Vector3.h:65
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15