Ocean
PlanarRectangleTracker.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_TRACKING_OFFLINE_PLANAR_RECTANGLE_TRACKER_PLANAR_H
9 #define META_OCEAN_TRACKING_OFFLINE_PLANAR_RECTANGLE_TRACKER_PLANAR_H
10 
15 
16 #include "ocean/cv/SubRegion.h"
17 
19 
21 
22 namespace Ocean
23 {
24 
25 namespace Tracking
26 {
27 
28 namespace Offline
29 {
30 
31 // Forward declaration.
32 class PlanarRectangleTracker;
33 
34 /**
35  * Definition of an object reference holding a PlanarRectangleTracker object.
36  * @see PlanarRectangleTracker.
37  * @ingroup trackingoffline
38  */
40 
41 /**
42  * This class implements a tracker that is able to track an rectangle located one a 3D plane.
43  * @ingroup trackingoffline
44  */
45 class OCEAN_TRACKING_OFFLINE_EXPORT PlanarRectangleTracker :
46  virtual public FrameTracker,
47  virtual public PlaneTracker
48 {
49  protected:
50 
51  /**
52  * Definition of a shift vector holding homographies.
53  */
55 
56  /**
57  * Definition of a shift vector holding image point pairs.
58  */
60 
61  // Forward declaration of an optimization data object for camera profiles.
62  class CameraPosesData;
63 
64  // Forward declaration of an optimization data object for camera profiles changing the distortion parameters only.
65  class DistortionCameraPosesData;
66 
67  /**
68  * This component implements a plane tracker that uses an already known plane to create camera poses.
69  * Further, this component is able to optimized the camera profile.
70  */
72  {
73  public:
74 
75  /**
76  * Creates a new plane tracking component object.
77  * @param parent The parent tracker object that invokes this component
78  * @param pinholeCamera The pinhole camera profile that will be used for homography tracking
79  * @param initialPose Initial pose that corresponds with the camera frame in that the tracking starts
80  * @param plane Already known plane that will be used for pose tracking
81  * @param resultingPoses Resulting camera poses, one for each frame
82  * @param resultingOptimizedCamera Optional resulting optimized camera profile
83  */
84  PlaneTrackerComponent(PlanarRectangleTracker& parent, const PinholeCamera& pinholeCamera, const HomogenousMatrix4& initialPose, const Plane3& plane, OfflinePoses& resultingPoses, PinholeCamera* resultingOptimizedCamera);
85 
86  /**
87  * Destructor
88  */
89  inline ~PlaneTrackerComponent() override;
90 
91  protected:
92 
93  /**
94  * Applies one component step.
95  * @see TrackerComponent::onFrame().
96  */
97  IterationResult onFrame(const unsigned int previousIndex, const unsigned int currentIndex, const unsigned int iteration, const unsigned int maximalIterations) override;
98 
99  /**
100  * Component start event function.
101  * @see TrackerComponent::onStart().
102  */
103  bool onStart(const unsigned int lowerFrameIndex, const unsigned int initialFrameIndex, const unsigned int upperFrameIndex) override;
104 
105  /**
106  * Component start event function.
107  * @see TrackerComponent::onStop().
108  */
109  bool onStop(const unsigned int lowerFrameIndex, const unsigned int initialFrameIndex, const unsigned int upperFrameIndex) override;
110 
111  /**
112  * Tracks the camera pose between two successive frames.
113  * Only points lying on a 3D plane are used for pose determination.<br>
114  * @param previousFramePyramid Frame pyramid of the previous frame
115  * @param currentFramePyramid Frame pyramid of the current frame
116  * @param previousSubRegion Sub-region that specifies the planar area in the previous frame
117  * @param previousPose Pose that corresponds with the previous frame
118  * @param currentPose Resulting pose for the current frame
119  * @param maximalSqrError Maximal square distance between forward and backward tracking for a valid point
120  * @param horizontalBins Optional horizontal bins that can be used to distribute the tracked points into array bins (in each bin there will be at most one point)
121  * @param verticalBins Optional vertical bins that can be used to distribute the tracked points into array bins (in each bin there will be at most one point)
122  * @param strength Minimal strength parameter of the tracked feature points
123  * @param worker Optional worker object to distribute the computation
124  * @param trackingLayers Number of pyramid layers on which points are tracked, with range [1, pyramidLayers]
125  * @param previousImagePoints Optional resulting image points of the previous image that have been used for tracking
126  * @param currentImagePoints Optional resulting image points of the current image that have been used for tracking, each point corresponds to one point in the previous image
127  * @return The number of feature points that have been used for pose determination
128  */
129  inline size_t frame2framePose(const CV::FramePyramid& previousFramePyramid, const CV::FramePyramid& currentFramePyramid, const CV::SubRegion& previousSubRegion, const HomogenousMatrix4& previousPose, HomogenousMatrix4& currentPose, const Scalar maximalSqrError, const unsigned int horizontalBins, const unsigned int verticalBins, const unsigned int strength, Worker* worker = nullptr, const unsigned int trackingLayers = 1u, Vectors2* previousImagePoints = nullptr, Vectors2* currentImagePoints = nullptr);
130 
131  /**
132  * Optimizes an already known pose for the current frame by creating two rectified frames of the tracking plane.
133  * @param currentFrame The current camera frame
134  * @param currentPose The already known (rough) pose for the current frame
135  * @param optimizedPose Resulting optimized pose
136  * @param worker Optional worker object to distribute the computation
137  * @param validInitialImagePoints Optional resulting points in the initial camera frame that have been used for pose optimization
138  * @param validCurrentImagePoints Optional resulting points in the current camera frame that have been used for pose optimization, each point corresponds to one point of the set of initial image points
139  * @param reliableImagePoints Optional resulting statement whether the resulting image points correspondences are reliable and may be used for further optimization (e.g. of the camera profile); only False will be set, never True
140  * @return True, if succeeded
141  */
142  bool optimizePose(const Frame& currentFrame, const HomogenousMatrix4& currentPose, HomogenousMatrix4& optimizedPose, Worker* worker, ImagePoints* validInitialImagePoints, ImagePoints* validCurrentImagePoints, bool* reliableImagePoints = nullptr);
143 
144  /**
145  * Optimizes the camera profile for the point correspondences that have been determined during the tracking phase of this component.
146  * @param optimizedCamera Resulting optimized camera profile
147  * @param numberFrames The number of frames that are used to optimized the camera profile
148  * @return True, if the camera could be optimized with plausible parameters
149  */
150  bool optimizeCamera(PinholeCamera& optimizedCamera, const unsigned int numberFrames);
151 
152  protected:
153 
154  /// The parent tracker invoking this component.
156 
157  /// The camera profile that is applied in this component.
159 
160  /// Initial camera pose for the frame index for that the tracking starts.
162 
163  /// The plane that is applied in this component.
164  const Plane3 plane_;
165 
166  /// The camera poses that are detected during tracking, one pose for each frame.
168 
169  /// The resulting poses that are tracked in this component.
171 
172  /// The frame pyramid of the rectified initial frame.
174 
175  /// The camera profile that is used to create the initial rectified frame.
177 
178  /// The camera pose that is used to create the initial rectified frame.
180 
181  /// The intermediate rectified frame.
183 
184  /// The frame pyramid of the intermediate rectified frame.
186 
187  /// Pairs of image points that are used to determine the camera pose.
189 
190  /// Optional resulting optimized camera profile.
191  PinholeCamera* resultingOptimizedCamera_ = nullptr;
192 
193  /// Frame pyramid of the initial frame.
195  };
196 
197  public:
198 
199  /**
200  * Creates a new tracker object.
201  */
203 
204  /**
205  * Destructs a tracker object.
206  */
208 
209  /**
210  * Sets the four points of a planar rectangle that is visible in the initial camera frame.
211  * Beware: Set the rectangle before the tracker has been started.<br>
212  * @param rectangleCorners The four corners of the rectangle.
213  * @return True, if succeed
214  */
215  bool setInitialRectangle(const Vector2 rectangleCorners[4]);
216 
217  protected:
218 
219  /**
220  * Frame tracker run function.
221  * @see OfflineFrameTracker::applyFrameTracking().
222  */
223  bool applyFrameTracking(const FrameType& frameType) override;
224 
225  /**
226  * Tracks a known plane and can determines the camera poses or/and optimize the camera profile.
227  * @param pinholeCamera The pinhole camera profile to be applied
228  * @param plane 3D plane to be tracked
229  * @param lowerFrameIndex Index of the frame defining the lower (including) tracking boundary
230  * @param initialFrameIndex Index of the frame at that the tracking process will start
231  * @param upperFrameIndex Index of the frame defining the upper (including) tracking boundary
232  * @param createStateEvents True, to create state events for the individual poses
233  * @param poses Resulting camera poses
234  * @param optimizedCamera Optional resulting optimized camera profile
235  * @return True, if succeeded
236  */
237  bool trackPlane(const PinholeCamera& pinholeCamera, const Plane3& plane, const unsigned int lowerFrameIndex, const unsigned int initialFrameIndex, const unsigned int upperFrameIndex, const bool createStateEvents, OfflinePoses& poses, PinholeCamera* optimizedCamera);
238 
239  /**
240  * Updates the plane of this tracker and invokes the corresponding state event(s).
241  * @see PlaneTracker::updatePlane().
242  */
243  void updatePlane(const Plane3& plane)override;
244 
245  /**
246  * Updates the camera of this tracker and invokes the corresponding state event(s).
247  * @see FrameTracker::updateCamera().
248  */
249  void updateCamera(const PinholeCamera& pinholeCamera) override;
250 
251  /**
252  * Updates the tracker object transformation using the current camera profile and plane of this tracker.
253  * @return True, if succeeded
254  */
256 
257  /**
258  * Determines the angle difference between a perfect 90 degree rectangular angle and the angle of the parallelogram defined by the four points given by the user.
259  * @param pinholeCamera The pinhole camera profile to be applied
260  * @param plane The plane to be applied
261  * @return The absolute angle difference between a 90 degree angle and the parallelogram angles in radian
262  */
263  Scalar parallelogramAngle(const PinholeCamera& pinholeCamera, const Plane3& plane);
264 
265  /**
266  * Determines the plane from four corners of a visible planar rectangle.
267  * @param pinholeCamera The pinhole camera profile that is applied
268  * @param rectangleCorners The four corners of the planar rectangle
269  * @param plane Resulting plane, if a valid plane can be estimated
270  * @return True, if succeeded
271  */
272  static bool determinePlane(const PinholeCamera& pinholeCamera, const Vector2 rectangleCorners[4], Plane3& plane);
273 
274  /**
275  * Calculates the transformation (camera pose and camera profile) for the rectangle that the users has selected.
276  * The camera will be located in top of the plane so that the rectangle perfectly fits into the camera frame.
277  * @param pinholeCamera The pinhole camera profile of the camera frames
278  * @param initialPose The initial pose for the camera frame in that the user has selected the four corners of the rectangle
279  * @param rectangleCorners The four corners of the rectangle that lies in the 3D plane
280  * @param plane The 3D plane in which the four corners lie
281  * @param extraBorderPercent The distance between tracking plane and camera can be increased so that an extra border around the rectangle will be visible, with range [0, 1], (e.g. a value of 0.1 will calculate a pose that shows a border around the tracking rectangle with 10% of the frame's dimension)
282  * @param lookAtCamera Resulting camera profile that create a rectified frame of the tracking rectangle
283  * @param lookAtPose Resulting camera prose that create a rectified frame of the tracking rectangle
284  * @return True, if succeeded
285  */
286  static bool lookAtTransformation(const PinholeCamera& pinholeCamera, const HomogenousMatrix4& initialPose, const Vector2 rectangleCorners[4], const Plane3& plane, const Scalar extraBorderPercent, PinholeCamera& lookAtCamera, HomogenousMatrix4& lookAtPose);
287 
288  protected:
289 
290  /// The initial pose that is defined for the first frame index, this pose is the default pose: locking towards the negative z-axis with y-axis as up vector at the position (0, 0, 0).
292 
293  /// The user-defined sub-region for the initial tracking frame.
294  Vector2 initialRectangleCorners_[4];
295 
296  /// The sub-region that represents the initial rectangle corners as two triangles.
298 };
299 
301 {
302  // Nothing else to do.
303 }
304 
305 inline size_t PlanarRectangleTracker::PlaneTrackerComponent::frame2framePose(const CV::FramePyramid& previousFramePyramid, const CV::FramePyramid& currentFramePyramid, const CV::SubRegion& previousSubRegion, const HomogenousMatrix4& previousPose, HomogenousMatrix4& currentPose, const Scalar maximalSqrError, const unsigned int horizontalBins, const unsigned int verticalBins, const unsigned int strength, Worker* worker, const unsigned int trackingLayers, Vectors2* previousImagePoints, Vectors2* currentImagePoints)
306 {
307  ocean_assert(previousFramePyramid && currentFramePyramid);
308  ocean_assert(previousFramePyramid.layers() == currentFramePyramid.layers());
309 
310  return Frame2FrameTracker::trackPlanarObject<15u>(camera_, previousFramePyramid, currentFramePyramid, 2u, previousPose, plane_, previousSubRegion, currentPose, maximalSqrError, horizontalBins, verticalBins, strength, worker, trackingLayers, previousImagePoints, currentImagePoints);
311 }
312 
313 }
314 
315 }
316 
317 }
318 
319 #endif // META_OCEAN_TRACKING_OFFLINE_PLANAR_RECTANGLE_TRACKER_PLANAR_H
This class implements a frame pyramid.
Definition: FramePyramid.h:37
unsigned int layers() const
Returns the number of layers this pyramid holds.
Definition: FramePyramid.h:761
This class implement a sub-region either defined by 2D triangles or defined by a binary mask.
Definition: SubRegion.h:32
This class implements Ocean's image class.
Definition: Frame.h:1792
Definition of a frame type composed by the frame dimension, pixel format and pixel origin.
Definition: Frame.h:30
This template class implements a smart object reference which is a specialization of an ObjectRef obj...
Definition: SmartObjectRef.h:90
This class implements the base class for all components of a frame tracker.
Definition: FrameTracker.h:196
IterationResult
Definition of individual results for the component iterations.
Definition: FrameTracker.h:62
This class implements the base class for all visual offline tracker using frames to provide the track...
Definition: FrameTracker.h:46
PinholeCamera camera_
The camera object of this tracker.
Definition: FrameTracker.h:354
This component implements a plane tracker that uses an already known plane to create camera poses.
Definition: PlanarRectangleTracker.h:72
bool onStart(const unsigned int lowerFrameIndex, const unsigned int initialFrameIndex, const unsigned int upperFrameIndex) override
Component start event function.
const HomogenousMatrix4 & initialPose_
Initial camera pose for the frame index for that the tracking starts.
Definition: PlanarRectangleTracker.h:161
OfflinePoses & resultingPoses_
The resulting poses that are tracked in this component.
Definition: PlanarRectangleTracker.h:170
bool optimizePose(const Frame &currentFrame, const HomogenousMatrix4 &currentPose, HomogenousMatrix4 &optimizedPose, Worker *worker, ImagePoints *validInitialImagePoints, ImagePoints *validCurrentImagePoints, bool *reliableImagePoints=nullptr)
Optimizes an already known pose for the current frame by creating two rectified frames of the trackin...
CV::FramePyramid intermediateRectifiedFramePyramid_
The frame pyramid of the intermediate rectified frame.
Definition: PlanarRectangleTracker.h:185
HomogenousMatrix4 initialRectifiedPose_
The camera pose that is used to create the initial rectified frame.
Definition: PlanarRectangleTracker.h:179
bool optimizeCamera(PinholeCamera &optimizedCamera, const unsigned int numberFrames)
Optimizes the camera profile for the point correspondences that have been determined during the track...
OfflinePoses poses_
The camera poses that are detected during tracking, one pose for each frame.
Definition: PlanarRectangleTracker.h:167
ImagePointsPairs imagePointsPairs_
Pairs of image points that are used to determine the camera pose.
Definition: PlanarRectangleTracker.h:188
PinholeCamera initialRectifiedCamera_
The camera profile that is used to create the initial rectified frame.
Definition: PlanarRectangleTracker.h:176
bool onStop(const unsigned int lowerFrameIndex, const unsigned int initialFrameIndex, const unsigned int upperFrameIndex) override
Component start event function.
size_t frame2framePose(const CV::FramePyramid &previousFramePyramid, const CV::FramePyramid &currentFramePyramid, const CV::SubRegion &previousSubRegion, const HomogenousMatrix4 &previousPose, HomogenousMatrix4 &currentPose, const Scalar maximalSqrError, const unsigned int horizontalBins, const unsigned int verticalBins, const unsigned int strength, Worker *worker=nullptr, const unsigned int trackingLayers=1u, Vectors2 *previousImagePoints=nullptr, Vectors2 *currentImagePoints=nullptr)
Tracks the camera pose between two successive frames.
Definition: PlanarRectangleTracker.h:305
~PlaneTrackerComponent() override
Destructor.
Definition: PlanarRectangleTracker.h:300
PlanarRectangleTracker & parent_
The parent tracker invoking this component.
Definition: PlanarRectangleTracker.h:155
Frame intermediateRectifiedFrame_
The intermediate rectified frame.
Definition: PlanarRectangleTracker.h:182
IterationResult onFrame(const unsigned int previousIndex, const unsigned int currentIndex, const unsigned int iteration, const unsigned int maximalIterations) override
Applies one component step.
CV::FramePyramid initialRectifiedFramePyramid_
The frame pyramid of the rectified initial frame.
Definition: PlanarRectangleTracker.h:173
PlaneTrackerComponent(PlanarRectangleTracker &parent, const PinholeCamera &pinholeCamera, const HomogenousMatrix4 &initialPose, const Plane3 &plane, OfflinePoses &resultingPoses, PinholeCamera *resultingOptimizedCamera)
Creates a new plane tracking component object.
const Plane3 plane_
The plane that is applied in this component.
Definition: PlanarRectangleTracker.h:164
CV::FramePyramid initialFramePyramid_
Frame pyramid of the initial frame.
Definition: PlanarRectangleTracker.h:194
const PinholeCamera camera_
The camera profile that is applied in this component.
Definition: PlanarRectangleTracker.h:158
This class implements a tracker that is able to track an rectangle located one a 3D plane.
Definition: PlanarRectangleTracker.h:48
const HomogenousMatrix4 initialPose_
The initial pose that is defined for the first frame index, this pose is the default pose: locking to...
Definition: PlanarRectangleTracker.h:291
ShiftVector< Geometry::NonLinearOptimizationPlane::ImagePointsPair > ImagePointsPairs
Definition of a shift vector holding image point pairs.
Definition: PlanarRectangleTracker.h:59
static bool determinePlane(const PinholeCamera &pinholeCamera, const Vector2 rectangleCorners[4], Plane3 &plane)
Determines the plane from four corners of a visible planar rectangle.
CV::SubRegion initialRectangleSubRegion_
The sub-region that represents the initial rectangle corners as two triangles.
Definition: PlanarRectangleTracker.h:297
ShiftVector< SquareMatrix3 > Homographies
Definition of a shift vector holding homographies.
Definition: PlanarRectangleTracker.h:54
static bool lookAtTransformation(const PinholeCamera &pinholeCamera, const HomogenousMatrix4 &initialPose, const Vector2 rectangleCorners[4], const Plane3 &plane, const Scalar extraBorderPercent, PinholeCamera &lookAtCamera, HomogenousMatrix4 &lookAtPose)
Calculates the transformation (camera pose and camera profile) for the rectangle that the users has s...
void updateCamera(const PinholeCamera &pinholeCamera) override
Updates the camera of this tracker and invokes the corresponding state event(s).
bool setInitialRectangle(const Vector2 rectangleCorners[4])
Sets the four points of a planar rectangle that is visible in the initial camera frame.
bool updateObjectTransformation()
Updates the tracker object transformation using the current camera profile and plane of this tracker.
~PlanarRectangleTracker() override
Destructs a tracker object.
bool trackPlane(const PinholeCamera &pinholeCamera, const Plane3 &plane, const unsigned int lowerFrameIndex, const unsigned int initialFrameIndex, const unsigned int upperFrameIndex, const bool createStateEvents, OfflinePoses &poses, PinholeCamera *optimizedCamera)
Tracks a known plane and can determines the camera poses or/and optimize the camera profile.
bool applyFrameTracking(const FrameType &frameType) override
Frame tracker run function.
PlanarRectangleTracker()
Creates a new tracker object.
void updatePlane(const Plane3 &plane) override
Updates the plane of this tracker and invokes the corresponding state event(s).
Scalar parallelogramAngle(const PinholeCamera &pinholeCamera, const Plane3 &plane)
Determines the angle difference between a perfect 90 degree rectangular angle and the angle of the pa...
This class implements the abstract base class for all plane trackers.
Definition: PlaneTracker.h:42
Plane3 plane_
The plane of this tracker.
Definition: PlaneTracker.h:80
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
float Scalar
Definition of a scalar type.
Definition: Math.h:128
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition: Vector2.h:64
std::vector< ImagePoint > ImagePoints
Definition of a vector holding 2D image points.
Definition: Tracking.h:55
SmartObjectRef< PlanarRectangleTracker, OfflineTracker > PlanarRectangleTrackerRef
Definition of an object reference holding a PlanarRectangleTracker object.
Definition: PlanarRectangleTracker.h:32
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15