This is the documentation for libCalib, the C++ camera calibration library.
libCalib is a feature rich library with functions relating to geometrical camera calibration. It allows the user to automatically detect calibration targets and run optimization on the calibration setup. An arbitrary number of cameras, targets and poses is supported.
To get started, please see the examples directory, which show libCalib used in a number of different scenarios.
Defining and solving a camera calibration task can be summarized by the following steps:
find*()
function from detection.h.subpix*()
function declared in subpix.h.Features are the well-defined geometrical entities on a calibration target. Feature detection consists broadly of two steps: detection and subpixel refinement. They must have accurately defined positions. The detection step aims to find the collection of features for a particular calibration target. Subpixel refinement generally treats each observed feature independently and optimizes the detected position of it.
The 'calibration setup' describes the number of physical cameras, calibration targets, and detections. libCalib supports an arbitrary number of cameras and calibration targets. When more than one camera is used, this is generally referred to as stereo or multi-camera calibration. When more than one target is present, this is called network calibration. The particular use-cases of single camera or single target calibration are just special cases of multi-camera network calibration, and as such, the classes and function calls of libCalib are called the same no matter which situation is present.
Individual physical cameras are represented by instances of the Camera class, and each Camera class owns an instance of a specific CameraModel-derived class. Camera also has an associated roto-translation transform which describes its pose relative to the first (index 0) camera. The collection of cameras is called the camera rig, and it is assumed that the relative transformations between cameras are constant during and after calibration.
Different calibration targets can be used, given that they can be uniquely identified. This is possible with e.g. ChAruCo targets and AruCo coded targets. However, after the detection step, Target objects are unaware of their coding type, and hold only geometric information on the nominal positions (3D) of features in their own coordinate frames. The collection of targets is called target rig. Each target's transform brings locally defined features coordinates into the first (index 0) target's coordinate frame. These transforms are assumed to be constant during calibration.
Positioning the rigid camera rig in a particular position and orientation relative to the target rig defines a Pose.
Seeing a specific calibration target in a particular image constitutes a Detection. The Detection object has indices pointing to the Camera, the Target and the Pose.
Defining the calibration setup in libCalib entails creating a Calibration object. Camera objects, Target objects and Pose objects are added to this object whereby they receive indices.
Initializing the calibration is necessary, as otherwise, the following optimization step would most likely find a local minimum solution and not converge to the globally optimal solution. libCalib uses variants of the well-known Zhang method to initialize cameras individually and then solves for the multi-camera and target network transforms by means of unique graph optimization methods. In this process, a few of the most important intrinsic camera parameters are determined as well as all extrinsic parameters.
Note that a required prerequisite for successful initialization is that all transforms are in fact observed and constrained. This means that a transform chain must exist between any camera and target.
Initialization is done by the user by calling Calibration::initialize(). The returning results struct contains information on the success of the operation.
While initialization uses closed-form formulations to solve for a good initial guess of intrinsic and extrinsic parameters, the optimization step used nonlinear bundle block adjustment to refine these parameter estimates, and include all aspects of the chosen camera model. Mathematically, the optimization routine transforms all nominal feature point positions to the observing camera and propagates it through the camera model with the current parameter estimates, and determines a two-element residual between detected and projected point. The objective function aims to minimize the sum of squares of these residuals (or equivalently the RMS of reprojection-errors).
The optimization routine uses trust-region Levenberg-Marquardt algorithms with optional robust Huber-norm.
Optimization is started by the user through a call to Calibration::optimize(). Options are set using an OptimizationSettings object. A call-back can also be installed to receive feedback on the progress during optimization.
Once optimization has completed, is is generally necessary to carefully inspect calibration results and RPE statistics to determine if the calibration is sufficiently accurate and stable. For this purpose, libCalib has a variety of statistical and graphical functions defined in analysis.h.
Use of the libCalib library is subject to Calib.io's EULA (end user license agreement). Upon obtaining a node-locked license key, the machine must be registered online. This is done by setting environment variable "LIBCALIB_LICENSE_KEY" to your license key and running a libCalib function from within your program. This can be e.g. checkLicense() declared in license.h. Machine specific license information will be cached in the .LicenseSpring folder. The environment variable can be reset after initial registration. Changes to hardware components will require that you unregister, then re-register the machine. Please contact suppo for assistance. rt@c alib. io
https://calib.io/products/calib
sales @cal ib.io