Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009 #include "mvl_five_point_camera_pencil.h"
00010
00011 #include <vcl_cmath.h>
00012 #include <vnl/vnl_double_3.h>
00013 #include <vnl/algo/vnl_svd.h>
00014
00015 bool mvl_five_point_camera_pencil(double const xs[5],
00016 double const ys[5],
00017 vnl_double_3x4 *A,
00018 vnl_double_3x4 *B)
00019 {
00020
00021
00022
00023 vnl_double_3x4 design;
00024 for (int i=0; i<4; ++i) {
00025 double u = xs[i] - xs[4];
00026 double v = ys[i] - ys[4];
00027 double one_over_r = 1.0 / vcl_sqrt(u*u + v*v);
00028 if (! one_over_r)
00029 return false;
00030 design[0][i] = u * one_over_r;
00031 design[1][i] = v * one_over_r;
00032 design[2][i] = one_over_r;
00033 }
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #ifdef DEBUG
00048 vcl_cerr << "design = "; vnl_matlab_print(vcl_cerr,design);
00049 #endif
00050 vnl_svd<double> svd(design.extract(2, 4));
00051 #ifdef DEBUG
00052 vcl_cerr << "singvals = " << svd.W() << vcl_endl;
00053 #endif
00054
00055
00056 vnl_vector<double> a(svd.V().get_column(2));
00057 vnl_vector<double> b(svd.V().get_column(3));
00058 #ifdef DEBUG
00059 vcl_cerr << "a = "; vnl_matlab_print(vcl_cerr,a);
00060 vcl_cerr << "b = "; vnl_matlab_print(vcl_cerr,b);
00061 #endif
00062
00063
00064 *A = design;
00065 A->scale_column(0, a[0]);
00066 A->scale_column(1, a[1]);
00067 A->scale_column(2, a[2]);
00068 A->scale_column(3, a[3]);
00069 *B = design;
00070 B->scale_column(0, b[0]);
00071 B->scale_column(1, b[1]);
00072 B->scale_column(2, b[2]);
00073 B->scale_column(3, b[3]);
00074 #ifdef DEBUG
00075 vcl_cerr << "A = "; vnl_matlab_print(vcl_cerr,A);
00076 vcl_cerr << "B = "; vnl_matlab_print(vcl_cerr,B);
00077 #endif
00078
00079
00080 for (int i=0; i<4; ++i) {
00081 (*A)[0][i] += xs[4] * (*A)[2][i];
00082 (*A)[1][i] += ys[4] * (*A)[2][i];
00083
00084 (*B)[0][i] += xs[4] * (*B)[2][i];
00085 (*B)[1][i] += ys[4] * (*B)[2][i];
00086 }
00087
00088 return true;
00089 }
00090
00091 bool mvl_five_point_camera_pencil_parameters(vnl_double_3x4 const &A,
00092 vnl_double_3x4 const &B,
00093 vnl_double_4 const &X,
00094 double u, double v,
00095 double st[2],
00096 double res[2])
00097 {
00098
00099 vnl_double_3 AX = A * X;
00100 vnl_double_3 BX = B * X;
00101
00102
00103 AX[0] -= u * AX[2]; AX[1] -= v * AX[2];
00104 BX[0] -= u * BX[2]; BX[1] -= v * BX[2];
00105
00106
00107 vnl_double_3 l = vnl_cross_3d(AX, BX);
00108
00109 if (st) {
00110 double s = (l[1]*BX[0] - l[0]*BX[1]);
00111 double t = -(l[1]*AX[0] - l[0]*AX[1]);
00112 #if 1
00113 double n = vcl_sqrt(s*s + t*t);
00114 if (n == 0)
00115 return false;
00116 st[0] = s/n;
00117 st[1] = t/n;
00118 #else
00119 st[0] = s;
00120 st[1] = t;
00121 #endif
00122
00123 #ifdef DEBUG
00124 vcl_cerr << A << vcl_endl
00125 << B << vcl_endl
00126 << X << vcl_endl
00127 << u << ' ' << v << vcl_endl
00128 << st[0] << ' ' << st[1] << vcl_endl;
00129 #endif
00130 }
00131
00132 if (res) {
00133
00134 double nn = l[0]*l[0] + l[1]*l[1];
00135 if (nn == 0)
00136 return false;
00137
00138
00139 res[0] = l[0] * l[2] / nn;
00140 res[1] = l[1] * l[2] / nn;
00141 }
00142
00143 return true;
00144 }