Ocean
Loading...
Searching...
No Matches
CameraCalibrationManager.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_IO_CAMERA_CALIBRATION_MANAGER_H
9#define META_OCEAN_IO_CAMERA_CALIBRATION_MANAGER_H
10
11#include "ocean/io/IO.h"
12
14
15#include "ocean/io/JSONParser.h"
16
18
19#include <functional>
20
21namespace Ocean
22{
23
24namespace IO
25{
26
27/**
28 * This class implements a manager for camera calibrations using a modern JSON-based format.
29 * The manager supports multiple camera types through a factory pattern and can be extended with custom camera types.
30 *
31 * The manager supports device-specific calibrations through a device context system.
32 * Device context can be set at three specificity levels: product, version, or serial number.
33 * This allows users to specify simple camera names (e.g., "Back-facing Camera 0") and the manager
34 * automatically matches the appropriate calibration based on the current device context.
35 *
36 * Device Context Levels (from least to most specific):
37 * - Product: Broad product category (e.g., "Samsung S21 5G", "iPhone 13 Pro")
38 * - Version: Specific hardware variant (e.g., "SM-G991U", "A2483")
39 * - Serial: Individual device serial number (e.g., "ABC123456")
40 *
41 * By default, the manager supports "Ocean Pinhole" and "Ocean Fisheye" camera models, an example JSON file is:
42 * <pre>
43 * {
44 * "devices": [
45 * {
46 * "product": "Samsung S21 5G",
47 * "version": "SM-G991U",
48 * "serial": "ABC123456",
49 * "cameras": [
50 * {
51 * "name": "Back-facing Camera 0",
52 * "priority": 10,
53 * "calibrations": [...]
54 * }
55 * ]
56 * },
57 * {
58 * "product": "Samsung S21 5G",
59 * "version": "SM-G991U",
60 * "cameras": [...]
61 * }
62 * ],
63 * "cameras": [
64 * {
65 * "name": "Generic Camera",
66 * "aliases": ["Optional Alias 1", "Optional Alias 2"],
67 * "priority": 10,
68 * "calibrations": [
69 * {
70 * "resolution": {"width": 1920, "height": 1080},
71 * "model": "Ocean Pinhole",
72 * "configuration": "8_PARAMETERS",
73 * "parameters": [fx, fy, mx, my, k1, k2, p1, p2]
74 * "comment": "fully calibrated camera"
75 * },
76 * {
77 * "resolution": {"width": 640, "height": 480},
78 * "model": "Ocean Pinhole",
79 * "fovx": "1.05",
80 * "comment": "manually calibrate camera with approx. 60 degree of horizontal field of view"
81 * }
82 * ]
83 * }
84 * ]
85 * }
86 * </pre>
87 * @ingroup io
88 */
89class OCEAN_IO_EXPORT CameraCalibrationManager : public Singleton<CameraCalibrationManager>
90{
92
93 public:
94
95 /**
96 * Definition of different device context levels.
97 * The device context determines which cameras are visible during lookup operations.
98 */
99 enum DeviceContextLevel : uint32_t
100 {
101 /// No device context is set, only global cameras (without device context) are visible.
102 DCL_NONE = 0u,
103 /// Device context is set to a product name (least specific).
105 /// Device context is set to a hardware version/variant.
107 /// Device context is set to a device serial number (most specific).
108 DCL_SERIAL
109 };
110
111 /**
112 * Definition of different calibration qualities indicating how the calibration was obtained.
113 */
114 enum CalibrationQuality : uint32_t
115 {
116 /// Unknown or invalid calibration quality.
117 CQ_UNKNOWN = 0u,
118 /// The calibration was interpolated from a calibration with a different resolution but the same aspect ratio.
120 /// The calibration exactly matches the requested resolution.
121 CQ_EXACT
122 };
123
124 /**
125 * Definition of a factory function that creates a SharedAnyCamera from a JSON model object.
126 * @param modelObject The JSON object containing the camera model calibration, must be valid
127 * @return The created camera object, nullptr if creation failed
128 */
129 using FactoryFunction = std::function<SharedAnyCamera(const JSONParser::JSONValue& modelObject)>;
130
131 protected:
132
133 /**
134 * This class stores multiple camera calibrations with the same priority.
135 * Each Calibrations object can hold camera models for different resolutions, but all share the same priority level.
136 */
138 {
139 public:
140
141 /**
142 * Creates a new Calibrations object with a specific priority.
143 * @param priority The priority of the calibrations, higher values indicate higher priority, with range (-infinity, infinity)
144 * @param deviceProduct Optional device product for this calibration group (e.g., "Samsung S21 5G
145 * @param deviceVersion Optional device version for this calibration group (e.g., "SM-G991U")
146 * @param deviceSerial Optional device serial for this calibration group (e.g., "ABC123456")
147 */
148 inline CalibrationGroup(const int32_t priority, const std::string& deviceProduct = std::string(), const std::string& deviceVersion = std::string(), const std::string& deviceSerial = std::string());
149
150 /**
151 * Adds a camera model to this calibration group.
152 * @param camera The camera to add, must be valid
153 * @return True if the camera was added successfully, false if a camera with the same resolution already exists
154 */
156
157 /**
158 * Returns the best matching camera calibration for a given resolution.
159 * The function first tries to find an exact resolution match.
160 * If no exact match is found, it tries to interpolate a calibration from cameras with the same aspect ratio.
161 * @param width The width of the requested camera image in pixels, with range [1, infinity)
162 * @param height The height of the requested camera image in pixels, with range [1, infinity)
163 * @param calibrationQuality The resulting quality of the calibration
164 * @return The best matching camera model, nullptr if no match was found
165 */
166 SharedAnyCamera camera(const unsigned int width, const unsigned int height, CalibrationQuality& calibrationQuality) const;
167
168 /**
169 * Checks whether this calibration group matches the given device context.
170 * @param deviceContextLevel The device context level to check against
171 * @param deviceContextValue The device context value (product, version, or serial)
172 * @return True if this calibration group matches the device context, false otherwise
173 */
174 bool matchesDeviceContext(const DeviceContextLevel deviceContextLevel, const std::string& deviceContextValue) const;
175
176 /**
177 * Returns the number of camera calibrations in this group.
178 * @return The number of calibrations
179 */
180 inline size_t size() const;
181
182 public:
183
184 /// The priority of all calibrations in this group, higher values indicate higher priority.
185 int32_t priority_ = 0;
186
187 /// All camera models with individual resolutions.
189
190 /// Optional device product for this calibration group (e.g., "Samsung S21 5G", "iPhone 13 Pro"), empty if not set.
191 std::string deviceProduct_;
192
193 /// Optional device version for this calibration group (e.g., "SM-G991U", "A2483"), empty if not set.
194 std::string deviceVersion_;
195
196 /// Optional device serial for this calibration group (e.g., "ABC123456"), empty if not set.
197 std::string deviceSerial_;
198 };
199
200 /**
201 * Definition of a vector holding calibration groups.
202 */
203 using CalibrationGroups = std::vector<CalibrationGroup>;
204
205 /**
206 * Definition of a map mapping camera model names to factory functions.
207 */
208 using FactoryFunctionMap = std::unordered_map<std::string, FactoryFunction>;
209
210 /**
211 * Definition of a map mapping camera names to calibration groups.
212 */
213 using CameraMap = std::unordered_map<std::string, CalibrationGroups>;
214
215 /**
216 * Definition of a map mapping camera aliases to their actual camera names.
217 */
218 using AliasMap = std::unordered_map<std::string, std::string>;
219
220 public:
221
222 /**
223 * Returns a camera for a given camera name and resolution.
224 * The function will find the best matching calibration for the given resolution.<br>
225 * First, it searches for exact resolution matches. If none are found, it attempts to interpolate from calibrations with the same aspect ratio.<br>
226 * When multiple calibrations are available, the one with the highest priority and best quality is selected.
227 * The camera lookup is filtered based on the current device context (if set).
228 * @param cameraName The name of the camera (or alias), must be valid
229 * @param width The width of the camera image in pixels, with range [1, infinity)
230 * @param height The height of the camera image in pixels, with range [1, infinity)
231 * @param calibrationQuality Optional resulting calibration quality, nullptr if not of interest
232 * @return The camera model, nullptr if no matching calibration was found
233 * @see setDeviceProduct(), setDeviceVersion(), setDeviceSerial()
234 */
235 SharedAnyCamera camera(const std::string& cameraName, unsigned int width, unsigned int height, CalibrationQuality* calibrationQuality = nullptr) const;
236
237 /**
238 * Sets the device context to a specific product name.
239 * When set, only cameras associated with this product (and no version/serial constraints) will be visible during lookup.
240 * @param product The product name (e.g., "Samsung S21 5G", "iPhone 13 Pro"), must be valid
241 * @return True if the device context was set successfully
242 * @see clearDeviceContext()
243 */
244 bool setDeviceProduct(const std::string& product);
245
246 /**
247 * Sets the device context to a specific hardware version/variant.
248 * When set, only cameras associated with this version will be visible during lookup.
249 * @param version The hardware version/variant identifier (e.g., "SM-G991U", "A2483"), must be valid
250 * @return True if the device context was set successfully
251 * @see clearDeviceContext()
252 */
253 bool setDeviceVersion(const std::string& version);
254
255 /**
256 * Sets the device context to a specific device serial number.
257 * When set, only cameras associated with this exact serial number will be visible during lookup.
258 * @param serial The device serial number (e.g., "ABC123456"), must be valid
259 * @return True if the device context was set successfully
260 * @see clearDeviceContext()
261 */
262 bool setDeviceSerial(const std::string& serial);
263
264 /**
265 * Clears the device context.
266 * After clearing, only global cameras (without device context) will be visible during lookup.
267 */
269
270 /**
271 * Registers calibrations from a JSON file.
272 * @param url The URL or file path of the JSON calibration file, must be valid
273 * @return True if the calibrations were registered successfully, false otherwise
274 */
275 bool registerCalibrations(const std::string& url);
276
277 /**
278 * Registers calibrations from a memory buffer containing JSON data.
279 * @param buffer The memory buffer containing the JSON calibration data, must be valid
280 * @param size The size of the buffer in bytes, with range [1, infinity)
281 * @return True if the calibrations were registered successfully, false otherwise
282 */
283 bool registerCalibrations(const void* buffer, const size_t size);
284
285 /**
286 * Registers calibrations from a parsed JSON value.
287 * @param jsonValue The parsed JSON value, must be a valid object holding the calibration
288 * @return True if the calibrations were registered successfully, false otherwise
289 */
291
292 /**
293 * Registers a single camera calibration with a specific priority.
294 * @param cameraName The name of the camera, must be valid
295 * @param camera The camera model to register, must be valid
296 * @param priority The priority of this calibration, higher values indicate higher priority, with range (-infinity, infinity)
297 * @return True if the camera was registered successfully
298 * @see registerCalibrations()
299 */
300 bool registerCamera(const std::string& cameraName, SharedAnyCamera&& camera, const int32_t priority);
301
302 /**
303 * Registers a new camera factory for a specific camera type.
304 * Factory functions are used to create camera objects from JSON model configurations.
305 * @param modelName The name of the camera model, e.g., "Custom Camera", must be valid
306 * @param factoryFunction The factory function to create cameras of the specified model, nullptr to unregister a factory
307 * @return True if the factory was registered successfully, false if a factory for the same model name already exists
308 */
309 bool registerFactoryFunction(const std::string& modelName, FactoryFunction&& factoryFunction);
310
311 /**
312 * Parses one camera calibration from a file or a string/buffer containing the JSON calibration object for only one camera model.
313 * The provided JSON object must have the following structure:
314 * <pre>
315 * {
316 * "resolution": {"width": <WIDTH_IN_PIXELS>, "height": <HEIGHT_IN_PIXELS>},
317 * "model": "<MODEL_NAME>",
318 * "configuration": "<PARAMETER_CONFIGURATION>",
319 * "parameters": [<PARAMETER_1>, <PARAMETER_2>, ...],
320 * }
321 * </pre>
322 * @param jsonCameraCalibrationFile The file path of the JSON calibration file, empty in case a buffer is provided via 'jsonCameraCalibrationBuffer'
323 * @param jsonCameraCalibrationBuffer The JSON string/buffer containing the camera calibration, empty in case a file is provided via 'jsonCameraCalibrationFile'
324 * @return The parsed camera object, nullptr in case of an error
325 */
326 SharedAnyCamera parseCamera(const std::string& jsonCameraCalibrationFile, std::string&& jsonCameraCalibration = std::string()) const;
327
328 /**
329 * Clears all registered calibrations and aliases.
330 * This function does not remove registered factory functions.
331 */
332 void clear();
333
334 /**
335 * Parses the resolution of a camera from a JSON calibration object.
336 * @param calibrationObject The JSON calibration object, must be valid
337 * @param width The resulting width in pixels
338 * @param height The resulting height in pixels
339 * @return True if the resolution was parsed successfully
340 */
341 static bool parseResolution(const JSONParser::JSONValue& calibrationObject, unsigned int& width, unsigned int& height);
342
343 protected:
344
345 /**
346 * Protected default constructor.
347 * Automatically registers the built-in factory functions for "Ocean Pinhole" and "Ocean Fisheye" camera models.
348 */
350
351 /**
352 * Registers cameras from a JSON cameras array with optional device context.
353 * @param camerasArray The JSON array containing camera definitions, must be valid
354 * @param deviceProduct Optional device product name, empty for global cameras
355 * @param deviceVersion Optional device version, empty for global cameras
356 * @param deviceSerial Optional device serial number, empty for global cameras
357 * @return True if at least one camera was registered successfully
358 */
359 bool registerCameras(const JSONParser::JSONValue::Array& camerasArray, const std::string& deviceProduct = std::string(), const std::string& deviceVersion = std::string(), const std::string& deviceSerial = std::string());
360
361 /**
362 * Factory function able to create the "Ocean Pinhole" camera model from a JSON configuration.
363 * @param modelObject The JSON object containing the camera model configuration, must be valid
364 * @return The created camera object, nullptr if creation failed
365 */
367
368 /**
369 * Factory function able to create the "Ocean Fisheye" camera model from a JSON configuration.
370 * @param modelObject The JSON object containing the camera model configuration, must be valid
371 * @return The created camera object, nullptr if creation failed
372 */
374
375 protected:
376
377 /// The map mapping camera model names to factory functions.
379
380 /// The map mapping camera names to calibration groups.
382
383 /// The map mapping camera aliases to their actual camera names.
385
386 /// The current device context level.
387 DeviceContextLevel deviceContextLevel_ = DCL_NONE;
388
389 /// The current device context value (product, version, or serial depending on deviceContextLevel_).
391
392 /// The lock for thread-safe access to all manager data.
393 mutable Lock lock_;
394};
395
396inline CameraCalibrationManager::CalibrationGroup::CalibrationGroup(const int32_t priority, const std::string& deviceProduct, const std::string& deviceVersion, const std::string& deviceSerial) :
397 priority_(priority),
398 deviceProduct_(std::move(deviceProduct)),
399 deviceVersion_(std::move(deviceVersion)),
400 deviceSerial_(std::move(deviceSerial))
401{
402 // nothing to do here
403}
404
406{
407 return cameras_.size();
408}
409
410}
411
412}
413
414#endif // META_OCEAN_IO_CAMERA_CALIBRATION_MANAGER_H
This class stores multiple camera calibrations with the same priority.
Definition CameraCalibrationManager.h:138
size_t size() const
Returns the number of camera calibrations in this group.
Definition CameraCalibrationManager.h:405
SharedAnyCamera camera(const unsigned int width, const unsigned int height, CalibrationQuality &calibrationQuality) const
Returns the best matching camera calibration for a given resolution.
CalibrationGroup(const int32_t priority, const std::string &deviceProduct=std::string(), const std::string &deviceVersion=std::string(), const std::string &deviceSerial=std::string())
Creates a new Calibrations object with a specific priority.
Definition CameraCalibrationManager.h:396
std::string deviceVersion_
Optional device version for this calibration group (e.g., "SM-G991U", "A2483"), empty if not set.
Definition CameraCalibrationManager.h:194
bool matchesDeviceContext(const DeviceContextLevel deviceContextLevel, const std::string &deviceContextValue) const
Checks whether this calibration group matches the given device context.
SharedAnyCameras cameras_
All camera models with individual resolutions.
Definition CameraCalibrationManager.h:188
std::string deviceSerial_
Optional device serial for this calibration group (e.g., "ABC123456"), empty if not set.
Definition CameraCalibrationManager.h:197
std::string deviceProduct_
Optional device product for this calibration group (e.g., "Samsung S21 5G", "iPhone 13 Pro"),...
Definition CameraCalibrationManager.h:191
bool addCamera(SharedAnyCamera &&camera)
Adds a camera model to this calibration group.
This class implements a manager for camera calibrations using a modern JSON-based format.
Definition CameraCalibrationManager.h:90
bool registerFactoryFunction(const std::string &modelName, FactoryFunction &&factoryFunction)
Registers a new camera factory for a specific camera type.
AliasMap aliasMap_
The map mapping camera aliases to their actual camera names.
Definition CameraCalibrationManager.h:384
std::unordered_map< std::string, FactoryFunction > FactoryFunctionMap
Definition of a map mapping camera model names to factory functions.
Definition CameraCalibrationManager.h:208
bool registerCalibrations(const std::string &url)
Registers calibrations from a JSON file.
FactoryFunctionMap factoryFunctionMap_
The map mapping camera model names to factory functions.
Definition CameraCalibrationManager.h:378
bool registerCameras(const JSONParser::JSONValue::Array &camerasArray, const std::string &deviceProduct=std::string(), const std::string &deviceVersion=std::string(), const std::string &deviceSerial=std::string())
Registers cameras from a JSON cameras array with optional device context.
SharedAnyCamera parseCamera(const std::string &jsonCameraCalibrationFile, std::string &&jsonCameraCalibration=std::string()) const
Parses one camera calibration from a file or a string/buffer containing the JSON calibration object f...
void clear()
Clears all registered calibrations and aliases.
CalibrationQuality
Definition of different calibration qualities indicating how the calibration was obtained.
Definition CameraCalibrationManager.h:115
@ CQ_INTERPOLATED
The calibration was interpolated from a calibration with a different resolution but the same aspect r...
Definition CameraCalibrationManager.h:119
std::vector< CalibrationGroup > CalibrationGroups
Definition of a vector holding calibration groups.
Definition CameraCalibrationManager.h:203
bool setDeviceProduct(const std::string &product)
Sets the device context to a specific product name.
std::function< SharedAnyCamera(const JSONParser::JSONValue &modelObject)> FactoryFunction
Definition of a factory function that creates a SharedAnyCamera from a JSON model object.
Definition CameraCalibrationManager.h:129
static bool parseResolution(const JSONParser::JSONValue &calibrationObject, unsigned int &width, unsigned int &height)
Parses the resolution of a camera from a JSON calibration object.
static SharedAnyCamera createOceanFisheye(const JSONParser::JSONValue &modelObject)
Factory function able to create the "Ocean Fisheye" camera model from a JSON configuration.
std::unordered_map< std::string, std::string > AliasMap
Definition of a map mapping camera aliases to their actual camera names.
Definition CameraCalibrationManager.h:218
Lock lock_
The lock for thread-safe access to all manager data.
Definition CameraCalibrationManager.h:393
CameraMap cameraMap_
The map mapping camera names to calibration groups.
Definition CameraCalibrationManager.h:381
void clearDeviceContext()
Clears the device context.
std::unordered_map< std::string, CalibrationGroups > CameraMap
Definition of a map mapping camera names to calibration groups.
Definition CameraCalibrationManager.h:213
bool setDeviceVersion(const std::string &version)
Sets the device context to a specific hardware version/variant.
bool setDeviceSerial(const std::string &serial)
Sets the device context to a specific device serial number.
bool registerCalibrations(const void *buffer, const size_t size)
Registers calibrations from a memory buffer containing JSON data.
CameraCalibrationManager()
Protected default constructor.
bool registerCamera(const std::string &cameraName, SharedAnyCamera &&camera, const int32_t priority)
Registers a single camera calibration with a specific priority.
SharedAnyCamera camera(const std::string &cameraName, unsigned int width, unsigned int height, CalibrationQuality *calibrationQuality=nullptr) const
Returns a camera for a given camera name and resolution.
static SharedAnyCamera createOceanPinhole(const JSONParser::JSONValue &modelObject)
Factory function able to create the "Ocean Pinhole" camera model from a JSON configuration.
std::string deviceContextValue_
The current device context value (product, version, or serial depending on deviceContextLevel_).
Definition CameraCalibrationManager.h:390
bool registerCalibrations(const JSONParser::JSONValue &jsonValue)
Registers calibrations from a parsed JSON value.
DeviceContextLevel
Definition of different device context levels.
Definition CameraCalibrationManager.h:100
@ DCL_VERSION
Device context is set to a hardware version/variant.
Definition CameraCalibrationManager.h:106
@ DCL_PRODUCT
Device context is set to a product name (least specific).
Definition CameraCalibrationManager.h:104
This class implements a JSON value that can hold different JSON types.
Definition JSONParser.h:35
std::vector< JSONValue > Array
Definition of a JSON array (vector of JSONValue).
Definition JSONParser.h:62
This class implements a recursive lock object.
Definition Lock.h:31
This template class is the base class for all singleton objects.
Definition Singleton.h:71
std::shared_ptr< AnyCamera > SharedAnyCamera
Definition of a shared pointer holding an AnyCamera object with Scalar precision.
Definition AnyCamera.h:61
SharedAnyCamerasT< Scalar > SharedAnyCameras
Definition of a vector holding AnyCamera objects.
Definition AnyCamera.h:91
The namespace covering the entire Ocean framework.
Definition Accessor.h:15