ceres_utest.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (Apache License)
00003  *
00004  * Copyright (c) 2014, Southwest Research Institute
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  * http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 
00019 
00020 #include <industrial_extrinsic_cal/ceres_costs_utils.hpp>
00021 
00022 #include <gtest/gtest.h>
00023 #include <yaml-cpp/yaml.h>
00024 #include <fstream>
00025 #include <iostream>
00026 
00027 #include <Eigen/Geometry>
00028 #include <Eigen/Core>
00029 
00030 using namespace industrial_extrinsic_cal;
00031 
00032 Point3d transformPoint(Point3d &original_point, double &ax, double &ay, double &az, double &x, double&y, double &z);
00033 
00034 std::vector<Point3d> created_points;
00035 double aa[3]; // angle axis known/set
00036 double p[3]; // point rotated known/set
00037 std::vector<Point3d> transformed_points;
00038 
00039 struct PointReprjErrorNoDistortion
00040 {
00041   PointReprjErrorNoDistortion(double ob_x, double ob_y, double fx) :
00042       px_(ob_x), py_(ob_y), pz_(fx)
00043   {
00044   }
00045 
00046   template<typename T>
00047     bool operator()(const T* const c_p1, 
00048                     //const T* c_p2, /** intrinsic parameters */
00049                     const T* point, 
00050                     T* resid) const
00051     {
00053       int q = 0; 
00054       const T& x = c_p1[0]; 
00055       const T& y = c_p1[1]; 
00056       const T& z = c_p1[2]; 
00057       const T& tx = c_p1[3]; 
00058       const T& ty = c_p1[4]; 
00059       const T& tz = c_p1[5]; 
00061       //std::cout<<"x, y, z: "<<c_p1[3]<<", "<<c_p1[4]<<", "<<c_p1[5]<<std::endl;
00062 
00063       //q = 0; /** intrinsic block of parameters */
00064       //const T& fx = c_p2[q++]; /**  focal length x */
00065       //const T& fy = c_p2[q++]; /**  focal length x */
00066       //const T& cx = c_p2[q++]; /**  center point x */
00067       //const T& cy = c_p2[q++]; /**  center point y */
00068 
00070       T aa[3]; 
00071       T p[3]; 
00072       aa[0] = x;
00073       aa[1] = y;
00074       aa[2] = z;
00075       ceres::AngleAxisRotatePoint(aa, point, p);
00076 
00078       T xp1 = p[0] + tx; 
00079       T yp1 = p[1] + ty;
00080       T zp1 = p[2] + tz;
00081 
00085       T xp=xp1;
00086       T yp=yp1;
00087       T zp=zp1;
00088 
00092       resid[0] = T(xp)-T(px_);
00093       resid[1] = T(yp)-T(py_);
00094       resid[2] = T(zp)-T(pz_);
00095 
00096       return true;
00097     } 
00101   static ceres::CostFunction* Create(const double p_x, const double p_y, const double p_z)
00102   {
00103     return (new ceres::AutoDiffCostFunction<PointReprjErrorNoDistortion, 3, 6, 3>(new PointReprjErrorNoDistortion(p_x, p_y, p_z)));
00104   }
00105   double px_; 
00106   double py_; 
00107   double pz_; 
00108 };
00109 
00110 TEST(IndustrialExtrinsicCalCeresSuite, create_points)
00111 {
00112   Point3d x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20;
00113   x1.pb[0]=1.0;x1.pb[1]=1.0;x1.pb[2]=1;
00114   created_points.push_back(x1);
00115   x2.pb[0]=0;x2.pb[1]=0;x2.pb[2]=0.01;
00116   created_points.push_back(x2);
00117   x3.pb[0]=0.65;x3.pb[1]=0.94;x3.pb[2]=0.01;
00118   created_points.push_back(x3);
00119   x4.pb[0]=0.2;x4.pb[1]=0.3;x4.pb[2]=0.01;
00120   created_points.push_back(x4);
00121   x5.pb[0]=0.372;x5.pb[1]=0.4;x5.pb[2]=0.4;
00122   created_points.push_back(x5);
00123   x6.pb[0]=0.3762;x6.pb[1]=0.8;x6.pb[2]=0.3;
00124   created_points.push_back(x6);
00125   x7.pb[0]=0.4;x7.pb[1]=0.389;x7.pb[2]=0.4;
00126   created_points.push_back(x7);
00127   x8.pb[0]=0.431;x8.pb[1]=0.7;x8.pb[2]=0.7;
00128   created_points.push_back(x8);
00129   x9.pb[0]=0.535;x9.pb[1]=0.9;x9.pb[2]=0.01;
00130   created_points.push_back(x9);
00131   x10.pb[0]=0.596;x10.pb[1]=1;x10.pb[2]=1.0;
00132   created_points.push_back(x10);
00133   x11.pb[0]=0.24;x11.pb[1]=1.0;x11.pb[2]=0.01;
00134   created_points.push_back(x11);
00135   x12.pb[0]=0.673;x12.pb[1]=1.7;x12.pb[2]=0.8;
00136   created_points.push_back(x12);
00137   x13.pb[0]=0.552;x13.pb[1]=1.15;x13.pb[2]=0.01;
00138   created_points.push_back(x13);
00139   x14.pb[0]=0.56;x14.pb[1]=0.81;x14.pb[2]=0.01;
00140   created_points.push_back(x14);
00141   x15.pb[0]=.70;x15.pb[1]=1.10;x15.pb[2]=0.01;
00142   created_points.push_back(x15);
00143   x16.pb[0]=0.3762;x16.pb[1]=0.02435;x16.pb[2]=0.3;
00144   created_points.push_back(x16);
00145   x17.pb[0]=0.0234;x17.pb[1]=0.389;x17.pb[2]=0.132;
00146   created_points.push_back(x17);
00147   x18.pb[0]=0.431;x18.pb[1]=0.245;x18.pb[2]=0.0235;
00148   created_points.push_back(x18);
00149   x19.pb[0]=0.535;x19.pb[1]=0.673;x19.pb[2]=0.01;
00150   created_points.push_back(x19);
00151   x20.pb[0]=0.76;x20.pb[1]=0.453;x20.pb[2]=1.0;
00152   created_points.push_back(x20);
00153   std::cout<<"Original Point 1: "<<x1.pb[0]<<" "<<x1.pb[1]<<" "<<x1.pb[2]<<std::endl;
00154 
00155   //create known transform
00156   aa[0] = 2.7;
00157   aa[1] = 0.3;
00158   aa[2] = 0.1;
00159   p[0]=0.2;
00160   p[1]=0.4;
00161   p[2]=0.5;
00162   Point3d t_point;
00163   for (int i=0; i<created_points.size();i++)
00164   {
00165     t_point=transformPoint(created_points.at(i), aa[0], aa[1], aa[2], p[0], p[1], p[2]);
00166     transformed_points.push_back(t_point);
00167   }
00168 
00169 }
00170 
00171 TEST(IndustrialExtrinsicCalCeresSuite, points_costfunction)
00172 {
00173 double extrinsics[6];
00174 ceres::Problem problem;
00175   for (int j = 0; j < transformed_points.size(); ++j)
00176   {
00177     ceres::CostFunction* cost_function = PointReprjErrorNoDistortion::Create(transformed_points.at(j).pb[0], transformed_points.at(j).pb[1], transformed_points.at(j).pb[2]);
00178 
00179     problem.AddResidualBlock(cost_function, NULL, extrinsics, created_points[j].pb);
00180     //problem.SetParameterBlockConstant(C.PB_intrinsics);
00181     problem.SetParameterBlockConstant(created_points[j].pb);
00182   }
00183   ceres::Solver::Options options;
00184   options.linear_solver_type = ceres::DENSE_SCHUR;
00185   options.minimizer_progress_to_stdout = false;
00186   options.max_num_iterations = 1000;
00187 
00188   ceres::Solver::Summary summary;
00189   ceres::Solve(options, &problem, &summary);
00190   //std::cout << summary.FullReport() << "\n";
00191   std::cout << summary.BriefReport() << "\n";
00192 
00193   EXPECT_FLOAT_EQ(-2.7,extrinsics[0]);
00194   EXPECT_FLOAT_EQ(-0.3,extrinsics[1]);
00195   EXPECT_FLOAT_EQ(-0.1,extrinsics[2]);
00196   EXPECT_FLOAT_EQ(0.2,extrinsics[3]);
00197   EXPECT_FLOAT_EQ(0.4,extrinsics[4]);
00198   EXPECT_FLOAT_EQ(0.5,extrinsics[5]);
00199   std::cout<<"Original aa rot and translation: "<<aa[0]<<" "<<aa[1]<<" "<<aa[2]
00200                                      <<" "<<p[0]<<" "<<p[1]<<" "<<p[2]<<std::endl;
00201 
00202   std::cout<<"Optimized Extrinsics rot/transl: "<<extrinsics[0]<<" "<<extrinsics[1]<<" "<<extrinsics[2]<<" "
00203       <<extrinsics[3]<<" "<<extrinsics[4]<<" "<<extrinsics[5]<<std::endl;
00204 }
00205 
00206 TEST(DISABLED_IndustrialExtrinsicCalCeresSuite, camera_costfunction)
00207 //void test()//
00208 {
00209   CameraParameters c_parameters;
00210   c_parameters.angle_axis[0]=0.0;//aa[0];//0.3;//
00211   c_parameters.angle_axis[1]=0.0;//aa[1];//0.7;//
00212   c_parameters.angle_axis[2]=0.0;//aa[2];//2.9;//
00213   c_parameters.position[0]=0.0;//p[0];//0.9;//
00214   c_parameters.position[1]=0.0;//p[1];//0.3;//
00215   c_parameters.position[2]=0.0;//p[2];//1.8;//
00216   c_parameters.focal_length_x=525;
00217   c_parameters.focal_length_y=525;
00218   c_parameters.center_x=320;
00219   c_parameters.center_y=240;
00220   c_parameters.distortion_k1=0.01;
00221   c_parameters.distortion_k2=0.02;
00222   c_parameters.distortion_k3=0.03;
00223   c_parameters.distortion_p1=0.01;
00224   c_parameters.distortion_p2=0.01;
00225 
00226   std::vector<Observation> projected_observations;
00227   Observation proj_point;
00228   for (int m=0; m<transformed_points.size(); m++)
00229   {
00230     proj_point=industrial_extrinsic_cal::projectPointWithDistortion(c_parameters, transformed_points.at(m));
00231     projected_observations.push_back(proj_point);
00232   }
00233 
00234   double extrinsics[6];
00235   extrinsics[0]=c_parameters.pb_extrinsics[0];//0.2;//
00236   extrinsics[1]=c_parameters.pb_extrinsics[1];//0.1;//
00237   extrinsics[2]=c_parameters.pb_extrinsics[2];//0.9;//
00238   extrinsics[3]=c_parameters.pb_extrinsics[3];//1.3;//
00239   extrinsics[4]=c_parameters.pb_extrinsics[4];//0.1;//
00240   extrinsics[5]=c_parameters.pb_extrinsics[5];//2.0;//
00241   ceres::Problem problem;
00242   double original_points[3];
00243     for (int j = 0; j < projected_observations.size(); ++j)
00244     {
00245       ceres::CostFunction* cost_function = CameraReprjErrorWithDistortion::Create(projected_observations.at(j).image_loc_x,
00246              projected_observations.at(j).image_loc_y);
00247 
00248 
00249       problem.AddResidualBlock(cost_function, NULL, extrinsics, c_parameters.pb_intrinsics, created_points[j].pb);
00250       problem.SetParameterBlockConstant(c_parameters.pb_intrinsics);
00251       problem.SetParameterBlockConstant(created_points[j].pb);
00252     }
00253     ceres::Solver::Options options;
00254     options.linear_solver_type = ceres::DENSE_SCHUR;
00255     options.minimizer_progress_to_stdout = true;
00256     options.max_num_iterations = 1000;
00257 
00258     ceres::Solver::Summary summary;
00259     ceres::Solve(options, &problem, &summary);
00260     //std::cout << summary.FullReport() << "\n";
00261     std::cout << summary.BriefReport() << "\n";
00262 
00263     std::cout<<"Expected aa rot and translation: "<<aa[0]<<" "<<aa[1]<<" "<<aa[2]
00264                                        <<" "<<p[0]<<" "<<p[1]<<" "<<p[2]<<std::endl;
00265 
00266     std::cout<<"Optimized Extrinsics rot/transl: "<<extrinsics[0]<<" "<<extrinsics[1]<<" "
00267         <<extrinsics[2]<<" "<<extrinsics[3]<<" "<<extrinsics[4]<<" "
00268         <<extrinsics[5]<<std::endl;
00269 }
00270 
00271 //void test()
00272 TEST(DISABLED_IndustrialExtrinsicCalCeresSuite, camera_no_dist_costfunction)
00273 {
00274   CameraParameters c_parameters;
00275   c_parameters.angle_axis[0]=0.0;//aa[0];//0.3;//
00276   c_parameters.angle_axis[1]=0.0;//aa[1];//0.7;//
00277   c_parameters.angle_axis[2]=0.0;//aa[2];//2.9;//
00278   c_parameters.position[0]=0.0;//p[0];//0.9;//
00279   c_parameters.position[1]=0.0;//p[1];//0.3;//
00280   c_parameters.position[2]=0.0;//p[2];//1.8;//
00281   c_parameters.focal_length_x=525;
00282   c_parameters.focal_length_y=525;
00283   c_parameters.center_x=320;
00284   c_parameters.center_y=240;
00285   c_parameters.distortion_k1=0.01;
00286   c_parameters.distortion_k2=0.02;
00287   c_parameters.distortion_k3=0.03;
00288   c_parameters.distortion_p1=0.01;
00289   c_parameters.distortion_p2=0.01;
00290 
00291   std::vector<Observation> projected_observations;
00292   Observation proj_point;
00293   for (int m=0; m<transformed_points.size(); m++)
00294   {
00295 
00296     proj_point=industrial_extrinsic_cal::projectPointNoDistortion(c_parameters, transformed_points.at(m));
00297     projected_observations.push_back(proj_point);
00298   }
00299 
00300   double extrinsics[6];
00301   extrinsics[0]=c_parameters.pb_extrinsics[0];//0.2;//
00302   extrinsics[1]=c_parameters.pb_extrinsics[1];//0.1;//
00303   extrinsics[2]=c_parameters.pb_extrinsics[2];//0.9;//
00304   extrinsics[3]=c_parameters.pb_extrinsics[3];//1.3;//
00305   extrinsics[4]=c_parameters.pb_extrinsics[4];//0.1;//
00306   extrinsics[5]=c_parameters.pb_extrinsics[5];//2.0;//
00307   ceres::Problem problem;
00308     for (int j = 0; j < projected_observations.size(); ++j)
00309     {
00310       ceres::CostFunction* cost_function = CameraReprjErrorNoDistortion::Create(projected_observations.at(j).image_loc_x,
00311              projected_observations.at(j).image_loc_y, c_parameters.focal_length_x, c_parameters.focal_length_y,
00312              c_parameters.center_x, c_parameters.center_y);
00313 
00314       problem.AddResidualBlock(cost_function, NULL, extrinsics, c_parameters.pb_intrinsics, created_points.at(j).pb);
00315       problem.SetParameterBlockConstant(c_parameters.pb_intrinsics);
00316       problem.SetParameterBlockConstant(created_points.at(j).pb);
00317     }
00318     ceres::Solver::Options options;
00319     options.linear_solver_type = ceres::DENSE_SCHUR;
00320     options.minimizer_progress_to_stdout = true;
00321     options.max_num_iterations = 1000;
00322 
00323     ceres::Solver::Summary summary;
00324     ceres::Solve(options, &problem, &summary);
00325     //std::cout << summary.FullReport() << "\n";
00326     std::cout << summary.BriefReport() << "\n";
00327 
00328     std::cout<<"Expected aa rot and translation: "<<aa[0]<<" "<<aa[1]<<" "<<aa[2]
00329                                        <<" "<<p[0]<<" "<<p[1]<<" "<<p[2]<<std::endl;
00330 
00331     std::cout<<"Optimized Extrinsics rot/transl: "<<extrinsics[0]<<" "<<extrinsics[1]<<" "
00332         <<extrinsics[2]<<" "<<extrinsics[3]<<" "<<extrinsics[4]<<" "
00333         <<extrinsics[5]<<std::endl;
00334 }
00335 
00336 Point3d transformPoint(Point3d &original_point, double &ax, double &ay, double &az, double &x, double&y, double &z)
00337 {
00338   //std::cout<<"ange axis inputs ax, ay, az: "<<ax<<", "<<ay<<", "<<az<<std::endl;
00339   Eigen::Matrix3f m_ceres;
00340   Eigen::Matrix3f m_eigen;
00341   m_eigen = Eigen::AngleAxisf(ax, Eigen::Vector3f::UnitX())
00342   * Eigen::AngleAxisf(ay, Eigen::Vector3f::UnitY())
00343   * Eigen::AngleAxisf(az, Eigen::Vector3f::UnitZ());
00344   //std::cout<<"m_eigen : "<<std::endl<< m_eigen <<std::endl;
00345   double aa[3]; // angle axis
00346   double p[3]; // point rotated
00347   aa[0] = ax;
00348   aa[1] = ay;
00349   aa[2] = az;
00350   Eigen::Vector3f orig_point(original_point.pb[0], original_point.pb[1], original_point.pb[2]);
00351   //std::cout<<"within transformPoint, original point Vector3f x, y, z: "<<orig_point.x()<<", "<<orig_point.y()<<", "<<orig_point.z()<<std::endl;
00352 
00353   double R[9];
00354   ceres::AngleAxisToRotationMatrix(aa, R);
00355   m_ceres << R[0], R[1],R[2],
00356       R[3], R[4], R[5],
00357       R[6], R[7], R[8];
00358   //std::cout<<"m_ceres : "<<std::endl<< m_ceres <<std::endl;
00359   Eigen::Vector3f rot_point=m_ceres*orig_point;
00360   //std::cout<<"within transformPoint, rotated point Vector3f x, y, z: "<<rot_point.x()<<", "<<rot_point.y()<<", "<<rot_point.z()<<std::endl;
00361   double xp1 = rot_point.x() + x; // point rotated and translated
00362   double yp1 = rot_point.y() + y;
00363   double zp1 = rot_point.z() + z;
00364   //std::cout<<"within transformPoint, original point double x, y, z: "<<xp1<<", "<<yp1<<", "<<zp1<<std::endl;
00365   Point3d t_point;
00366   t_point.pb[0]=xp1;t_point.pb[1]=yp1;t_point.pb[2]=zp1;
00367   //std::cout<<"within transformPoint, t_point x, y, z: "<<t_point.pb[0]<<", "<<t_point.pb[1]<<", "<<t_point.pb[2]<<std::endl;
00368   return t_point;
00369 }
00370 
00371 // Run all the tests that were declared with TEST()
00372 int main(int argc, char **argv)
00373 {
00374   //ros::init(argc, argv, "test");
00375   testing::InitGoogleTest(&argc, argv);
00376   return RUN_ALL_TESTS();
00377 
00378 }


industrial_extrinsic_cal
Author(s): Chris Lewis
autogenerated on Wed Aug 26 2015 12:00:27