ivt_calibration.cpp
Go to the documentation of this file.
00001 
00018 #include <ivt_bridge/ivt_calibration.h>
00019 #include <boost/make_shared.hpp>
00020 
00021 #include <iostream>
00022 
00023 namespace ivt_bridge {
00024 
00025 cv::Mat_<double> matx34ToMat_(const cv::Matx<double, 3,4> &matx) {
00026         cv::Mat_<double>M(3,4);
00027         for (int i = 0; i < M.rows; ++i) {
00028                 for (int j = 0; j < M.cols; ++j) {
00029                         M(i,j) = matx(i,j);
00030                 }
00031         }
00032         return M;
00033 }
00034 
00035 cv::Mat_<double> matx33ToMat_(const cv::Matx<double, 3,3> &matx) {
00036         cv::Mat_<double>M(3,3);
00037         for (int i = 0; i < M.rows; ++i) {
00038                 for (int j = 0; j < M.cols; ++j) {
00039                         M(i,j) = matx(i,j);
00040                 }
00041         }
00042         return M;
00043 }
00044 
00045 cv::Mat_<double> matx35ToMat_(const cv::Matx<double, 3,5> &matx) {
00046         cv::Mat_<double>M(3,5);
00047         for (int i = 0; i < M.rows; ++i) {
00048                 for (int j = 0; j < M.cols; ++j) {
00049                         M(i,j) = matx(i,j);
00050                 }
00051         }
00052         return M;
00053 }
00054 
00055 
00056 boost::shared_ptr<CCalibration> calibrationImpl(const image_geometry::PinholeCameraModel& cam_model, bool forRectifiedImages){
00057         boost::shared_ptr<CCalibration> calibration = boost::make_shared<CCalibration>();
00058 
00059         Mat3d ivtR; Vec3d ivtt;
00060         // Set with + height
00061         calibration->SetCameraParameters(0, 0, 0, 0, 0, 0, 0, 0, ivtR, ivtt, cam_model.rawRoi().width, cam_model.rawRoi().height);
00062 
00063         cv::Mat_<double> projectionMatrix = matx34ToMat_(cam_model.projectionMatrix());
00064         cv::Mat_<double> intrinsicMatrix = matx33ToMat_(cam_model.intrinsicMatrix());
00065         cv::Mat_<double> R = matx33ToMat_(cam_model.rotationMatrix());
00066         cv::Mat_<double> t;
00067         const cv::Mat_<double> distortion;
00068 
00069         if (forRectifiedImages) {
00070                 cv::decomposeProjectionMatrix(projectionMatrix, intrinsicMatrix, R, t);
00071                 // IVT calibrates in mm while ROS does it in m. (-1) determined empirical.
00072                 t = t * -1000;
00073                 calibration->SetDistortion(0, 0, 0, 0);
00074         } else {
00075                 //intrinsicMatrix = cam_model.intrinsicMatrix();
00076                 // Rec = P[0,3]^(-1) * H * K (src:Learning OpenCV Book) => H = P[0,3] * Rec * K^(-1)
00077                 const cv::Mat_<double> H = projectionMatrix.colRange(0,3) * R * intrinsicMatrix.inv();
00078                 // P^(*) = H * P = H * K * [R|t] (src:  Image processing, Analysis, and Machine vision) => [R|t] = K^(-1) * H^(-1) * P^(*)
00079                 const cv::Mat_<double> Rt = intrinsicMatrix.inv() * H.inv() * projectionMatrix;
00080                 R = Rt.colRange(0,3);
00081                 // IVT calibrates in mm while ROS does it in m.
00082                 t = Rt.col(3) * 1000;
00083                 cv::Mat_<double> distortion = cam_model.distortionCoeffs();
00084                 calibration->SetDistortion(distortion(0,0), distortion(0,1), distortion(0,2), distortion(0,3));
00085         }
00086 
00087         calibration->SetIntrinsicBase(intrinsicMatrix(0,2), intrinsicMatrix(1,2), intrinsicMatrix(0,0), intrinsicMatrix(1,1));
00088 
00089         Math3d::SetMat(ivtR,
00090                         R(0,0), R(0,1), R(0,2),
00091                         R(1,0), R(1,1), R(1,2),
00092                         R(2,0), R(2,1), R(2,2));
00093         calibration->SetRotation(ivtR);
00094 
00095         Math3d::SetVec(ivtt, t(0,0), t(1,0), t(2,0));
00096         calibration->SetTranslation(ivtt);
00097 
00098         return calibration;
00099 
00100 }
00101 
00102 bool IvtCalibration::fromCameraInfo(const sensor_msgs::CameraInfo& msg){
00103         return cam_model.fromCameraInfo(msg);
00104 }
00105 
00106 bool IvtCalibration::fromCameraInfo(const sensor_msgs::CameraInfoConstPtr& msg){
00107         return cam_model.fromCameraInfo(msg);
00108 }
00109 
00110 boost::shared_ptr<CCalibration> IvtCalibration::getCalibration(bool forRectifiedImages) const{
00111         return calibrationImpl(cam_model, forRectifiedImages);
00112 }
00113 
00114 bool IvtStereoCalibration::fromCameraInfo(const sensor_msgs::CameraInfo& left, const sensor_msgs::CameraInfo& right){
00115         return cam_model.fromCameraInfo(left, right);
00116 }
00117 
00118 bool IvtStereoCalibration::fromCameraInfo(const sensor_msgs::CameraInfoConstPtr& left, const sensor_msgs::CameraInfoConstPtr& right){
00119         return cam_model.fromCameraInfo(left, right);
00120 }
00121 
00122 boost::shared_ptr<CStereoCalibration> IvtStereoCalibration::getStereoCalibration(bool forRectifiedImages) const{
00123         boost::shared_ptr<CStereoCalibration> stereoCalibration = boost::make_shared<CStereoCalibration>();
00124         stereoCalibration->SetSingleCalibrations(*calibrationImpl(cam_model.left(), forRectifiedImages), *calibrationImpl(cam_model.right(), forRectifiedImages), true);
00125 
00126         Mat3d Hl, Hr;
00127         cv::Mat_<double> projectionMatrixLeft = matx34ToMat_(cam_model.left().projectionMatrix());
00128         cv::Mat_<double> projectionMatrixRight = matx34ToMat_(cam_model.right().projectionMatrix());
00129         cv::Mat_<double> intrinsicMatrixLeft = matx33ToMat_(cam_model.left().intrinsicMatrix());
00130         cv::Mat_<double> intrinsicMatrixRight = matx33ToMat_(cam_model.right().intrinsicMatrix());
00131         cv::Mat_<double> RLeft = matx33ToMat_(cam_model.left().rotationMatrix());
00132         cv::Mat_<double> RRight = matx33ToMat_(cam_model.right().rotationMatrix());
00133 
00134         if (forRectifiedImages) {
00135                 // use identity
00136                 Math3d::SetMat(Hl, 1,0,0,0,1,0,0,0,1);
00137                 Math3d::SetMat(Hr, 1,0,0,0,1,0,0,0,1);
00138         } else {
00139                 // ivt saves H inverted
00140                 // Rec = P[0,3]^(-1) * H * K (src:Learning OpenCV Book) => H = P[0,3] * Rec * K^(-1)
00141                 const cv::Mat_<double> rectificationMatrixLeft = (projectionMatrixLeft.colRange(0,3) * RLeft * intrinsicMatrixLeft.inv()).inv();
00142                 Math3d::SetMat(Hl,
00143                                 rectificationMatrixLeft(0,0), rectificationMatrixLeft(0,1), rectificationMatrixLeft(0,2),
00144                                 rectificationMatrixLeft(1,0), rectificationMatrixLeft(1,1), rectificationMatrixLeft(1,2),
00145                                 rectificationMatrixLeft(2,0), rectificationMatrixLeft(2,1), rectificationMatrixLeft(2,2));
00146 
00147                 const cv::Mat_<double> rectificationMatrixRight = (projectionMatrixRight.colRange(0,3) * RRight * intrinsicMatrixRight.inv()).inv();
00148                 Math3d::SetMat(Hr,
00149                                 rectificationMatrixRight(0,0), rectificationMatrixRight(0,1), rectificationMatrixRight(0,2),
00150                                 rectificationMatrixRight(1,0), rectificationMatrixRight(1,1), rectificationMatrixRight(1,2),
00151                                 rectificationMatrixRight(2,0), rectificationMatrixRight(2,1), rectificationMatrixRight(2,2));
00152         }
00153 
00154         stereoCalibration->rectificationHomographyLeft = Hl;
00155         stereoCalibration->rectificationHomographyRight = Hr;
00156 
00157         return stereoCalibration;
00158 }
00159 
00160 
00161 } //namespace ivt_bridge


asr_ivt_bridge
Author(s): Hutmacher Robin, Kleinert Daniel, Meißner Pascal
autogenerated on Sat Jun 8 2019 19:52:36