00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <industrial_extrinsic_cal/basic_types.h>
00020 #include <industrial_extrinsic_cal/observation_scene.h>
00021
00022 namespace industrial_extrinsic_cal
00023 {
00024 Observation projectPoint(CameraParameters C, Point3d P)
00025 {
00026 double p[3];
00027 double pt[3];
00028 pt[0] = P.x;
00029 pt[1] = P.y;
00030 pt[2] = P.z;
00031
00032
00033
00034 double aa[3];
00035 aa[0]=C.pb_extrinsics[0];
00036 aa[0]=C.pb_extrinsics[1];
00037 aa[0]=C.pb_extrinsics[2];
00038 ceres::AngleAxisRotatePoint(aa, pt, p);
00039
00040 p[0] +=C.pb_extrinsics[3];
00041 p[1] +=C.pb_extrinsics[4];
00042 p[2] +=C.pb_extrinsics[5];
00043
00044 double xp = p[0] / p[2];
00045 double yp = p[1] / p[2];
00046
00047
00048 double r2 = xp * xp + yp * yp;
00049 double r4 = r2 * r2;
00050 double r6 = r2 * r4;
00051
00052 double xp2 = xp * xp;
00053 double yp2 = yp * yp;
00054
00055
00056 double xpp = xp + C.distortion_k1 * r2 * xp + C.distortion_k2 * r4 * xp +
00057 C.distortion_k3 * r6 * xp + C.distortion_p2 * (r2 + 2 * xp2) + 2 * C.distortion_p1 * xp * yp;
00058 double ypp = yp + C.distortion_k1 * r2 * yp + C.distortion_k2 * r4 * yp +
00059 C.distortion_k3 * r6 * yp + C.distortion_p1 * (r2 + 2 * yp2) + 2 * C.distortion_p2 * xp * yp;
00060
00061
00062 Observation O;
00063 O.point_id = 0;
00064 O.image_loc_x = C.focal_length_x * xpp + C.center_x;
00065 O.image_loc_y = C.focal_length_y * ypp + C.center_y;
00066 return (O);
00067 }
00068
00069 struct CameraReprjErrorWithDistortion
00070 {
00071 CameraReprjErrorWithDistortion(double ob_x, double ob_y) :
00072 ox_(ob_x), oy_(ob_y)
00073 {
00074 }
00075
00076 template<typename T>
00077 bool operator()(const T* const c_p1,
00078 const T* c_p2,
00079 const T* point,
00080 T* resid) const
00081 {
00083 int q = 0;
00084 const T& x = c_p1[q++];
00085 const T& y = c_p1[q++];
00086 const T& z = c_p1[q++];
00087 const T& tx = c_p1[q++];
00088 const T& ty = c_p1[q++];
00089 const T& tz = c_p1[q++];
00091 q = 0;
00092 const T& fx = c_p2[q++];
00093 const T& fy = c_p2[q++];
00094 const T& cx = c_p2[q++];
00095 const T& cy = c_p2[q++];
00096 const T& k1 = c_p2[q++];
00097 const T& k2 = c_p2[q++];
00098 const T& k3 = c_p2[q++];
00099 const T& p1 = c_p2[q++];
00100 const T& p2 = c_p2[q++];
00103 T aa[3];
00104 T p[3];
00105 aa[0] = x;
00106 aa[1] = y;
00107 aa[2] = z;
00108 ceres::AngleAxisRotatePoint(aa, point, p);
00109
00111 T xp1 = p[0] + tx;
00112 T yp1 = p[1] + ty;
00113 T zp1 = p[2] + tz;
00114
00116 T xp = xp1 / zp1;
00117 T yp = yp1 / zp1;
00118
00120 T r2 = xp * xp + yp * yp;
00121 T r4 = r2 * r2;
00122 T r6 = r2 * r4;
00123
00124 T xp2 = xp * xp;
00125 T yp2 = yp * yp;
00126
00127 T xpp = xp + k1 * r2 * xp + k2 * r4 * xp + k3 * r6 * xp + p2 * (r2 + T(2.0) * xp2) + T(2.0) * p1 * xp * yp;
00128 T ypp = yp + k1 * r2 * yp + k2 * r4 * yp + k3 * r6 * yp + p1 * (r2 + T(2.0) * yp2) + T(2.0) * p2 * xp * yp;
00130 resid[0] = fx * xpp + cx - T(ox_);
00131 resid[1] = fy * ypp + cy - T(oy_);
00132
00133 return true;
00134 }
00138 static ceres::CostFunction* Create(const double o_x, const double o_y)
00139 {
00140 return (new ceres::AutoDiffCostFunction<CameraReprjErrorWithDistortion, 2, 6, 9, 3>(new CameraReprjErrorWithDistortion(o_x, o_y)));
00141 }
00142 double ox_;
00143 double oy_;
00144 };
00145
00146 struct CameraReprjErrorNoDistortion
00147 {
00148 CameraReprjErrorNoDistortion(double ob_x, double ob_y) :
00149 ox_(ob_x), oy_(ob_y)
00150 {
00151 }
00152
00153 template<typename T>
00154 bool operator()(const T* const c_p1,
00155 const T* c_p2,
00156 const T* point,
00157 T* resid) const
00158 {
00160 int q = 0;
00161 const T& x = c_p1[q++];
00162 const T& y = c_p1[q++];
00163 const T& z = c_p1[q++];
00164 const T& tx = c_p1[q++];
00165 const T& ty = c_p1[q++];
00166 const T& tz = c_p1[q++];
00168 q = 0;
00169 const T& fx = c_p2[q++];
00170 const T& fy = c_p2[q++];
00171 const T& cx = c_p2[q++];
00172 const T& cy = c_p2[q++];
00175 T aa[3];
00176 T p[3];
00177 aa[0] = x;
00178 aa[1] = y;
00179 aa[2] = z;
00180 ceres::AngleAxisRotatePoint(aa, point, p);
00181
00183 T xp1 = p[0] + tx;
00184 T yp1 = p[1] + ty;
00185 T zp1 = p[2] + tz;
00186
00188 T xp = xp1 / zp1;
00189 T yp = yp1 / zp1;
00190
00192 resid[0] = T(fx_) * xp + T(cx_) - T(ox_);
00193 resid[1] = T(fy_) * yp + T(cy_) - T(oy_);
00194
00195 return true;
00196 }
00200 static ceres::CostFunction* Create(const double o_x, const double o_y)
00201 {
00202 return (new ceres::AutoDiffCostFunction<CameraReprjErrorNoDistortion, 2, 6, 4, 3>(new CameraReprjErrorNoDistortion(o_x, o_y)));
00203 }
00204 double ox_;
00205 double oy_;
00206 double fx_;
00207 double fy_;
00208 double cx_;
00209 double cy_;
00210 };
00211
00212 struct TargetCameraReprjErrorNoDistortion
00213 {
00214 TargetCameraReprjErrorNoDistortion(double ob_x, double ob_y) :
00215 ox_(ob_x), oy_(ob_y)
00216 {
00217 }
00218
00219 template<typename T>
00220 bool operator()(const T* const c_p1,
00221 const T* const c_p2,
00222 const T* const c_p3,
00223 const T* const point,
00224 T* resid) const
00225 {
00226
00228 int q = 0;
00229 const T& ax = c_p1[q++];
00230 const T& ay = c_p1[q++];
00231 const T& az = c_p1[q++];
00232 const T& tx = c_p1[q++];
00233 const T& ty = c_p1[q++];
00234 const T& tz = c_p1[q++];
00236 q = 0;
00237 const T& fx = c_p2[q++];
00238 const T& fy = c_p2[q++];
00239 const T& cx = c_p2[q++];
00240 const T& cy = c_p2[q++];
00242 q = 0;
00243 const T& target_x = c_p3[q++];
00244 const T& target_y = c_p3[q++];
00245 const T& target_z = c_p3[q++];
00246 const T& target_ax = c_p3[q++];
00247 const T& target_ay = c_p3[q++];
00248 const T& target_az = c_p3[q++];
00251 T target_aa[3];
00252 T world_point_loc[3];
00253 target_aa[0] = target_ax;
00254 target_aa[1] = target_ay;
00255 target_aa[2] = target_az;
00256 ceres::AngleAxisRotatePoint(target_aa, point, world_point_loc);
00257
00259 world_point_loc[0] = world_point_loc[0] + target_x;
00260 world_point_loc[1] = world_point_loc[1] + target_y;
00261 world_point_loc[2] = world_point_loc[2] + target_z;
00262
00264
00265 T aa[3];
00266 T camera_point_loc[3];
00267 aa[0] = ax;
00268 aa[1] = ay;
00269 aa[2] = az;
00270 ceres::AngleAxisRotatePoint(aa, point, camera_point_loc);
00271
00273 T xp1 = camera_point_loc[0] + tx;
00274 T yp1 = camera_point_loc[1] + ty;
00275 T zp1 = camera_point_loc[2] + tz;
00276
00278 T xp = xp1 / zp1;
00279 T yp = yp1 / zp1;
00280
00282 resid[0] = fx * xp + cx - T(ox_);
00283 resid[1] = fy * yp + cy - T(oy_);
00284
00285 return true;
00286 }
00290 static ceres::CostFunction* Create(const double o_x, const double o_y)
00291 {
00292 return (new ceres::AutoDiffCostFunction<TargetCameraReprjErrorNoDistortion, 2, 6, 4, 6, 3>(
00293 new CameraReprjError(o_x, o_y)));
00294 }
00295 double ox_;
00296 double oy_;
00297 };
00298
00299 struct TargetCameraReprjErrorProjModelAsClassVars
00300 {
00301 TargetCameraReprjErrorProjModelAsClassVars(double ob_x, double ob_y, double fx, double fy, double cx, double cy) :
00302 ox_(ob_x), oy_(ob_y), fx_(fx), fy_(fy), cx_(cx), cy_(cy)
00303 {
00304 }
00305
00306 template<typename T>
00307 bool operator()(const T* const c_p1,
00308 const T* const c_p2,
00309 const T* const point,
00310 T* resid) const
00311 {
00312
00314 int q = 0;
00315 const T& ax = c_p1[q++];
00316 const T& ay = c_p1[q++];
00317 const T& az = c_p1[q++];
00318 const T& tx = c_p1[q++];
00319 const T& ty = c_p1[q++];
00320 const T& tz = c_p1[q++];
00322 q = 0;
00323 const T& target_x = c_p2[q++];
00324 const T& target_y = c_p2[q++];
00325 const T& target_z = c_p2[q++];
00326 const T& target_ax = c_p2[q++];
00327 const T& target_ay = c_p2[q++];
00328 const T& target_az = c_p2[q++];
00331
00332 T point[3];
00333 point[0] = pnt_x_;
00334 point[1] = pnt_y_;
00335 point[2] = pnt_z_;
00336
00338 T target_aa[3];
00339 T world_point_loc[3];
00340 target_aa[0] = target_ax;
00341 target_aa[1] = target_ay;
00342 target_aa[2] = target_az;
00343 ceres::AngleAxisRotatePoint(target_aa, point, world_point_loc);
00344
00346 world_point_loc[0] = world_point_loc[0] + target_x;
00347 world_point_loc[1] = world_point_loc[1] + target_y;
00348 world_point_loc[2] = world_point_loc[2] + target_z;
00349
00351
00352 T aa[3];
00353 T camera_point_loc[3];
00354 aa[0] = ax;
00355 aa[1] = ay;
00356 aa[2] = az;
00357 ceres::AngleAxisRotatePoint(aa, point, camera_point_loc);
00358
00360 T xp1 = camera_point_loc[0] + tx;
00361 T yp1 = camera_point_loc[1] + ty;
00362 T zp1 = camera_point_loc[2] + tz;
00363
00365 T xp = xp1 / zp1;
00366 T yp = yp1 / zp1;
00367
00369 resid[0] = T(fx_) * xp + T(cx_) - T(ox_);
00370 resid[1] = T(fy_) * yp + T(cy_) - T(oy_);
00371
00372 return true;
00373 }
00377 static ceres::CostFunction* Create(const double o_x, const double o_y, double fx, double fy, double cx, double cy)
00378 {
00379 return (new ceres::AutoDiffCostFunction<TargetCameraReprjErrorProjModelAsClassVars, 2, 6, 6, 3>(
00380 new CameraReprjError(o_x, o_y, fx, fy, cx, cy)));
00381 }
00382 double ox_;
00383 double oy_;
00384 double fx_;
00385 double fy_;
00386 double cx_;
00387 double cy_;
00388 double pnt_x_;
00389 double pnt_y_;
00390 double pnt_z_;
00391 };
00392
00393 void printQTasH(double qx, double qy, double qz, double qw, double tx, double ty, double tz)
00394 {
00395 double Rs11 = qw * qw + qx * qx - qy * qy - qz * qz;
00396 double Rs21 = 2.0 * qx * qy + 2.0 * qw * qz;
00397 double Rs31 = 2.0 * qx * qz - 2.0 * qw * qy;
00398
00399 double Rs12 = 2.0 * qx * qy - 2.0 * qw * qz;
00400 double Rs22 = qw * qw - qx * qx + qy * qy - qz * qz;
00401 double Rs32 = 2.0 * qy * qz + 2.0 * qw * qx;
00402
00403 double Rs13 = 2.0 * qx * qz + 2.0 * qw * qy;
00404 double Rs23 = 2.0 * qy * qz - 2.0 * qw * qx;
00405 double Rs33 = qw * qw - qx * qx - qy * qy + qz * qz;
00406
00407 printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", Rs11, Rs12, Rs13, tx);
00408 printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", Rs21, Rs22, Rs23, ty);
00409 printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", Rs31, Rs32, Rs33, tz);
00410 printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", 0.0, 0.0, 0.0, 1.0);
00411 }
00412
00413 void printAATasH(double x, double y, double z, double tx, double ty, double tz)
00414 {
00415 double R[9];
00416 double aa[3];
00417 aa[0] = x;
00418 aa[1] = y;
00419 aa[2] = z;
00420 ceres::AngleAxisToRotationMatrix(aa, R);
00421 printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", R[0], R[3], R[6], tx);
00422 printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", R[1], R[4], R[7], ty);
00423 printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", R[2], R[5], R[8], tz);
00424 printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", 0.0, 0.0, 0.0, 1.0);
00425 }
00426
00427 void printAATasHI(double x, double y, double z, double tx, double ty, double tz)
00428 {
00429 double R[9];
00430 double aa[3];
00431 aa[0] = x;
00432 aa[1] = y;
00433 aa[2] = z;
00434 ceres::AngleAxisToRotationMatrix(aa, R);
00435 double ix = -(tx * R[0] + ty * R[1] + tz * R[2]);
00436 double iy = -(tx * R[3] + ty * R[4] + tz * R[5]);
00437 double iz = -(tx * R[6] + ty * R[7] + tz * R[8]);
00438 printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", R[0], R[1], R[2], ix);
00439 printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", R[3], R[4], R[5], iy);
00440 printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", R[6], R[7], R[8], iz);
00441 printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", 0.0, 0.0, 0.0, 1.0);
00442 }
00443
00444 void printAAasEuler(double x, double y, double z)
00445 {
00446 double R[9];
00447 double aa[3];
00448 aa[0] = x;
00449 aa[1] = y;
00450 aa[2] = z;
00451 ceres::AngleAxisToRotationMatrix(aa, R);
00452 double rx = atan2(R[7], R[8]);
00453 double ry = atan2(-R[6], sqrt(R[7] * R[7] + R[8] * R[8]));
00454 double rz = atan2(R[3], R[0]);
00455 printf("rpy = %8.4f %8.4f %8.4f\n", rx, ry, rz);
00456 }
00457
00458 void printCameraParameters(CameraParameters C, std::string words)
00459 {
00460 printf("%s\n", words.c_str());
00461 printf("Camera to World Transform:\n");
00462 printAATasHI(C.aa[0], C.aa[1], C.aa[2], C.pos[0], C.pos[1], C.pos[2]);
00463
00464 printf("World to Camera\n");
00465 printAATasH(C.aa[0], C.aa[1], C.aa[2], C.pos[0], C.pos[1], C.pos[2]);
00466 printAAasEuler(C.aa[0], C.aa[1], C.aa[2]);
00467 printf("fx = %8.3lf fy = %8.3lf\n", C.fx, C.fy);
00468 printf("k1 = %8.3lf k2 = %8.3lf k3 = %8.3lf\n", C.k1, C.k2, C.k3);
00469 printf("p1 = %8.3lf p2 = %8.3lf\n", C.p1, C.p2);
00470 printf("cx = %8.3lf cy = %8.3lf\n", C.cx, C.cy);
00471 }
00472 }