00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
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
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 }
00275 #endif