Ocean
Loading...
Searching...
No Matches
BullseyeDetectorStereo.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 OCEAN_CV_DETECTOR_BULLSEYES_BULLSEYEDETECTORSTEREO_H
9#define OCEAN_CV_DETECTOR_BULLSEYES_BULLSEYEDETECTORSTEREO_H
10
12
15
16#include "ocean/base/Frame.h"
17#include "ocean/base/Worker.h"
19
21#include "ocean/math/Matrix.h"
22#include "ocean/math/Vector3.h"
23
24namespace Ocean
25{
26
27namespace CV
28{
29
30namespace Detector
31{
32
33namespace Bullseyes
34{
35
36/**
37 * This class implements a stereo detector for bullseye patterns.
38 * @ingroup cvdetectorbullseyes
39 */
40class OCEAN_CV_DETECTOR_BULLSEYES_EXPORT BullseyeDetectorStereo
41{
42 public:
43
44 /**
45 * Definition of a pair of bullseyes.
46 */
47 using BullseyePair = std::pair<Bullseye, Bullseye>;
48
49 /**
50 * Definition of a vector holding bullseye pairs.
51 */
52 using BullseyePairs = std::vector<BullseyePair>;
53
54 /**
55 * Definition of a pair of vectors of bullseyes, one from each camera.
56 */
57 using BullseyeGroup = std::array<Bullseyes, 2>;
58
59 /**
60 * This class holds the most important parameters for the stereo detector.
61 * Currently, this class inherits all parameters from the monocular detector.
62 */
64 {
65 public:
66
67 /**
68 * Creates a new parameter object with default parameters.
69 */
70 Parameters() = default;
71
72 /**
73 * Returns the default parameters for the stereo detector.
74 * @return The default parameters
75 */
77 };
78
79 protected:
80
81 /**
82 * This class represents a candidate bullseye match between two stereo cameras.
83 * A candidate includes the triangulated 3D center position and the reprojection errors for
84 * both cameras. The indices of the matched bullseyes are stored separately as keys in the
85 * CandidateMap. Candidates are used during the matching process before final validation and
86 * selection.
87 */
89 {
90 public:
91
92 /**
93 * Creates a default (invalid) candidate.
94 */
95 Candidate() = default;
96
97 /**
98 * Creates a new candidate with the specified parameters.
99 * The indices of the matched bullseyes are not stored in the candidate itself,
100 * but rather as keys in the CandidateMap that holds this candidate.
101 * @param center The triangulated 3D center position in world coordinates
102 * @param reprojectionErrorA The reprojection error for camera A, in pixels
103 * @param reprojectionErrorB The reprojection error for camera B, in pixels
104 */
105 Candidate(const Vector3& center, const Scalar reprojectionErrorA, const Scalar reprojectionErrorB);
106
107 /**
108 * Returns whether this candidate is valid.
109 * @return True if the candidate has valid indices and center position, otherwise false
110 */
111 bool isValid() const;
112
113 /**
114 * Returns the triangulated 3D center position.
115 * @return The 3D center position in world coordinates
116 */
117 const Vector3& center() const;
118
119 /**
120 * Returns the reprojection error for camera A.
121 * @return The reprojection error in pixels
122 */
124
125 /**
126 * Returns the reprojection error for camera B.
127 * @return The reprojection error in pixels
128 */
130
131 /**
132 * Returns an invalid bullseye center value used as a sentinel for uninitialized positions.
133 * @return The invalid center position
134 */
136
137 protected:
138
139 /// The triangulated 3D center position in world coordinates
140 Vector3 center_ = invalidBullseyeCenter();
141
142 /// The reprojection error for camera A, in pixels
143 Scalar reprojectionErrorA_ = Numeric::minValue();
144
145 /// The reprojection error for camera B, in pixels
146 Scalar reprojectionErrorB_ = Numeric::minValue();
147 };
148
149 /**
150 * Definition of an unordered map holding candidate bullseyes.
151 * The key is a pair of indices (indexA, indexB) where indexA corresponds to a bullseye in camera A
152 * and indexB corresponds to a bullseye in camera B. The value is the Candidate object containing
153 * the triangulated 3D position and reprojection errors for this match.
154 */
155 using CandidateMap = std::unordered_map<IndexPair32, Candidate, PairHash>;
156
157 public:
158
159 /**
160 * Detects bullseyes in a pair of stereo frames.
161 * @param cameras The camera profiles for the stereo pair, must contain exactly 2 valid cameras
162 * @param yFrames The stereo frames in which bullseyes will be detected, must contain exactly 2 valid 8-bit grayscale frames
163 * @param world_T_device The transformation from the device coordinate system to the world coordinate system, must be valid
164 * @param device_T_cameras The transformations from each camera coordinate system to the device coordinate system, must contain exactly 2 valid transformations
165 * @param bullseyePairs The resulting pairs of detected bullseyes, one from each camera
166 * @param bullseyeCenters The resulting 3D positions of the triangulated bullseye centers in world coordinates
167 * @param parameters The parameters for the detector, must be valid
168 * @param worker Optional worker to distribute the computation
169 * @return True, if succeeded
170 */
171 static bool detectBullseyes(const SharedAnyCameras& cameras, const Frames& yFrames, const HomogenousMatrix4& world_T_device, const HomogenousMatrices4& device_T_cameras, BullseyePairs& bullseyePairs, Vectors3& bullseyeCenters, const Parameters& parameters = Parameters::defaultParameters(), Worker* worker = nullptr);
172
173 protected:
174
175 /**
176 * Extracts and validates candidate bullseye matches between two stereo cameras.
177 * This function triangulates all possible bullseye pairs and returns those that produce valid 3D positions.
178 * The returned map uses index pairs (indexA, indexB) as keys, where indexA corresponds to a bullseye in camera A
179 * and indexB corresponds to a bullseye in camera B. The values are Candidate objects containing the triangulated
180 * 3D positions and reprojection errors for each matched pair.
181 * @param cameraA The camera profile for the first camera, must be valid
182 * @param cameraB The camera profile for the second camera, must be valid
183 * @param world_T_cameraA The transformation from camera A coordinate system to world coordinate system, must be valid
184 * @param world_T_cameraB The transformation from camera B coordinate system to world coordinate system, must be valid
185 * @param bullseyesA The bullseyes detected in camera A, may be empty
186 * @param bullseyesB The bullseyes detected in camera B, may be empty
187 * @return The map of valid candidate matches; may be empty if no valid matches were found
188 */
189 static CandidateMap extractBullseyeCandidates(const AnyCamera& cameraA, const AnyCamera& cameraB, const HomogenousMatrix4& world_T_cameraA, const HomogenousMatrix4& world_T_cameraB, const Bullseyes& bullseyesA, const Bullseyes& bullseyesB);
190
191 /**
192 * Extracts the final bullseye pairs and their 3D centers from candidate matches.
193 * This function uses the candidate map to retrieve the original bullseye objects and their triangulated positions.
194 * @param cameraA The camera profile for the first camera, must be valid
195 * @param cameraB The camera profile for the second camera, must be valid
196 * @param bullseyesA The bullseyes detected in camera A, must not be empty
197 * @param bullseyesB The bullseyes detected in camera B, must not be empty
198 * @param candidateMap The map of candidate matches with index pairs as keys and triangulated positions as values, must not be empty
199 * @param bullseyePairs The resulting validated bullseye pairs
200 * @param bullseyeCenters The resulting 3D positions of the bullseye centers in world coordinates
201 * @return True if extraction succeeded, otherwise false
202 */
203 static bool extractBullseyes(const AnyCamera& cameraA, const AnyCamera& cameraB, const Bullseyes& bullseyesA, const Bullseyes& bullseyesB, const CandidateMap& candidateMap, BullseyePairs& bullseyePairs, Vectors3& bullseyeCenters);
204
205 /**
206 * Computes a cost matrix for matching bullseyes based on candidate triangulation results.
207 * The cost matrix dimensions are (numBullseyesA x numBullseyesB), where each element (i, j)
208 * contains the cost of matching bullseye i from camera A with bullseye j from camera B.
209 * Costs are based on the triangulation quality (reprojection errors) and geometric consistency
210 * (comparing bullseye radii across cameras using the camera scale factor).
211 * @param cameraA The camera profile for the first camera, must be valid
212 * @param cameraB The camera profile for the second camera, must be valid
213 * @param bullseyesA The bullseyes detected in camera A, must not be empty
214 * @param bullseyesB The bullseyes detected in camera B, must not be empty
215 * @param candidateMap The map of candidate matches to evaluate, must not be empty
216 * @param costMatrix The resulting cost matrix with dimensions (numBullseyesA x numBullseyesB)
217 * @return True if the cost matrix was successfully computed, otherwise false
218 */
219 static bool computeCostMatrix(const AnyCamera& cameraA, const AnyCamera& cameraB, const Bullseyes& bullseyesA, const Bullseyes& bullseyesB, const CandidateMap& candidateMap, Matrix& costMatrix);
220
221 /**
222 * Returns an invalid (arbitrarily large) matching cost value used to indicate that two bullseyes cannot be matched.
223 * This value is large enough to prevent matching but not so large as to cause numerical issues.
224 * @return The invalid matching cost value
225 */
226 constexpr static Scalar invalidMatchingCost();
227
228 /**
229 * Triangulates a single matched bullseye pair to compute its 3D position in world coordinates.
230 * This function casts rays from both camera centers through the bullseye positions and finds their nearest point
231 * to determine the 3D location. It also computes reprojection errors to assess triangulation quality.
232 * @param cameraA The camera profile for the first camera, must be valid
233 * @param cameraB The camera profile for the second camera, must be valid
234 * @param world_T_cameraA The transformation from camera A coordinate system to world coordinate system, must be valid
235 * @param world_T_cameraB The transformation from camera B coordinate system to world coordinate system, must be valid
236 * @param bullseyeA The bullseye from camera A, must be valid and within camera A's field of view
237 * @param bullseyeB The bullseye from camera B, must be valid and within camera B's field of view
238 * @param bullseyeCenter The resulting 3D position of the bullseye center in world coordinates
239 * @param reprojectionErrorA The resulting reprojection error for camera A, in pixels
240 * @param reprojectionErrorB The resulting reprojection error for camera B, in pixels
241 * @return True if triangulation succeeded and the 3D point is in front of both cameras, otherwise false
242 */
243 static bool triangulateBullseye(const AnyCamera& cameraA, const AnyCamera& cameraB, const HomogenousMatrix4& world_T_cameraA, const HomogenousMatrix4& world_T_cameraB, const Bullseye& bullseyeA, const Bullseye& bullseyeB, Vector3& bullseyeCenter, Scalar& reprojectionErrorA, Scalar& reprojectionErrorB);
244};
245
247{
248 // Arbitrarily large value that doesn't cause numerical issues.
249 return Scalar(1000);
250}
251
252} // namespace Bullseyes
253
254} // namespace Detector
255
256} // namespace CV
257
258} // namespace Ocean
259
260#endif // OCEAN_CV_DETECTOR_BULLSEYES_BULLSEYEDETECTORSTEREO_H
This class implements the abstract base class for all AnyCamera objects.
Definition AnyCamera.h:130
This class holds the most important parameters for the detector.
Definition BullseyeDetectorMono.h:66
This class represents a candidate bullseye match between two stereo cameras.
Definition BullseyeDetectorStereo.h:89
static Vector3 invalidBullseyeCenter()
Returns an invalid bullseye center value used as a sentinel for uninitialized positions.
const Vector3 & center() const
Returns the triangulated 3D center position.
bool isValid() const
Returns whether this candidate is valid.
Candidate()=default
Creates a default (invalid) candidate.
Candidate(const Vector3 &center, const Scalar reprojectionErrorA, const Scalar reprojectionErrorB)
Creates a new candidate with the specified parameters.
Scalar reprojectionErrorA() const
Returns the reprojection error for camera A.
Scalar reprojectionErrorB() const
Returns the reprojection error for camera B.
This class holds the most important parameters for the stereo detector.
Definition BullseyeDetectorStereo.h:64
Parameters()=default
Creates a new parameter object with default parameters.
static Parameters defaultParameters()
Returns the default parameters for the stereo detector.
This class implements a stereo detector for bullseye patterns.
Definition BullseyeDetectorStereo.h:41
static constexpr Scalar invalidMatchingCost()
Returns an invalid (arbitrarily large) matching cost value used to indicate that two bullseyes cannot...
Definition BullseyeDetectorStereo.h:246
static CandidateMap extractBullseyeCandidates(const AnyCamera &cameraA, const AnyCamera &cameraB, const HomogenousMatrix4 &world_T_cameraA, const HomogenousMatrix4 &world_T_cameraB, const Bullseyes &bullseyesA, const Bullseyes &bullseyesB)
Extracts and validates candidate bullseye matches between two stereo cameras.
std::vector< BullseyePair > BullseyePairs
Definition of a vector holding bullseye pairs.
Definition BullseyeDetectorStereo.h:52
static bool triangulateBullseye(const AnyCamera &cameraA, const AnyCamera &cameraB, const HomogenousMatrix4 &world_T_cameraA, const HomogenousMatrix4 &world_T_cameraB, const Bullseye &bullseyeA, const Bullseye &bullseyeB, Vector3 &bullseyeCenter, Scalar &reprojectionErrorA, Scalar &reprojectionErrorB)
Triangulates a single matched bullseye pair to compute its 3D position in world coordinates.
std::unordered_map< IndexPair32, Candidate, PairHash > CandidateMap
Definition of an unordered map holding candidate bullseyes.
Definition BullseyeDetectorStereo.h:155
static bool detectBullseyes(const SharedAnyCameras &cameras, const Frames &yFrames, const HomogenousMatrix4 &world_T_device, const HomogenousMatrices4 &device_T_cameras, BullseyePairs &bullseyePairs, Vectors3 &bullseyeCenters, const Parameters &parameters=Parameters::defaultParameters(), Worker *worker=nullptr)
Detects bullseyes in a pair of stereo frames.
std::pair< Bullseye, Bullseye > BullseyePair
Definition of a pair of bullseyes.
Definition BullseyeDetectorStereo.h:47
std::array< Bullseyes, 2 > BullseyeGroup
Definition of a pair of vectors of bullseyes, one from each camera.
Definition BullseyeDetectorStereo.h:57
static bool computeCostMatrix(const AnyCamera &cameraA, const AnyCamera &cameraB, const Bullseyes &bullseyesA, const Bullseyes &bullseyesB, const CandidateMap &candidateMap, Matrix &costMatrix)
Computes a cost matrix for matching bullseyes based on candidate triangulation results.
static bool extractBullseyes(const AnyCamera &cameraA, const AnyCamera &cameraB, const Bullseyes &bullseyesA, const Bullseyes &bullseyesB, const CandidateMap &candidateMap, BullseyePairs &bullseyePairs, Vectors3 &bullseyeCenters)
Extracts the final bullseye pairs and their 3D centers from candidate matches.
Definition of a bullseye composed of a location and a radius.
Definition Bullseye.h:32
This class implements a worker able to distribute function calls over different threads.
Definition Worker.h:33
std::vector< Frame > Frames
Definition of a vector holding padding frames.
Definition Frame.h:1771
float Scalar
Definition of a scalar type.
Definition Math.h:129
std::vector< HomogenousMatrix4 > HomogenousMatrices4
Definition of a vector holding HomogenousMatrix4 objects.
Definition HomogenousMatrix4.h:73
std::vector< Vector3 > Vectors3
Definition of a vector holding Vector3 objects.
Definition Vector3.h:65
SharedAnyCamerasT< Scalar > SharedAnyCameras
Definition of a vector holding AnyCamera objects.
Definition AnyCamera.h:90
std::vector< Bullseye > Bullseyes
Definition of a vector holding bullseyes.
Definition Bullseye.h:103
The namespace covering the entire Ocean framework.
Definition Accessor.h:15