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 * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the rectified frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
457 */
458 template <unsigned int tChannels, bool tPixelOriginUpperLeft>
459 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);
460
461 /**
462 * Creates a subset of the rectangular image of an area on a 3D plane as seen in a camera image.
463 * @param cameraFrame The frame that captures the 3D plane, must be valid
464 * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
465 * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
466 * @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
467 * @param rectangleOrigin Origin of the planar rectangle object in world units
468 * @param rectangleHorizontal Vector defining the horizontal edge of the rectangle object (beginning at the origin) in world units
469 * @param rectangleVertical Vector defining the vertical edge of the rectangle object (beginning at the origin and perpendicular to the rectangleHorizontal vector) in world units
470 * @param targetFrame The resulting target image, must be valid
471 * @param targetMask The resulting mask, must be valid
472 * @param targetWidth Width of the target image, in pixel, with range [1, infinity)
473 * @param targetHeight Height of the target image, in pixel, with range [1, infinity)
474 * @param targetFramePaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
475 * @param targetMaskPaddingElements The number of padding elements at the end of each row target mask row, in elements, with range [0, infinity)
476 * @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)
477 * @param firstTargetRow First target row to be handled
478 * @param numberTargetRows Number of target rows to be handled
479 * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
480 * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the target frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
481 */
482 template <unsigned int tChannels, bool tPixelOriginUpperLeft>
483 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);
484
485 /**
486 * Creates a subset of the rectangular image from a specific position in 3D space.
487 * @param cameraFrame The frame that captures the 3D plane, must be valid
488 * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
489 * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
490 * @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
491 * @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
492 * @param targetFrame The resulting target image, must be valid
493 * @param targetMask The resulting mask, must be valid
494 * @param targetWidth Width of the target image, in pixel, with range [1, infinity)
495 * @param targetHeight Height of the target image, in pixel, with range [1, infinity)
496 * @param targetFramePaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
497 * @param targetMaskPaddingElements The number of padding elements at the end of each row target mask row, in elements, with range [0, infinity)
498 * @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)
499 * @param firstTargetRow First target row to be handled, with range [0, targetHeight - 1]
500 * @param numberTargetRows The number of target rows to be handled, with range [1, targetHeight - firstTargetRow]
501 * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
502 * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the target frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
503 */
504 template <unsigned int tChannels, bool tPixelOriginUpperLeft>
505 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);
506
507 /**
508 * Creates a subset of a 2D triangle in a target image from a specific 3D triangle on a 3D plane.
509 * @param cameraFrame The frame that captures the 3D plane, must be valid
510 * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
511 * @param camera The camera profile defining the projection of the camera frame, must have the same resolution as the camera frame, must be valid
512 * @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
513 * @param triangle2 2D triangle defined in the target frame, must be valid
514 * @param triangle3 3D triangle defined in the world coordinate system, must be valid
515 * @param targetFrame The resulting target image, must be valid
516 * @param targetMask The resulting mask, must be valid
517 * @param targetWidth Width of the target image, in pixel, with range [1, infinity)
518 * @param targetHeight Height of the target image, in pixel, with range [1, infinity)
519 * @param targetFramePaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
520 * @param targetMaskPaddingElements The number of padding elements at the end of each row target mask row, in elements, with range [0, infinity)
521 * @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)
522 * @param firstTargetRow First target row to be handled, with range [0, targetHeight - 1]
523 * @param numberTargetRows The number of target rows to be handled, with range [1, targetHeight - firstTargetRow]
524 * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
525 * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the target frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
526 */
527 template <unsigned int tChannels, bool tPixelOriginUpperLeft>
528 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);
529
530 /**
531 * 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.
532 * @param cameraFrame The frame that captures the 3D plane, must be valid
533 * @param cameraFrameWidth The width of the camera frame, in pixels, with range [1, infinity)
534 * @param cameraFrameHeight The height of the camera frame, in pixels, with range [1, infinity)
535 * @param cameraFramePaddingElements The number of padding elements at the end of each camera frame row, in elements, with range [0, infinity)
536 * @param lookupTable The lookup table allowing to approximate the triangle positions
537 * @param triangle2 2D triangle defined in the target frame
538 * @param targetFrame The resulting target image, must be valid
539 * @param targetMask The resulting mask, must be valid
540 * @param targetFramePaddingElements The number of padding elements at the end of each target frame row, in elements, with range [0, infinity)
541 * @param targetMaskPaddingElements The number of padding elements at the end of each row target mask row, in elements, with range [0, infinity)
542 * @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)
543 * @param firstTargetRow First target row to be handled, with range [0, targetHeight - 1]
544 * @param numberTargetRows The number of target rows to be handled, with range [1, targetHeight - firstTargetRow]
545 * @tparam tChannels Number of data channels of the given frame, with range [1, infinity)
546 * @tparam tPixelOriginUpperLeft True, if the pixel origin of the frame (and the rectified frame) is FrameType::ORIGIN_UPPER_LEFT, False otherwise
547 */
548 template <unsigned int tChannels, bool tPixelOriginUpperLeft>
549 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);
550};
551
552template <bool tPixelOriginUpperLeft>
553Vector2 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)
554{
555 ocean_assert(anyCamera.isValid() && flippedCamera_T_world.isValid());
556 ocean_assert(rectifiedWidth != 0u && rectifiedHeight != 0u);
557
558 ocean_assert(rectifiedPosition.x() >= 0 && rectifiedPosition.x() < Scalar(rectifiedWidth));
559 ocean_assert(rectifiedPosition.y() >= 0 && rectifiedPosition.y() < Scalar(rectifiedHeight));
560
561 const Scalar yCorrected = tPixelOriginUpperLeft ? rectifiedPosition.y() : (Scalar(rectifiedHeight - 1u) - rectifiedPosition.y());
562
563 // the actual pixel position is located at the upper left corner of each individual pixel
564 const Vector3 objectPoint(rectangleOrigin + rectangleHorizontal * (rectifiedPosition.x() / Scalar(rectifiedWidth)) + rectangleVertical * (yCorrected / Scalar(rectifiedHeight)));
565 const Vector2 cameraPoint(anyCamera.projectToImageIF(flippedCamera_T_world, objectPoint));
566
567 const Vector2 correctedCameraPoint(cameraPoint.x(), tPixelOriginUpperLeft ? cameraPoint.y() : (Scalar(anyCamera.height() - 1u) - cameraPoint.y()));
568
569 return correctedCameraPoint;
570}
571
572template <unsigned int tChannels>
573inline 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)
574{
575 static_assert(tChannels > 0u, "Invalid frame channel number!");
576
577 const uint8_t zeroValue[tChannels] = {0x00};
578
579 if (approximationBinSize == 0u)
580 {
581 if (worker)
582 {
583 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
584 {
585 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);
586 }
587 else
588 {
589 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);
590 }
591 }
592 else
593 {
594 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
595 {
596 planarRectangleObjectIF8BitPerChannelSubset<tChannels, true>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &rectangleOrigin, &rectangleHorizontal, &rectangleVertical, rectifiedFrame, rectifiedFrameWidth, rectifiedFrameHeight, rectifiedFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, rectifiedFrameHeight);
597 }
598 else
599 {
600 planarRectangleObjectIF8BitPerChannelSubset<tChannels, false>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &rectangleOrigin, &rectangleHorizontal, &rectangleVertical, rectifiedFrame, rectifiedFrameWidth, rectifiedFrameHeight, rectifiedFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, rectifiedFrameHeight);
601 }
602 }
603 }
604 else
605 {
606 const unsigned int binsX = minmax(1u, rectifiedFrameWidth / approximationBinSize, rectifiedFrameWidth / 4u);
607 const unsigned int binsY = minmax(1u, rectifiedFrameHeight / approximationBinSize, rectifiedFrameHeight / 4u);
608 LookupTable lookupTable(rectifiedFrameWidth, rectifiedFrameHeight, binsX, binsY);
609
610 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
611 {
612 planarRectangleObjectIFLookupTable<true>(camera, flippedCamera_T_world, rectangleOrigin, rectangleHorizontal, rectangleVertical, lookupTable);
613 }
614 else
615 {
616 planarRectangleObjectIFLookupTable<false>(camera, flippedCamera_T_world, rectangleOrigin, rectangleHorizontal, rectangleVertical, lookupTable);
617 }
618
619 CV::FrameInterpolatorBilinear::lookup<uint8_t, tChannels>(cameraFrame, camera.width(), camera.height(), lookupTable, false, outsideFrameColor ? outsideFrameColor : zeroValue, rectifiedFrame, cameraFramePaddingElements, rectifiedFramePaddingElements, worker);
620 }
621}
622
623template <unsigned int tChannels>
624inline 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)
625{
626 static_assert(tChannels > 0u, "Invalid frame channel number!");
627
628 const uint8_t zeroValue[tChannels] = {0x00};
629
630 if (approximationBinSize == 0u)
631 {
632 const Vector3 rectangle[4] = {rectangle0, rectangle1, rectangle2, rectangle3};
633
634 if (worker)
635 {
636 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
637 {
638 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);
639 }
640 else
641 {
642 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);
643 }
644 }
645 else
646 {
647 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
648 {
649 arbitraryRectangleObjectIF8BitPerChannelSubset<tChannels, true>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, rectangle, rectifiedFrame, rectifiedFrameWidth, rectifiedFrameHeight, rectifiedFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, rectifiedFrameHeight);
650 }
651 else
652 {
653 arbitraryRectangleObjectIF8BitPerChannelSubset<tChannels, false>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, rectangle, rectifiedFrame, rectifiedFrameWidth, rectifiedFrameHeight, rectifiedFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, rectifiedFrameHeight);
654 }
655 }
656 }
657 else
658 {
659 const unsigned int binsX = minmax(1u, rectifiedFrameWidth / approximationBinSize, rectifiedFrameWidth / 4u);
660 const unsigned int binsY = minmax(1u, rectifiedFrameHeight / approximationBinSize, rectifiedFrameHeight / 4u);
661 LookupTable lookupTable(rectifiedFrameWidth, rectifiedFrameHeight, binsX, binsY);
662
663 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
664 {
665 arbitraryRectangleObjectIFLookupTable<true>(camera, flippedCamera_T_world, rectangle0, rectangle1, rectangle2, rectangle3, lookupTable);
666 }
667 else
668 {
669 arbitraryRectangleObjectIFLookupTable<false>(camera, flippedCamera_T_world, rectangle0, rectangle1, rectangle2, rectangle3, lookupTable);
670 }
671
672 CV::FrameInterpolatorBilinear::lookup<uint8_t, tChannels>(cameraFrame, camera.width(), camera.height(), lookupTable, false, outsideFrameColor ? outsideFrameColor : zeroValue, rectifiedFrame, cameraFramePaddingElements, rectifiedFramePaddingElements, worker);
673 }
674}
675
676template <unsigned int tChannels>
677inline 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)
678{
679 static_assert(tChannels > 0u, "Invalid frame channel number!");
680
681 const uint8_t zeroValue[tChannels] = {0x00};
682
683 if (approximationBinSize == 0u)
684 {
685 if (worker)
686 {
687 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
688 {
689 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);
690 }
691 else
692 {
693 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);
694 }
695 }
696 else
697 {
698 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
699 {
700 triangleObjectIF8BitPerChannelSubset<tChannels, true>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &triangle2, &triangle3, targetFrame, targetWidth, targetHeight, targetFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, targetHeight);
701 }
702 else
703 {
704 triangleObjectIF8BitPerChannelSubset<tChannels, false>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &triangle2, &triangle3, targetFrame, targetWidth, targetHeight, targetFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, targetHeight);
705 }
706 }
707 }
708 else
709 {
710 const unsigned int binsX = minmax(1u, targetWidth / approximationBinSize, targetWidth / 4u);
711 const unsigned int binsY = minmax(1u, targetHeight / approximationBinSize, targetHeight / 4u);
712 LookupTable lookupTable(targetWidth, targetHeight, binsX, binsY);
713
714 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
715 {
716 triangleObjectIFLookupTable<true>(camera, flippedCamera_T_world, triangle2, triangle3, lookupTable);
717 }
718 else
719 {
720 triangleObjectIFLookupTable<false>(camera, flippedCamera_T_world, triangle2, triangle3, lookupTable);
721 }
722
723 if (worker)
724 {
725 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
726 {
727 worker->executeFunction(Worker::Function::createStatic(triangleObjectLookup8BitPerChannelSubset<tChannels, true>, cameraFrame, camera.width(), camera.height(), cameraFramePaddingElements, (const LookupTable*)(&lookupTable), &triangle2, targetFrame, targetFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, 0u), 0u, targetHeight, 9u, 10u, 20u);
728 }
729 else
730 {
731 worker->executeFunction(Worker::Function::createStatic(triangleObjectLookup8BitPerChannelSubset<tChannels, false>, cameraFrame, camera.width(), camera.height(), cameraFramePaddingElements, (const LookupTable*)(&lookupTable), &triangle2, targetFrame, targetFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, 0u), 0u, targetHeight, 9u, 10u, 20u);
732 }
733 }
734 else
735 {
736 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
737 {
738 triangleObjectLookup8BitPerChannelSubset<tChannels, true>(cameraFrame, camera.width(), camera.height(), cameraFramePaddingElements, &lookupTable, &triangle2, targetFrame, targetFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, targetHeight);
739 }
740 else
741 {
742 triangleObjectLookup8BitPerChannelSubset<tChannels, false>(cameraFrame, camera.width(), camera.height(), cameraFramePaddingElements, &lookupTable, &triangle2, targetFrame, targetFramePaddingElements, outsideFrameColor ? outsideFrameColor : zeroValue, 0u, targetHeight);
743 }
744 }
745 }
746}
747
748template <unsigned int tChannels>
749inline 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)
750{
751 static_assert(tChannels > 0u, "Invalid frame channel number!");
752
753 if (approximationBinSize == 0u)
754 {
755 if (worker)
756 {
757 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
758 {
759 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);
760 }
761 else
762 {
763 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);
764 }
765 }
766 else
767 {
768 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
769 {
770 planarRectangleObjectMaskIF8BitPerChannelSubset<tChannels, true>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &rectangleOrigin, &rectangleHorizontal, &rectangleVertical, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
771 }
772 else
773 {
774 planarRectangleObjectMaskIF8BitPerChannelSubset<tChannels, false>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &rectangleOrigin, &rectangleHorizontal, &rectangleVertical, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
775 }
776 }
777 }
778 else
779 {
780 const unsigned int binsX = minmax(1u, targetWidth / approximationBinSize, targetWidth / 4u);
781 const unsigned int binsY = minmax(1u, targetHeight / approximationBinSize, targetHeight / 4u);
782 LookupTable lookupTable(targetWidth, targetHeight, binsX, binsY);
783
784 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
785 {
786 planarRectangleObjectIFLookupTable<true>(camera, flippedCamera_T_world, rectangleOrigin, rectangleHorizontal, rectangleVertical, lookupTable);
787 }
788 else
789 {
790 planarRectangleObjectIFLookupTable<false>(camera, flippedCamera_T_world, rectangleOrigin, rectangleHorizontal, rectangleVertical, lookupTable);
791 }
792
793 CV::FrameInterpolatorBilinear::lookupMask8BitPerChannel<tChannels>(cameraFrame, camera.width(), camera.height(), lookupTable, false, targetFrame, targetMask, cameraFramePaddingElements, targetFramePaddingElements, targetMaskPaddingElements, worker, maskValue);
794 }
795}
796
797template <unsigned int tChannels>
798inline 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)
799{
800 static_assert(tChannels > 0u, "Invalid frame channel number!");
801
802 if (approximationBinSize == 0u)
803 {
804 const Vector3 rectangle[4] = {rectangle0, rectangle1, rectangle2, rectangle3};
805
806 if (worker)
807 {
808 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
809 {
810 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);
811 }
812 else
813 {
814 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);
815 }
816 }
817 else
818 {
819 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
820 {
821 arbitraryRectangleObjectMaskIF8BitPerChannelSubset<tChannels, true>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, rectangle, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
822 }
823 else
824 {
825 arbitraryRectangleObjectMaskIF8BitPerChannelSubset<tChannels, false>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, rectangle, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
826 }
827 }
828 }
829 else
830 {
831 const unsigned int binsX = minmax(1u, targetWidth / approximationBinSize, targetWidth / 4u);
832 const unsigned int binsY = minmax(1u, targetHeight / approximationBinSize, targetHeight / 4u);
833 LookupTable lookupTable(targetWidth, targetHeight, binsX, binsY);
834
835 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
836 {
837 arbitraryRectangleObjectIFLookupTable<true>(camera, flippedCamera_T_world, rectangle0, rectangle1, rectangle2, rectangle3, lookupTable);
838 }
839 else
840 {
841 arbitraryRectangleObjectIFLookupTable<false>(camera, flippedCamera_T_world, rectangle0, rectangle1, rectangle2, rectangle3, lookupTable);
842 }
843
844 CV::FrameInterpolatorBilinear::lookupMask8BitPerChannel<tChannels>(cameraFrame, camera.width(), camera.height(), lookupTable, false, targetFrame, targetMask, cameraFramePaddingElements, targetFramePaddingElements, targetMaskPaddingElements, worker, maskValue);
845 }
846}
847
848template <unsigned int tChannels>
849inline 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)
850{
851 static_assert(tChannels > 0u, "Invalid frame channel number!");
852
853 if (approximationBinSize == 0u)
854 {
855 if (worker)
856 {
857 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
858 {
859 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);
860 }
861 else
862 {
863 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);
864 }
865 }
866 else
867 {
868 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
869 {
870 triangleObjectMaskIF8BitPerChannelSubset<tChannels, true>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &triangle2, &triangle3, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
871 }
872 else
873 {
874 triangleObjectMaskIF8BitPerChannelSubset<tChannels, false>(cameraFrame, cameraFramePaddingElements, &camera, &flippedCamera_T_world, &triangle2, &triangle3, targetFrame, targetMask, targetWidth, targetHeight, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
875 }
876 }
877 }
878 else
879 {
880 const unsigned int binsX = minmax(1u, targetWidth / approximationBinSize, targetWidth / 4u);
881 const unsigned int binsY = minmax(1u, targetHeight / approximationBinSize, targetHeight / 4u);
882 LookupTable lookupTable(targetWidth, targetHeight, binsX, binsY);
883
884 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
885 {
886 triangleObjectIFLookupTable<true>(camera, flippedCamera_T_world, triangle2, triangle3, lookupTable);
887 }
888 else
889 {
890 triangleObjectIFLookupTable<false>(camera, flippedCamera_T_world, triangle2, triangle3, lookupTable);
891 }
892
893 if (worker)
894 {
895 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
896 {
897 worker->executeFunction(Worker::Function::createStatic(triangleObjectMaskLookup8BitPerChannelSubset<tChannels, true>, cameraFrame, camera.width(), camera.height(), cameraFramePaddingElements, (const LookupTable*)&lookupTable, &triangle2, targetFrame, targetMask, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, 0u), 0u, targetHeight, 11u, 12u, 20u);
898 }
899 else
900 {
901 worker->executeFunction(Worker::Function::createStatic(triangleObjectMaskLookup8BitPerChannelSubset<tChannels, false>, cameraFrame, camera.width(), camera.height(), cameraFramePaddingElements, (const LookupTable*)&lookupTable, &triangle2, targetFrame, targetMask, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, 0u), 0u, targetHeight, 11u, 12u, 20u);
902 }
903 }
904 else
905 {
906 if (pixelOrigin == FrameType::ORIGIN_UPPER_LEFT)
907 {
908 triangleObjectMaskLookup8BitPerChannelSubset<tChannels, true>(cameraFrame, camera.width(), camera.height(), cameraFramePaddingElements, (const LookupTable*)(&lookupTable), &triangle2, targetFrame, targetMask, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
909 }
910 else
911 {
912 triangleObjectMaskLookup8BitPerChannelSubset<tChannels, false>(cameraFrame, camera.width(), camera.height(), cameraFramePaddingElements, (const LookupTable*)(&lookupTable), &triangle2, targetFrame, targetMask, targetFramePaddingElements, targetMaskPaddingElements, maskValue, 0u, targetHeight);
913 }
914 }
915 }
916}
917
918template <bool tPixelOriginUpperLeft>
919void FrameRectification::planarRectangleObjectIFLookupTable(const AnyCamera& anyCamera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangleOrigin, const Vector3& rectangleHorizontal, const Vector3& rectangleVertical, LookupTable& lookupTable)
920{
921 ocean_assert(anyCamera.isValid() && flippedCamera_T_world.isValid());
922
923 const Scalar frameHeight1 = Scalar(anyCamera.height() - 1u);
924
925 const Scalar invRectifiedWidth = Scalar(1) / Scalar(lookupTable.sizeX());
926 const Scalar invRectifiedHeight = Scalar(1) / Scalar(lookupTable.sizeY());
927
928 Vectors3 objectPoints(lookupTable.binsX() + 1u);
929 Vectors2 imagePoints(lookupTable.binsX() + 1u);
930
931 for (unsigned int yBin = 0u; yBin <= lookupTable.binsY(); ++yBin)
932 {
933 const Scalar y = lookupTable.binTopLeftCornerPositionY(yBin);
934 const Scalar yCorrected = tPixelOriginUpperLeft ? y : (Scalar(lookupTable.sizeY() - 1) - Scalar(y));
935
936 for (unsigned int xBin = 0u; xBin <= lookupTable.binsX(); ++xBin)
937 {
938 const Scalar x = lookupTable.binTopLeftCornerPositionX(xBin);
939
940 objectPoints[xBin] = Vector3(rectangleOrigin + rectangleHorizontal * (Scalar(x) * invRectifiedWidth) + rectangleVertical * (yCorrected * invRectifiedHeight));
941 }
942
943 anyCamera.projectToImageIF(flippedCamera_T_world, objectPoints.data(), objectPoints.size(), imagePoints.data());
944
945 for (unsigned int xBin = 0u; xBin <= lookupTable.binsX(); ++xBin)
946 {
947 const Vector2& imagePoint = imagePoints[xBin];
948
949 const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
950
951 lookupTable.setBinTopLeftCornerValue(xBin, yBin, correctedImagePoint);
952 }
953 }
954}
955
956template <bool tPixelOriginUpperLeft>
957void FrameRectification::arbitraryRectangleObjectIFLookupTable(const AnyCamera& anyCamera, const HomogenousMatrix4& flippedCamera_T_world, const Vector3& rectangle0, const Vector3& rectangle1, const Vector3& rectangle2, const Vector3& rectangle3, LookupTable& lookupTable)
958{
959 ocean_assert(anyCamera.isValid() && flippedCamera_T_world.isValid());
960
961 const Scalar frameHeight1 = Scalar(anyCamera.height() - 1u);
962
963 const Scalar invRectifiedWidth = Scalar(1) / Scalar(lookupTable.sizeX());
964 const Scalar invRectifiedHeight = Scalar(1) / Scalar(lookupTable.sizeY());
965
966 for (unsigned int yBin = 0u; yBin <= lookupTable.binsY(); ++yBin)
967 {
968 const Scalar y = lookupTable.binTopLeftCornerPositionY(yBin);
969 const Scalar yCorrected = tPixelOriginUpperLeft ? y : (Scalar(lookupTable.sizeY() - 1) - Scalar(y));
970
971 const Vector3 left(rectangle0 + (rectangle1 - rectangle0) * (Scalar(yCorrected) * invRectifiedHeight));
972 const Vector3 right(rectangle3 + (rectangle2 - rectangle3) * (Scalar(yCorrected) * invRectifiedHeight));
973
974 for (unsigned int xBin = 0u; xBin <= lookupTable.binsX(); ++xBin)
975 {
976 const Scalar x = lookupTable.binTopLeftCornerPositionX(xBin);
977
978 const Vector3 objectPoint(left + (right - left) * (Scalar(x) * invRectifiedWidth));
979 const Vector2 imagePoint(anyCamera.projectToImageIF(flippedCamera_T_world, objectPoint));
980
981 const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
982
983 lookupTable.setBinTopLeftCornerValue(xBin, yBin, correctedImagePoint);
984 }
985 }
986}
987
988template <bool tPixelOriginUpperLeft>
989void FrameRectification::triangleObjectIFLookupTable(const AnyCamera& anyCamera, const HomogenousMatrix4& flippedCamera_T_world, const Triangle2& triangle2, const Triangle3& triangle3, LookupTable& lookupTable)
990{
991 ocean_assert(anyCamera.isValid() && flippedCamera_T_world.isValid());
992
993 const Scalar frameHeight1 = Scalar(anyCamera.height() - 1u);
994
995 for (unsigned int yBin = 0u; yBin <= lookupTable.binsY(); ++yBin)
996 {
997 const Scalar y = lookupTable.binTopLeftCornerPositionY(yBin);
998 const Scalar yCorrected = tPixelOriginUpperLeft ? y : (Scalar(lookupTable.sizeY() - 1) - Scalar(y));
999
1000 for (unsigned int xBin = 0u; xBin <= lookupTable.binsX(); ++xBin)
1001 {
1002 const Scalar x = lookupTable.binTopLeftCornerPositionX(xBin);
1003
1004 const Vector3 barycentricTargetPosition(triangle2.cartesian2barycentric(Vector2(x, yCorrected)));
1005
1006 const Vector3 objectPoint(triangle3.barycentric2cartesian(barycentricTargetPosition));
1007 const Vector2 imagePoint(anyCamera.projectToImageIF(flippedCamera_T_world, objectPoint));
1008
1009 const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
1010
1011 lookupTable.setBinTopLeftCornerValue(xBin, yBin, correctedImagePoint);
1012 }
1013 }
1014}
1015
1016template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1017void 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)
1018{
1019 static_assert(tChannels >= 1u, "Invalid channel number!");
1020
1021 ocean_assert(cameraFrame != nullptr && rectifiedFrame != nullptr && rectangleOrigin != nullptr && rectangleHorizontal != nullptr && rectangleVertical != nullptr);
1022 ocean_assert(camera != nullptr && camera->isValid() && flippedCamera_T_world != nullptr && flippedCamera_T_world->isValid());
1023 ocean_assert(rectifiedFrameWidth >= 1u && rectifiedFrameHeight >= 1u);
1024
1025 ocean_assert(firstRectifiedFrameRow + numberRectifiedFrameRows <= rectifiedFrameHeight);
1026
1027 const Scalar frameWidth1 = Scalar(camera->width() - 1u);
1028 const Scalar frameHeight1 = Scalar(camera->height() - 1u);
1029
1030 const Scalar invRectifiedFrameWidth = Scalar(1) / Scalar(rectifiedFrameWidth);
1031 const Scalar invRectifiedFrameHeight = Scalar(1) / Scalar(rectifiedFrameHeight);
1032
1033 const unsigned int rectifiedFrameStrideElements = rectifiedFrameWidth * tChannels + rectifiedFramePaddingElements;
1034
1035 uint8_t* rectifiedPixel = rectifiedFrame + firstRectifiedFrameRow * rectifiedFrameStrideElements;
1036
1037 for (unsigned int y = firstRectifiedFrameRow; y < firstRectifiedFrameRow + numberRectifiedFrameRows; ++y)
1038 {
1039 const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar(rectifiedFrameHeight - 1u) - Scalar(y));
1040
1041 for (unsigned int x = 0u; x < rectifiedFrameWidth; ++x)
1042 {
1043 const Vector3 objectPoint(*rectangleOrigin + *rectangleHorizontal * (Scalar(x) * invRectifiedFrameWidth) + *rectangleVertical * (yCorrected * invRectifiedFrameHeight));
1044 const Vector2 imagePoint(camera->projectToImageIF(*flippedCamera_T_world, objectPoint));
1045
1046 const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
1047
1048 if (correctedImagePoint.x() >= 0 && correctedImagePoint.y() >= 0 && correctedImagePoint.x() <= frameWidth1 && correctedImagePoint.y() <= frameHeight1)
1049 {
1050 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, camera->width(), camera->height(), cameraFramePaddingElements, correctedImagePoint, rectifiedPixel);
1051 }
1052 else
1053 {
1054 memcpy(rectifiedPixel, outsideFrameColor, sizeof(uint8_t) * tChannels);
1055 }
1056
1057 rectifiedPixel += tChannels;
1058 }
1059
1060 rectifiedPixel += rectifiedFramePaddingElements;
1061 }
1062}
1063
1064template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1065void 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)
1066{
1067 static_assert(tChannels >= 1u, "Invalid channel number!");
1068
1069 ocean_assert(cameraFrame != nullptr && rectifiedFrame != nullptr && rectangle != nullptr);
1070 ocean_assert(camera != nullptr && camera->isValid() && flippedCamera_T_world != nullptr && flippedCamera_T_world->isValid());
1071 ocean_assert(rectifiedFrameWidth >= 1u && rectifiedFrameHeight >= 1u);
1072
1073 ocean_assert(firstRectifiedFrameRow + numberRectifiedFrameRows <= rectifiedFrameHeight);
1074
1075 const Scalar frameWidth1 = Scalar(camera->width() - 1u);
1076 const Scalar frameHeight1 = Scalar(camera->height() - 1u);
1077
1078 const Scalar invRectifiedFrameWidth = Scalar(1) / Scalar(rectifiedFrameWidth);
1079 const Scalar invRectifiedFrameHeight = Scalar(1) / Scalar(rectifiedFrameHeight);
1080
1081 const unsigned int rectifiedFrameStrideElements = rectifiedFrameWidth * tChannels + rectifiedFramePaddingElements;
1082
1083 uint8_t* rectifiedPixel = rectifiedFrame + firstRectifiedFrameRow * rectifiedFrameStrideElements;
1084
1085 const Vector3 direction10 = rectangle[1] - rectangle[0];
1086 const Vector3 direction23 = rectangle[2] - rectangle[3];
1087
1088 for (unsigned int y = firstRectifiedFrameRow; y < firstRectifiedFrameRow + numberRectifiedFrameRows; ++y)
1089 {
1090 const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar(rectifiedFrameHeight - 1u) - Scalar(y));
1091
1092 const Vector3 left(rectangle[0] + direction10 * (Scalar(yCorrected) * invRectifiedFrameHeight));
1093 const Vector3 right(rectangle[3] + direction23 * (Scalar(yCorrected) * invRectifiedFrameHeight));
1094
1095 for (unsigned int x = 0u; x < rectifiedFrameWidth; ++x)
1096 {
1097 const Vector3 objectPoint(left + (right - left) * (Scalar(x) * invRectifiedFrameWidth));
1098 const Vector2 imagePoint(camera->projectToImageIF(*flippedCamera_T_world, objectPoint));
1099
1100 const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
1101
1102 if (correctedImagePoint.x() >= 0 && correctedImagePoint.y() >= 0 && correctedImagePoint.x() <= frameWidth1 && correctedImagePoint.y() <= frameHeight1)
1103 {
1104 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, camera->width(), camera->height(), cameraFramePaddingElements, correctedImagePoint, rectifiedPixel);
1105 }
1106 else
1107 {
1108 memcpy(rectifiedPixel, outsideFrameColor, sizeof(uint8_t) * tChannels);
1109 }
1110
1111 rectifiedPixel += tChannels;
1112 }
1113
1114 rectifiedPixel += rectifiedFramePaddingElements;
1115 }
1116}
1117
1118template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1119void 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)
1120{
1121 static_assert(tChannels >= 1u, "Invalid channel number!");
1122
1123 ocean_assert(cameraFrame != nullptr && targetFrame != nullptr && triangle2 != nullptr && triangle3 != nullptr);
1124 ocean_assert(camera != nullptr && camera->isValid() && flippedCamera_T_world != nullptr && flippedCamera_T_world->isValid());
1125 ocean_assert(targetWidth >= 0u &&targetHeight >= 0u);
1126
1127 ocean_assert(firstTargetRow + numberTargetRows <= targetHeight);
1128
1129 const Scalar frameWidth1 = Scalar(camera->width() - 1u);
1130 const Scalar frameHeight1 = Scalar(camera->height() - 1u);
1131
1132 const unsigned int targetStrideElements = targetWidth * tChannels + targetFramePaddingElements;
1133
1134 using PixelType = typename DataType<uint8_t, tChannels>::Type;
1135
1136 for (unsigned int y = firstTargetRow; y < firstTargetRow + numberTargetRows; ++y)
1137 {
1138 const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar(targetHeight - 1u) - Scalar(y));
1139
1140 uint8_t* targetPixel = targetFrame + y * targetStrideElements;
1141
1142 for (unsigned int x = 0u; x < targetWidth; ++x)
1143 {
1144 const Vector3 barycentricTargetPosition(triangle2->cartesian2barycentric(Vector2(Scalar(x), yCorrected)));
1145
1146 if (triangle2->isBarycentricInside(barycentricTargetPosition))
1147 {
1148 const Vector3 objectPoint(triangle3->barycentric2cartesian(barycentricTargetPosition));
1149 const Vector2 imagePoint(camera->projectToImageIF(*flippedCamera_T_world, objectPoint));
1150
1151 const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
1152
1153 if (correctedImagePoint.x() >= 0 && correctedImagePoint.y() >= 0 && correctedImagePoint.x() <= frameWidth1 && correctedImagePoint.y() <= frameHeight1)
1154 {
1155 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, camera->width(), camera->height(), cameraFramePaddingElements, correctedImagePoint, targetPixel);
1156 }
1157 else
1158 {
1159 *((PixelType*)(targetPixel)) = *((const PixelType*)(outsideFrameColor));
1160 }
1161 }
1162
1163 targetPixel += tChannels;
1164 }
1165 }
1166}
1167
1168template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1169void 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)
1170{
1171 static_assert(tChannels >= 1u, "Invalid channel number!");
1172
1173 ocean_assert(cameraFrame != nullptr && targetFrame != nullptr && triangle2 != nullptr && lookupTable && !lookupTable->isEmpty());
1174 ocean_assert(cameraFrameWidth >= 1u && cameraFrameHeight >= 1u);
1175
1176 ocean_assert(firstTargetRow + numberTargetRows <= (unsigned int)(lookupTable->sizeY()));
1177
1178 const Scalar cameraFrameWidth1 = Scalar(cameraFrameWidth - 1u);
1179 const Scalar cameraFrameHeight1 = Scalar(cameraFrameHeight - 1u);
1180
1181 const unsigned int targetFrameWidth = (unsigned int)(lookupTable->sizeX());
1182 const unsigned int targetFrameHeight = (unsigned int)(lookupTable->sizeY());
1183
1184 const unsigned int targetFrameStrideElements = targetFrameWidth * tChannels + targetFramePaddingElements;
1185
1186 using PixelType = typename DataType<uint8_t, tChannels>::Type;
1187
1188 for (unsigned int y = firstTargetRow; y < firstTargetRow + numberTargetRows; ++y)
1189 {
1190 const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar(targetFrameHeight - 1u) - Scalar(y));
1191
1192 uint8_t* targetPixel = targetFrame + y * targetFrameStrideElements;
1193
1194 for (unsigned int x = 0u; x < targetFrameWidth; ++x)
1195 {
1196 if (triangle2->isInside(Vector2(Scalar(x), yCorrected)))
1197 {
1198 const Vector2 inputPosition(lookupTable->bilinearValue(Scalar(x), Scalar(y)));
1199
1200 if (inputPosition.x() >= 0 && inputPosition.y() >= 0 && inputPosition.x() <= cameraFrameWidth1 && inputPosition.y() <= cameraFrameHeight1)
1201 {
1202 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, cameraFrameWidth, cameraFrameHeight, cameraFramePaddingElements, inputPosition, targetPixel);
1203 }
1204 else
1205 {
1206 *((PixelType*)(targetPixel)) = *((PixelType*)(outsideFrameColor));
1207 }
1208 }
1209
1210 targetPixel += tChannels;
1211 }
1212 }
1213}
1214
1215template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1216void 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)
1217{
1218 static_assert(tChannels >= 1u, "Invalid channel number!");
1219
1220 ocean_assert(cameraFrame != nullptr);
1221 ocean_assert(camera != nullptr && camera->isValid());
1222 ocean_assert(flippedCamera_T_world != nullptr && flippedCamera_T_world->isValid());
1223 ocean_assert(rectangleOrigin != nullptr && rectangleHorizontal != nullptr && rectangleVertical != nullptr);
1224 ocean_assert(targetFrame != nullptr && targetMask != nullptr);
1225 ocean_assert(targetWidth > 0u && targetHeight > 0u);
1226
1227 ocean_assert(firstTargetRow + numberTargetRows <= targetHeight);
1228
1229 const unsigned int targetFrameStrideElements = targetWidth * tChannels + targetFramePaddingElements;
1230 const unsigned int targetMaskStrideElements = targetWidth + targetMaskPaddingElements;
1231
1232 const Scalar frameWidth1 = Scalar(camera->width() - 1u);
1233 const Scalar frameHeight1 = Scalar(camera->height() - 1u);
1234
1235 const Scalar invTargetWidth = Scalar(1) / Scalar(targetWidth);
1236 const Scalar invTargetHeight = Scalar(1) / Scalar(targetHeight);
1237
1238 uint8_t* targetPixel = targetFrame + firstTargetRow * targetFrameStrideElements;
1239
1240 targetMask += firstTargetRow * targetMaskStrideElements;
1241
1242 Vectors3 objectPoints(targetWidth);
1243 Vectors2 imagePoints(targetWidth);
1244
1245 for (unsigned int y = firstTargetRow; y < firstTargetRow + numberTargetRows; ++y)
1246 {
1247 const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar(targetHeight - 1u) - Scalar(y));
1248
1249 for (unsigned int x = 0u; x < targetWidth; ++x)
1250 {
1251 objectPoints[x] = Vector3(*rectangleOrigin + *rectangleHorizontal * (Scalar(x) * invTargetWidth) + *rectangleVertical * (Scalar(yCorrected) * invTargetHeight));
1252 }
1253
1254 camera->projectToImageIF(*flippedCamera_T_world, objectPoints.data(), objectPoints.size(), imagePoints.data());
1255
1256 for (unsigned int x = 0u; x < targetWidth; ++x)
1257 {
1258 const Vector2& imagePoint = imagePoints[x];
1259
1260 const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
1261
1262 if (correctedImagePoint.x() >= 0 && correctedImagePoint.y() >= 0 && correctedImagePoint.x() <= frameWidth1 && correctedImagePoint.y() <= frameHeight1)
1263 {
1264 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, camera->width(), camera->height(), cameraFramePaddingElements, correctedImagePoint, targetPixel);
1265 *targetMask = maskValue;
1266 }
1267 else
1268 {
1269 *targetMask = 0xFF - maskValue;
1270 }
1271
1272 targetPixel += tChannels;
1273 ++targetMask;
1274 }
1275
1276 targetPixel += targetFramePaddingElements;
1277 targetMask += targetMaskPaddingElements;
1278 }
1279}
1280
1281template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1282void 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)
1283{
1284 static_assert(tChannels >= 1u, "Invalid channel number!");
1285
1286 ocean_assert(cameraFrame != nullptr);
1287 ocean_assert(camera != nullptr && camera->isValid());
1288 ocean_assert(flippedCamera_T_world != nullptr && flippedCamera_T_world->isValid());
1289 ocean_assert(rectangle != nullptr);
1290 ocean_assert(targetFrame != nullptr && targetMask != nullptr);
1291 ocean_assert(targetWidth > 0u && targetHeight > 0u);
1292
1293 ocean_assert(firstTargetRow + numberTargetRows <= targetHeight);
1294
1295 const unsigned int targetFrameStrideElements = targetWidth * tChannels + targetFramePaddingElements;
1296 const unsigned int targetMaskStrideElements = targetWidth + targetMaskPaddingElements;
1297
1298 const Scalar frameWidth1 = Scalar(camera->width() - 1u);
1299 const Scalar frameHeight1 = Scalar(camera->height() - 1u);
1300
1301 const Scalar invTargetWidth = Scalar(1) / Scalar(targetWidth);
1302 const Scalar invTargetHeight = Scalar(1) / Scalar(targetHeight);
1303
1304 uint8_t* targetPixel = targetFrame + firstTargetRow * targetFrameStrideElements;
1305
1306 targetMask += firstTargetRow * targetMaskStrideElements;
1307
1308 Vectors3 objectPoints(targetWidth);
1309 Vectors2 imagePoints(targetWidth);
1310
1311 const Vector3 direction10 = rectangle[1] - rectangle[0];
1312 const Vector3 direction23 = rectangle[2] - rectangle[3];
1313
1314 for (unsigned int y = firstTargetRow; y < firstTargetRow + numberTargetRows; ++y)
1315 {
1316 const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar(targetHeight - 1u) - Scalar(y));
1317
1318 const Vector3 left(rectangle[0] + direction10 * (Scalar(yCorrected) * invTargetHeight));
1319 const Vector3 right(rectangle[3] + direction23 * (Scalar(yCorrected) * invTargetHeight));
1320
1321 for (unsigned int x = 0u; x < targetWidth; ++x)
1322 {
1323 objectPoints[x] = left + (right - left) * (Scalar(x) * invTargetWidth);
1324 }
1325
1326 camera->projectToImageIF(*flippedCamera_T_world, objectPoints.data(), objectPoints.size(), imagePoints.data());
1327
1328 for (unsigned int x = 0u; x < targetWidth; ++x)
1329 {
1330 const Vector2& imagePoint = imagePoints[x];
1331
1332 const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
1333
1334 if (correctedImagePoint.x() >= 0 && correctedImagePoint.y() >= 0 && correctedImagePoint.x() <= frameWidth1 && correctedImagePoint.y() <= frameHeight1)
1335 {
1336 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, camera->width(), camera->height(), cameraFramePaddingElements, correctedImagePoint, targetPixel);
1337 *targetMask = maskValue;
1338 }
1339 else
1340 {
1341 *targetMask = 0xFF - maskValue;
1342 }
1343
1344 targetPixel += tChannels;
1345 ++targetMask;
1346 }
1347
1348 targetPixel += targetFramePaddingElements;
1349 targetMask += targetMaskPaddingElements;
1350 }
1351}
1352
1353template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1354void 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)
1355{
1356 static_assert(tChannels >= 1u, "Invalid channel number!");
1357
1358 ocean_assert(cameraFrame != nullptr && camera != nullptr && camera->isValid());
1359 ocean_assert(flippedCamera_T_world != nullptr && flippedCamera_T_world->isValid());
1360
1361 ocean_assert(triangle2 != nullptr && triangle2->isValid());
1362 ocean_assert(triangle3 != nullptr && triangle2->isValid());
1363
1364 ocean_assert(targetFrame != nullptr && targetMask != nullptr);
1365
1366 ocean_assert(targetWidth > 0u && targetHeight > 0u);
1367 ocean_assert(firstTargetRow + numberTargetRows <= targetHeight);
1368
1369 const Scalar frameWidth1 = Scalar(camera->width() - 1u);
1370 const Scalar frameHeight1 = Scalar(camera->height() - 1u);
1371
1372 const unsigned int targetFrameStrideElements = targetWidth * tChannels + targetFramePaddingElements;
1373 const unsigned int targetMaskStrideElements = targetWidth + targetMaskPaddingElements;
1374
1375 uint8_t* targetPixel = targetFrame + firstTargetRow * targetFrameStrideElements;
1376
1377 targetMask += firstTargetRow * targetMaskStrideElements;
1378
1379 for (unsigned int y = firstTargetRow; y < firstTargetRow + numberTargetRows; ++y)
1380 {
1381 const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar(targetHeight - 1u) - Scalar(y));
1382
1383 for (unsigned int x = 0u; x < targetWidth; ++x)
1384 {
1385 const Vector3 barycentricTargetPosition(triangle2->cartesian2barycentric(Vector2(Scalar(x), yCorrected)));
1386
1387 if (triangle2->isBarycentricInside(barycentricTargetPosition))
1388 {
1389 const Vector3 objectPoint(triangle3->barycentric2cartesian(barycentricTargetPosition));
1390 const Vector2 imagePoint(camera->projectToImageIF(*flippedCamera_T_world, objectPoint));
1391
1392 const Vector2 correctedImagePoint(imagePoint.x(), tPixelOriginUpperLeft ? imagePoint.y() : (frameHeight1 - imagePoint.y()));
1393
1394 if (correctedImagePoint.x() >= 0 && correctedImagePoint.y() >= 0 && correctedImagePoint.x() <= frameWidth1 && correctedImagePoint.y() <= frameHeight1)
1395 {
1396 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, camera->width(), camera->height(), cameraFramePaddingElements, correctedImagePoint, targetPixel);
1397 *targetMask = maskValue;
1398 }
1399 else
1400 {
1401 *targetMask = 0xFF - maskValue;
1402 }
1403 }
1404
1405 targetPixel += tChannels;
1406 ++targetMask;
1407 }
1408
1409 targetPixel += targetFramePaddingElements;
1410 targetMask += targetMaskPaddingElements;
1411 }
1412}
1413
1414template <unsigned int tChannels, bool tPixelOriginUpperLeft>
1415void 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)
1416{
1417 static_assert(tChannels >= 1u, "Invalid channel number!");
1418
1419 ocean_assert(cameraFrame != nullptr && cameraFrameWidth >= 1u && cameraFrameHeight >= 1u);
1420 ocean_assert(triangle2 != nullptr && lookupTable && !lookupTable->isEmpty());
1421
1422 ocean_assert(targetFrame != nullptr && targetMask != nullptr);
1423
1424 ocean_assert(firstTargetRow + numberTargetRows <= (unsigned int)(lookupTable->sizeY()));
1425
1426 const unsigned int targetFrameStrideElements = (unsigned int)(lookupTable->sizeX()) * tChannels + targetFramePaddingElements;
1427 const unsigned int targetMaskStrideElements = (unsigned int)(lookupTable->sizeX()) + targetMaskPaddingElements;
1428
1429 const Scalar cameraFrameWidth1 = Scalar(cameraFrameWidth - 1u);
1430 const Scalar cameraFrameHeight1 = Scalar(cameraFrameHeight - 1u);
1431
1432 uint8_t* targetPixel = targetFrame + firstTargetRow * targetFrameStrideElements;
1433
1434 targetMask += firstTargetRow * targetMaskStrideElements;
1435
1436 for (unsigned int y = firstTargetRow; y < firstTargetRow + numberTargetRows; ++y)
1437 {
1438 const Scalar yCorrected = tPixelOriginUpperLeft ? Scalar(y) : (Scalar((unsigned int)(lookupTable->sizeY()) - 1u) - Scalar(y));
1439
1440 for (unsigned int x = 0u; x < (unsigned int)(lookupTable->sizeX()); ++x)
1441 {
1442 if (triangle2->isInside(Vector2(Scalar(x), yCorrected)))
1443 {
1444 const Vector2 inputPosition(lookupTable->bilinearValue(Scalar(x), Scalar(y)));
1445
1446 if (inputPosition.x() >= 0 && inputPosition.y() >= 0 && inputPosition.x() <= cameraFrameWidth1 && inputPosition.y() <= cameraFrameHeight1)
1447 {
1448 CV::FrameInterpolatorBilinear::interpolatePixel8BitPerChannel<tChannels, CV::PC_TOP_LEFT>(cameraFrame, cameraFrameWidth, cameraFrameHeight, cameraFramePaddingElements, inputPosition, targetPixel);
1449 *targetMask = maskValue;
1450 }
1451 else
1452 {
1453 *targetMask = 0xFFu - maskValue;
1454 }
1455 }
1456
1457 targetPixel += tChannels;
1458 ++targetMask;
1459 }
1460
1461 targetPixel += targetFramePaddingElements;
1462 targetMask += targetMaskPaddingElements;
1463 }
1464}
1465
1466}
1467
1468}
1469
1470}
1471
1472#endif // META_OCEAN_CV_ADVANCED_FRAME_RECTIFICATION_H
This class implements the abstract base class for all AnyCamera objects.
Definition AnyCamera.h:131
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:1065
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:1017
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:1354
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:553
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:624
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:573
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:677
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:1119
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:957
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:749
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:919
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:1169
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:1216
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:989
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:1415
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:1282
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:798
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:849
static Caller< void > createStatic(typename StaticFunctionPointerMaker< void, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass >::Type function)
Creates a new caller container for a static function with no function parameter.
Definition Caller.h:2877
This class implements Ocean's image class.
Definition Frame.h:1969
PixelOrigin
Defines different types of frame origin positions.
Definition Frame.h:1136
@ ORIGIN_UPPER_LEFT
The first pixel lies in the upper left corner, the last pixel in the lower right corner.
Definition Frame.h:1140
const T * data() const
Returns a pointer to the internal values.
Definition HomogenousMatrix4.h:1837
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition HomogenousMatrix4.h:1800
size_t sizeY() const
Returns the vertical dimension of this lookup object.
Definition Lookup2.h:960
size_t sizeX() const
Returns the horizontal dimension of this lookup object.
Definition Lookup2.h:954
bool isEmpty() const
Returns whether this lookup object does not hold any lookup bin.
Definition Lookup2.h:1022
size_t binsY() const
Returns the number of vertical bins of this lookup object.
Definition Lookup2.h:972
size_t binsX() const
Returns the number of horizontal bins of this lookup object.
Definition Lookup2.h:966
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:2215
T bilinearValue(const TScalar x, const TScalar y) const
Applies a lookup for a specific position in this lookup object.
Definition Lookup2.h:1828
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:1788
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:1777
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:759
bool isInside(const VectorT2< T > &point) const
Returns whether a given point lies inside this triangle.
Definition Triangle2.h:722
bool isValid() const
Returns whether this triangle can provide valid barycentric coordinates (for 64 bit floating point va...
Definition Triangle2.h:798
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:703
const T & y() const noexcept
Returns the y value.
Definition Vector2.h:715
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:973
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition Vector2.h:64
float Scalar
Definition of a scalar type.
Definition Math.h:129
std::vector< Vector3 > Vectors3
Definition of a vector holding Vector3 objects.
Definition Vector3.h:65
VectorT3< Scalar > Vector3
Definition of a 3D vector.
Definition Vector3.h:29
The namespace covering the entire Ocean framework.
Definition Accessor.h:15
Default definition of a type with tBytes bytes.
Definition DataType.h:32