ceres_costs_utils.hpp
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 #ifndef CERES_COSTS_UTILS_HPP_
00020 #define CERES_COSTS_UTILS_HPP_
00021 
00022 #include "ceres/ceres.h"
00023 #include "ceres/rotation.h"
00024 #include <industrial_extrinsic_cal/basic_types.h>
00025 
00026 namespace industrial_extrinsic_cal
00027 {
00028   struct TargetCameraReprjErrorNoDistortion
00029   {
00030     TargetCameraReprjErrorNoDistortion(double ob_x, double ob_y,
00031                                        double fx,   double fy,
00032                                        double cx,   double cy,
00033                                        double pnt_x,   double pnt_y, double pnt_z)
00034       : ox_(ob_x),oy_(ob_y),
00035         fx_(fx),fy_(fy),
00036         cx_(cx),cy_(cy),
00037         pnt_x_(pnt_x), pnt_y_(pnt_y), pnt_z_(pnt_z){}
00038   
00039     template <typename T>
00040     bool operator()(const T* const c_p1,   
00041                     const T* const t_p1,   
00042                     T* resid) const {
00043 
00045       int q=0; 
00046       const T& ax    = c_p1[q++]; 
00047       const T& ay    = c_p1[q++]; 
00048       const T& az    = c_p1[q++]; 
00049       const T& tx    = c_p1[q++]; 
00050       const T& ty    = c_p1[q++]; 
00051       const T& tz    = c_p1[q++]; 
00053       q=0; 
00054       const T& target_x   = t_p1[q++]; 
00055       const T& target_y   = t_p1[q++]; 
00056       const T& target_z   = t_p1[q++]; 
00057       const T& target_ax  = t_p1[q++]; 
00058       const T& target_ay  = t_p1[q++]; 
00059       const T& target_az  = t_p1[q++]; 
00062       // create a vector from the location of the point in the target's frame
00063       T point[3];
00064       point[0] = T(pnt_x_);
00065       point[1] = T(pnt_y_);
00066       point[2] = T(pnt_z_);
00067 
00069       T target_aa[3];
00070       T world_point_loc[3]; 
00071       target_aa[0] = target_ax; 
00072       target_aa[1] = target_ay; 
00073       target_aa[2] = target_az; 
00074       //takes rotation as a Rodriques’ axis-angle vector, and point, returns world_point_loc as rotated point
00075       ceres::AngleAxisRotatePoint(target_aa,point,world_point_loc);
00076 
00078       world_point_loc[0] = world_point_loc[0] + target_x;
00079       world_point_loc[1] = world_point_loc[1] + target_y;
00080       world_point_loc[2] = world_point_loc[2] + target_z;
00081 
00083       /*  Note that camera transform is from world into camera frame, not vise versa */
00084       T aa[3];
00085       T camera_point_loc[3]; 
00086       aa[0] = ax; 
00087       aa[1] = ay; 
00088       aa[2] = az; 
00089       ceres::AngleAxisRotatePoint(aa,point,camera_point_loc);
00090 
00092       T xp1 = camera_point_loc[0] + tx; 
00093       T yp1 = camera_point_loc[1] + ty;
00094       T zp1 = camera_point_loc[2] + tz;
00095 
00097       T xp = xp1/zp1;                   
00098       T yp = yp1/zp1;
00099 
00101       resid[0] = T(fx_)*xp + T(cx_) - T(ox_); 
00102       resid[1] = T(fy_)*yp + T(cy_) - T(oy_);
00103 
00104       return true;
00105     } 
00109     static ceres::CostFunction* Create(const double o_x, const double o_y,
00110                                        const double fx,  const double fy,
00111                                        const double cx,  const double cy,
00112                                        const double pnt_x, const double pnt_y,
00113                                        const double pnt_z)
00114   {
00115     return (new ceres::AutoDiffCostFunction<TargetCameraReprjErrorNoDistortion, 2, 6, 6>(
00116         new TargetCameraReprjErrorNoDistortion(o_x, o_y, fx, fy, cx, cy, pnt_x, pnt_y, pnt_z)));
00117     }
00118     double ox_; 
00119     double oy_; 
00120     double fx_; 
00121     double fy_; 
00122     double cx_; 
00123     double cy_; 
00124     double pnt_x_;
00125     double pnt_y_;
00126     double pnt_z_;
00127   };
00128 
00129   struct CameraReprjErrorNoDistortion
00130   {
00131     CameraReprjErrorNoDistortion(double ob_x, double ob_y, double fx, double fy, double cx, double cy) :
00132         ox_(ob_x), oy_(ob_y), fx_(fx), fy_(fy), cx_(cx), cy_(cy)
00133     {
00134     }
00135 
00136     template<typename T>
00137       bool operator()(const T* const c_p1, 
00138                       const T* c_p2, 
00139                       const T* point, 
00140                       T* resid) const
00141       {
00143         int q = 0; 
00144         const T& ax = c_p1[q++]; 
00145         const T& ay = c_p1[q++]; 
00146         const T& az = c_p1[q++]; 
00147         const T& tx = c_p1[q++]; 
00148         const T& ty = c_p1[q++]; 
00149         const T& tz = c_p1[q++]; 
00151         q = 0; 
00152         const T& fx = c_p2[q++]; 
00153         const T& fy = c_p2[q++]; 
00154         const T& cx = c_p2[q++]; 
00155         const T& cy = c_p2[q++]; 
00158         T aa[3];
00159         T p[3]; 
00160         T P[3]; 
00161         aa[0] = ax;
00162         aa[1] = ay;
00163         aa[2] = az;
00164         ceres::AngleAxisRotatePoint(aa, point, p);
00165 
00167         T xp1 = p[0] + tx; 
00168         T yp1 = p[1] + ty;
00169         T zp1 = p[2] + tz;
00170 
00172         T xp = xp1 / zp1;
00173         T yp = yp1 / zp1;
00174 
00176         resid[0] = T(fx_) * xp + T(cx_) - T(ox_);
00177         resid[1] = T(fy_) * yp + T(cy_) - T(oy_);
00178 
00179         return true;
00180       } 
00184     static ceres::CostFunction* Create(const double o_x, const double o_y, const double f_x, const double f_y, const double c_x, const double c_y)
00185     {
00186       return (new ceres::AutoDiffCostFunction<CameraReprjErrorNoDistortion, 2, 6, 9, 3>(new CameraReprjErrorNoDistortion(o_x, o_y, f_x, f_y, c_x, c_y)));
00187     }
00188     double ox_; 
00189     double oy_; 
00190     double fx_; 
00191     double fy_; 
00192     double cx_; 
00193     double cy_; 
00194   };
00195 
00196   struct CameraReprjErrorWithDistortion
00197   {
00198     CameraReprjErrorWithDistortion(double ob_x, double ob_y) :
00199         ox_(ob_x), oy_(ob_y)
00200     {
00201     }
00202 
00203     template<typename T>
00204       bool operator()(const T* const c_p1, 
00205                       const T* c_p2, 
00206                       const T* point, 
00207                       T* resid) const
00208       {
00210         int q = 0; 
00211         const T& ax = c_p1[q++]; 
00212         const T& ay = c_p1[q++]; 
00213         const T& az = c_p1[q++]; 
00214         const T& tx = c_p1[q++]; 
00215         const T& ty = c_p1[q++]; 
00216         const T& tz = c_p1[q++]; 
00218         q = 0; 
00219         const T& fx = c_p2[q++]; 
00220         const T& fy = c_p2[q++]; 
00221         const T& cx = c_p2[q++]; 
00222         const T& cy = c_p2[q++]; 
00223         const T& k1 = c_p2[q++]; 
00224         const T& k2 = c_p2[q++]; 
00225         const T& k3 = c_p2[q++]; 
00226         const T& p1 = c_p2[q++]; 
00227         const T& p2 = c_p2[q++]; 
00230         T aa[3];
00231         T p[3]; 
00232         aa[0] = ax;
00233         aa[1] = ay;
00234         aa[2] = az;
00235         ceres::AngleAxisRotatePoint(aa, point, p);
00236 
00238         T xp1 = p[0] + tx; 
00239         T yp1 = p[1] + ty;
00240         T zp1 = p[2] + tz;
00241 
00243         T xp = xp1 / zp1;
00244         T yp = yp1 / zp1;
00245 
00247         T r2 = xp * xp + yp * yp;
00248         T r4 = r2 * r2;
00249         T r6 = r2 * r4;
00250 
00251         T xp2 = xp * xp; 
00252         T yp2 = yp * yp;
00253         /*apply the distortion coefficients to refine pixel location */
00254         T xpp = xp + k1 * r2 * xp + k2 * r4 * xp + k3 * r6 * xp + p2 * (r2 + T(2.0) * xp2) + T(2.0) * p1 * xp * yp;
00255         T ypp = yp + k1 * r2 * yp + k2 * r4 * yp + k3 * r6 * yp + p1 * (r2 + T(2.0) * yp2) + T(2.0) * p2 * xp * yp;
00257         resid[0] = fx * xpp + cx - T(ox_);
00258         resid[1] = fy * ypp + cy - T(oy_);
00259 
00260         return true;
00261       } 
00265     static ceres::CostFunction* Create(const double o_x, const double o_y)
00266     {
00267       return (new ceres::AutoDiffCostFunction<CameraReprjErrorWithDistortion, 2, 6, 9, 3>(new CameraReprjErrorWithDistortion(o_x, o_y)));
00268     }
00269     double ox_; 
00270     double oy_; 
00271   };
00272 
00273 
00274 } // end of namespace
00275 #endif


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