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
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
00072 t = t * -1000;
00073 calibration->SetDistortion(0, 0, 0, 0);
00074 } else {
00075
00076
00077 const cv::Mat_<double> H = projectionMatrix.colRange(0,3) * R * intrinsicMatrix.inv();
00078
00079 const cv::Mat_<double> Rt = intrinsicMatrix.inv() * H.inv() * projectionMatrix;
00080 R = Rt.colRange(0,3);
00081
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
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
00140
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 }