part of camodocal. Originally developed by Lionel Heng.
Google Ceres
Eigen3
OpenCV 3
Boost
mkdir build
cmake ..
make
It is very easy to adapt this into your own projects. You will need
to copy the include
and src
directories to your project and
edit your cmake files accordingly. Look at my cmake file to know how to do it.
Use intrinsic_calib.cc to calibrate your camera. You may use github-krosutils to get images out of a bag recording.
Go here to get printable checkerboards of various dimensions.
$ ./Calibration -w 9 -h 6 -s 35 -i ~/try/left_images -p image -e .png --camera-name leftcamera --view-results
$ ./Calibration --help
Allowed options:
--help produce help message
-w [ --width ] arg (=8) Number of inner corners on the
chessboard pattern in x direction
-h [ --height ] arg (=12) Number of inner corners on the
chessboard pattern in y direction
-s [ --size ] arg (=7) Size of one square in mm
-i [ --input ] arg (=calibrationdata) Input directory containing chessboard
images
-p [ --prefix ] arg (=left-) Prefix of images
-e [ --file-extension ] arg (=.png) File extension of images
--camera-model arg (=mei) Camera model: kannala-brandt | mei |
pinhole
--camera-name arg (=camera) Name of camera
--opencv Use OpenCV to detect corners
--view-results View results
-v [ --verbose ] Verbose output
$ ./Calibration_Stereo -w 9 -h 6 -s 37.4 -i ~/try/sync_stereo_pairs/ --prefix-l leftimage- --prefix-r rightimage- -e .png --view-result
$ ./Calibration_Stereo --help
Allowed options:
--help produce help message
-w [ --width ] arg (=9) Number of inner corners on the chessboard
pattern in x direction
-h [ --height ] arg (=6) Number of inner corners on the chessboard
pattern in y direction
-s [ --size ] arg (=120) Size of one square in mm
-i [ --input ] arg (=images) Input directory containing chessboard
images
-o [ --output ] arg (=.) Output directory containing calibration
data
--prefix-l arg (=left) Prefix of images from left camera
--prefix-r arg (=right) Prefix of images from right camera
-e [ --file-extension ] arg (=.bmp) File extension of images
--camera-model arg (=mei) Camera model: kannala-brandt | mei |
pinhole
--camera-name-l arg (=camera_left) Name of left camera
--camera-name-r arg (=camera_right) Name of right camera
--opencv Use OpenCV to detect corners
--view-results View results
-v [ --verbose ] Verbose output
See Camera.h for general interface:
Two main files for you to use camera model: Camera.h and CameraFactory.h.
Use function in CameraFactory.h to load in the camra calibration file:
#include <camera_model/camera_models/CameraFactory.h>
camera_model::CameraPtr cam;
void loadCameraFile(std::string camera_model_file)
{
cam = camera_model::CameraFactory::instance()->generateCameraFromYamlFile(camera_model_file);
}
void makeFromScratch( )
{
cam = camodocal::CameraFactory::instance()->generateCamera( camodocal::Camera::PINHOLE, "my_camera", cv::Size(480,640) );
vector<double>parameterVec;
cam->writeParameters( parameterVec );
parameterVec[4] = 481.20; //fx
parameterVec[5] = 480.; //fy
parameterVec[6] = 319.50; //cx
parameterVec[7] = 239.50; //cy
cam->readParameters( parameterVec );
cout << "Cam:\n" << cam->parametersToString() << endl;
// Similarly other camera types can also be loaded from scratch,
// just be careful on the ordering of the parameterVec, see relavant source code for details.
}
See Camera.h for general interface:
Projection (3D ---> 2D) function: spaceToPlane :Projects 3D points to the image plane (Pi function)
#include <camera_model/camera_models/CameraFactory.h>
camera_model::CameraPtr cam;
void loadCameraFile(std::string camera_model_file)
{
cam = camera_model::CameraFactory::instance()->generateCameraFromYamlFile(camera_model_file);
}
void useProjection(Eigen::Vector3d P)
{
Eigen::Vector2d p_dst;
cam->spaceToPlane(P, p_dst);
}
Back Projection (2D ---> 3D) function: liftSphere: Lift points from the image plane to the projective space.
#include <camera_model/camera_models/CameraFactory.h>
camera_model::CameraPtr cam;
void loadCameraFile(std::string camera_model_file)
{
cam = camera_model::CameraFactory::instance()->generateCameraFromYamlFile(camera_model_file);
}
void useProjection(Eigen::Vector3d P)
{
Eigen::Vector2d p_dst;
cam->spaceToPlane(P, p_dst);
}
void useBackProjection(Eigen::Vector2d p)
{
Eigen::Vector3d P_dst;
cam->liftSphere(p, P_dst);
}
- liftProjective
- normalize vector
- K.inverse() * [ u;v;1]
- apply inverse distortion
- P := (X/Z, Y/Z)
- \pho := apply distortion to P
- K . \pho
=> if input to spaceToPlane is (u,v,1) instead of a real 3d point, it has the effect of applying distorion to this point, assuming the input (u,v,1) is normalized image co-ordinate
Example usage of camodocal by mpkuse.
- 1_readcamera_from_yaml.cpp: How to initialize CameraPtr with yaml file.
- 2_readcamera_from_scratch.cpp: How to initialize CameraPtr with hardcoded params