## Accurate geometric camera calibration ##
## Overview ##
This repository contains a tool for **accurate geometric camera calibration**,
i.e., establishing a mapping between image pixels and the pixels' 3D observation
directions respectively lines. In particular, it supports calibration with
**generic** camera models, which fit nearly every camera and allow for highly
accurate calibration. The tool also includes support to calibrate
**fixed camera rigs** and additionally supports estimating
**accurate depth images for stereo cameras** such as the Intel D435 or the
Occipital Structure Core.
The requirements on the camera are:
* The camera must be near-central, i.e., all observation lines must approximately pass
through the same 3D point. This is because a central camera model is used for initialization.
There is support for a fully non-central model, but not for initializing directly with it
(however, re-implementations of Ramalingam and Sturm's initialization methods for
all combinations of central/non-central cameras and planar/non-planar calibrations patterns
are available in [applications/camera_calibration/src/camera_calibration/relative_pose_initialization](https://github.com/puzzlepaint/camera_calibration/tree/master/applications/camera_calibration/src/camera_calibration/relative_pose_initialization)).
* The observation directions / lines must vary smoothly. For example,
there should not be a mirror within the field-of-view of the camera that ends
abruptly. This is because observation directions / lines are stored sparsely
and are interpolated smoothly.
For depth estimation and live feature detection, a CUDA-capable graphics card is required.
The application has been tested on Ubuntu Linux only.
## About ##
This repository contains the
[Camera calibration application](https://github.com/puzzlepaint/camera_calibration/tree/master/applications/camera_calibration)
and the library it is based on,
[libvis](https://github.com/puzzlepaint/camera_calibration/tree/master/libvis).
The library is work-in-progress and it is not recommended to use it for other projects at this point.
The application and library code is licensed under the BSD license, but please
also notice the licenses of the included or externally used third-party components.
If you use the provided code for research, please cite the paper describing the approach:
[Thomas Schöps, Viktor Larsson, Marc Pollefeys, Torsten Sattler, "Why Having 10,000 Parameters in Your Camera Model is Better Than Twelve", arXiv 2019.](https://arxiv.org/abs/1912.02908)
## Building ##
Building has been tested on Ubuntu 14.04 and Ubuntu 18.04 (with gcc).
The following external dependencies are required.
| Dependency | Version(s) known to work |
| ------------ | ------------------------ |
| [Boost](https://www.boost.org/) | 1.54.0 |
| [CUDA](https://developer.nvidia.com/cuda-downloads) | 10.1 |
| [Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page) | 3.3.7 |
| [GLEW](http://glew.sourceforge.net/build.html) | 1.10.0 |
| [OpenGV](https://github.com/laurentkneip/opengv) | Commit 306a54e6c6b94e2048f820cdf77ef5281d4b48ad |
| [Qt](https://www.qt.io/) | 5.12.0; minimum version: 5.8 |
| [SuiteSparse](http://faculty.cse.tamu.edu/davis/suitesparse.html) | 4.2.1 |
| [zlib](https://zlib.net/) | - |
The following external dependencies are optional.
| Dependency | Purpose |
| ------------ | ------- |
| [librealsense2](https://github.com/IntelRealSense/librealsense) | Live input from RealSense D400 series depth cameras (tested with the D435 only). |
| [Structure SDK](https://structure.io/developers) | Live input from Structure Core cameras (tested with the color version only). To use this, set the SCSDK_ROOT CMake variable to the SDK path. |
After obtaining all dependencies, the application can be built with CMake, for example as follows:
```bash
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_CUDA_FLAGS="-arch=sm_61" ..
make -j camera_calibration # Reduce the number of threads if running out of memory, e.g., -j3
```
If you intend to use the depth estimation or live feature detection functionalities,
make sure to specify suitable CUDA architecture(s) in CMAKE_CUDA_FLAGS.
Common settings would either be the CUDA architecture of your graphics card only (in case
you only intend to run the compiled application on the system it was compiled on), or a range of virtual
architectures (in case the compiled application is intended for distribution).
See the [corresponding CUDA documentation](https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#options-for-steering-gpu-code-generation-gpu-architecture).
## How to use ##
### Obtaining a calibration pattern ###
This is a prerequisite for calibration.
The first step is to choose a suitable pattern. Ideally, the density of features
on the pattern is chosen to be appropriate for the resolution of the camera to
be calibrated. For example, a high-resolution camera can observe many features
at the same time, so a high feature density helps in quickly obtaining enough
calibration data. However, this pattern may not be well-suited for a low-resolution
camera, which cannot sharply observe all features at the same time. It should
also be considered that high numbers of features (either due to high density, or
due to using multiple patterns at the same time) significantly increase the time
required to perform the calibration.
Some readily usable patterns with different feature densities, generated for
DIN A4 sized paper, are included in the
[patterns](https://github.com/puzzlepaint/camera_calibration/tree/master/applications/camera_calibration/patterns) folder.
Each pattern consists of a PDF file for display and a YAML file that describes the pattern content.
The YAML file later needs to be passed to the camera calibration program such that it can detect
the corresponding pattern.
If the provided patterns are not sufficient, you can
generate additional patterns with the pattern generation script [scripts/create_calibration_pattern.py](https://github.com/puzzlepaint/camera_calibration/tree/master/applications/camera_calibration/scripts/create_calibration_pattern.py). The script uses [ReportLab](https://www.reportlab.com/) to generate the PDF file,
which may be installed like: `sudo pip[3] install reportlab`. It also depends on
numpy. Call the script as follows to see its usage:
`python[3] create_calibration_pattern.py -h`. Only the `--tag36h11_path` and
`--output_base_path` arguments are mandatory.
After deciding for one or multiple patterns, the second step is to choose how to
present the pattern(s) to the camera:
* One way is to **print** the pattern(s). It is possible to use multiple printed patterns
at the same time. This may for example help to fully calibrate fisheye cameras
with a very large field-of-view, since the pattern geometry is not limited to
a plane then. In this case, make sure that each printed pattern uses a unique
AprilTag index. Note that the final pattern(s) must be rigid, fixed wrt. each
other, and each individual pattern should be near-planar.
Planarity is assumed for initialization purposes, but not for later stages in
the calibration. Thus, as long as initialization works, the final accuracy is not
negatively affected by non-planar patterns in any way.
* Another way is to **show the pattern on a display** such as a computer monitor.
The application includes direct support to do this, while also showing the
feature coverage while not recording images. See below for how to use this.
This way, only a single pattern can be used at a time. If multiple patterns
are given, the current pattern can be changed with the arrow keys.
### Calibrating a camera with live input ###
Live input has the advantage that the coverage of the camera view with feature
detections is shown in real-time during recording, showing where additional data
is still needed. However, th