Ocean
Loading...
Searching...
No Matches
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"
24
25namespace Ocean
26{
27
28namespace CV
29{
30
31namespace 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 */
38class 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
550template <bool tPixelOriginUpperLeft>
551Vector2 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
570template <unsigned int tChannels>
571inline 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
621template <unsigned int tChannels>
622inline 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
674template <unsigned int tChannels>
675inline 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
732template <unsigned int tChannels>
733inline 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
781template <unsigned int tChannels>
782inline 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
832template <unsigned int tChannels>
833inline 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
888template <bool tPixelOriginUpperLeft>
889void 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
926template <bool tPixelOriginUpperLeft>
927void 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
958template <bool tPixelOriginUpperLeft>
959void 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
986template <unsigned int tChannels, bool tPixelOriginUpperLeft>
987void 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
1034template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1035void 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
1088template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1089void 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
1138template <unsigned int tChannels>
1139void 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
1182template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1183void 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
1248template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1249void 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
1320template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1321void 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
1381template <unsigned int tChannels>
1382void 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 unsigned int height() const =0
Returns the height of the camera image.
virtual VectorT2< T > projectToImageIF(const VectorT3< T > &objectPoint) const =0
Projects a 3D object point into the camera frame.
virtual bool isValid() const =0
Returns whether this camera is valid.
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
This class implements Ocean's image class.
Definition Frame.h:1808
PixelOrigin
Defines different types of frame origin positions.
Definition Frame.h:1046
@ ORIGIN_UPPER_LEFT
The first pixel lies in the upper left corner, the last pixel in the lower right corner.
Definition Frame.h:1050
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:710
const T & y() const noexcept
Returns the y value.
Definition Vector2.h:722
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:129
VectorT3< Scalar > Vector3
Definition of a 3D vector.
Definition Vector3.h:29
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition Vector2.h:64
std::vector< Vector3 > Vectors3
Definition of a vector holding Vector3 objects.
Definition Vector3.h:65
The namespace covering the entire Ocean framework.
Definition Accessor.h:15
Default definition of a type with tBytes bytes.
Definition DataType.h:32