2 #ifndef vpgl_camera_compute_cxx_ 3 #define vpgl_camera_compute_cxx_ 13 # include <vcl_msvc_warnings.h> 43 std::vector< vgl_homg_point_2d<double> > image_pts2;
44 std::vector< vgl_homg_point_3d<double> > world_pts2;
45 image_pts2.reserve(image_pts.size());
46 for (
auto image_pt : image_pts)
47 image_pts2.emplace_back( image_pt );
48 world_pts2.reserve(world_pts.size());
49 for (
const auto & world_pt : world_pts)
50 world_pts2.emplace_back( world_pt );
51 return compute( image_pts2, world_pts2, camera );
62 auto num_correspondences = static_cast<unsigned int>(image_pts.size());
63 if ( world_pts.size() < num_correspondences ) num_correspondences = static_cast<unsigned int>(world_pts.size());
64 assert( num_correspondences >= 6 );
68 for (
unsigned i = 0; i < num_correspondences; ++i ) {
69 S(2*i,0) = -image_pts[i].w()*world_pts[i].x();
70 S(2*i,1) = -image_pts[i].w()*world_pts[i].y();
71 S(2*i,2) = -image_pts[i].w()*world_pts[i].z();
72 S(2*i,3) = -image_pts[i].w()*world_pts[i].w();
73 S(2*i,8) = image_pts[i].x()*world_pts[i].x();
74 S(2*i,9) = image_pts[i].x()*world_pts[i].y();
75 S(2*i,10) = image_pts[i].x()*world_pts[i].z();
76 S(2*i,11) = image_pts[i].x()*world_pts[i].w();
77 S(2*i+1,4) = -image_pts[i].w()*world_pts[i].x();
78 S(2*i+1,5) = -image_pts[i].w()*world_pts[i].y();
79 S(2*i+1,6) = -image_pts[i].w()*world_pts[i].z();
81 S(2*i+1,7) = -image_pts[i].w()*world_pts[i].w();
82 S(2*i+1,8) = image_pts[i].y()*world_pts[i].x();
83 S(2*i+1,9) = image_pts[i].y()*world_pts[i].y();
84 S(2*i+1,10) = image_pts[i].y()*world_pts[i].z();
85 S(2*i+1,11) = image_pts[i].y()*world_pts[i].w();
90 cm(0,0)=c(0); cm(0,1)=c(1); cm(0,2)=c(2); cm(0,3)=c(3);
91 cm(1,0)=c(4); cm(1,1)=c(5); cm(1,2)=c(6); cm(1,3)=c(7);
92 cm(2,0)=c(8); cm(2,1)=c(9); cm(2,2)=c(10); cm(2,3)=c(11);
105 assert( image_pts.size() == world_pts.size() );
106 assert( image_pts.size() > 3 );
110 for (
unsigned int i = 0; i < world_pts.size(); ++i) {
111 A(i,0) = world_pts[i].x(); A(i,1) = world_pts[i].y(); A(i,2) = world_pts[i].z();
115 for (
unsigned int i = 0; i < image_pts.size(); ++i) {
116 b1(i) = image_pts[i].x(); b2(i) = image_pts[i].y();
120 if ( svd.
rank() < 4 ) {
121 std::cerr <<
"vpgl_affine_camera_compute:compute() cannot compute,\n" 122 <<
" input data has insufficient rank.\n";
145 auto N = static_cast<unsigned int>(world_pts.size());
146 if (image_pts.size()!=N)
148 std::cout <<
"Unequal points sets in" 149 <<
" vpgl_perspective_camera_compute::compute()\n";
154 std::cout <<
"Need at least 6 points for" 155 <<
" vpgl_perspective_camera_compute::compute()\n";
167 for (
unsigned c = 0; c<N; ++c)
170 wp[0][c] = p.
x(); wp[1][c] = p.
y(); wp[2][c] = p.
z();
174 std::cout <<
"World Points\n" << wp <<
'\n';
177 unsigned rank = svd.
rank();
180 std::cout <<
"Insufficient rank for world point" 181 <<
" matrix in vpgl_perspective_camera_compute::compute()\n";
188 for (
unsigned c = 4; c<nc; ++c)
189 for (
unsigned r = 0; r<nr; ++r)
190 null_space[r][c-4] = V[r][c];
192 std::cout <<
"Null Space\n" << null_space <<
'\n';
195 unsigned nrk = 3*(nc-4), nck = 3*nr;
197 for (
unsigned r = 0; r<(nc-4); ++r)
198 for (
unsigned c = 0; c<nr; ++c)
199 for (
unsigned rk = 0; rk<3; ++rk)
200 for (
unsigned ck = 0; ck<3; ++ck)
201 v2k[rk+3*r][ck+3*c] = k_inv[rk][ck]*null_space[c][r];
203 std::cout <<
"V2K\n" << v2k <<
'\n';
208 for (
unsigned c = 0; c<N; ++c)
211 D[3*c][c] = p.
x(); D[3*c+1][c] = p.
y(); D[3*c+2][c] = 1.0;
214 std::cout <<
"D\n" << D <<
'\n';
224 std::cout <<
"depths\n" << depth <<
'\n';
228 double average_depth = 0;
229 auto nd = static_cast<unsigned int>(depth.size());
230 for (
unsigned i = 0; i<nd; ++i)
231 average_depth += depth[i];
234 for (
unsigned i = 0; i<nd; ++i)
236 double dev = std::fabs(depth[i]-average_depth);
240 double norm_max_dev = max_dev/average_depth;
243 if (norm_max_dev < 0.01)
244 for (
unsigned i = 0; i<nd; ++i)
245 depth[i]=std::fabs(average_depth);
249 for (
unsigned c = 0; c<N; ++c)
254 X[0][c] = pi.
x()*depth[c]; X[1][c] = pi.
y()*depth[c]; X[2][c] = depth[c];
256 Y[0][c] = pw.
x(); Y[1][c] = pw.
y(); Y[2][c] = pw.
z();
268 std::cout <<
"translation\n" << t <<
'\n' 269 <<
"scale = " << op.
s() <<
'\n' 281 std::vector<vgl_homg_point_3d<double> > h_world_pts;
282 for (
unsigned i = 0; i<N; ++i)
283 h_world_pts.emplace_back(world_pts[i]);
304 if (image_pts.size() < 6) {
305 std::cout<<
"vpgl_perspective_camera_compute::compute needs at" 306 <<
" least 6 points!" << std::endl;
309 else if (image_pts.size() != world_pts.size()) {
310 std::cout<<
"vpgl_perspective_camera_compute::compute needs to" 311 <<
" have input vectors of the same size!" << std::endl
312 <<
"Currently, image_pts is size " << image_pts.size()
313 <<
" and world_pts is size " << world_pts.size() << std::endl;
320 int num_eqns = static_cast<int>(2 * image_pts.size());
337 for (
unsigned int i = 0; i < image_pts.size(); ++i)
340 A.
put(2*i, 0, world_pts[i].x());
341 A.
put(2*i, 1, world_pts[i].y());
342 A.
put(2*i, 2, world_pts[i].z());
350 A.
put(2*i, 8, -image_pts[i].x() * world_pts[i].x());
351 A.
put(2*i, 9, -image_pts[i].x() * world_pts[i].y());
352 A.
put(2*i, 10, -image_pts[i].x() * world_pts[i].z());
355 A.
put(2*i+1, 0, 0.0);
356 A.
put(2*i+1, 1, 0.0);
357 A.
put(2*i+1, 2, 0.0);
358 A.
put(2*i+1, 3, 0.0);
360 A.
put(2*i+1, 4, world_pts[i].x());
361 A.
put(2*i+1, 5, world_pts[i].y());
362 A.
put(2*i+1, 6, world_pts[i].z());
363 A.
put(2*i+1, 7, 1.0);
365 A.
put(2*i+1, 8, -image_pts[i].y() * world_pts[i].x());
366 A.
put(2*i+1, 9, -image_pts[i].y() * world_pts[i].y());
367 A.
put(2*i+1, 10, -image_pts[i].y() * world_pts[i].z());
370 b[2 * i] = image_pts[i].x();
371 b[2 * i + 1] = image_pts[i].y();
381 for (
int row = 0; row < 3; row++) {
382 for (
int col = 0; col < 4; col++) {
383 if (row*4 + col < 11) {
384 proj.
put(row, col, x[row*4 + col]);
393 for (
unsigned int i = 0; i < image_pts.size(); ++i) {
395 world_pt[0] = world_pts[i].x();
396 world_pt[1] = world_pts[i].y();
397 world_pt[2] = world_pts[i].z();
402 projed_pt[0] /= projed_pt[2];
403 projed_pt[1] /= projed_pt[2];
405 double dx = projed_pt[0] - image_pts[i].x();
406 double dy = projed_pt[1] - image_pts[i].y();
426 auto num_pts = static_cast<unsigned int>(ground_pts.size());
427 if (image_pts.size()!=num_pts)
429 std::cout <<
"Unequal points sets in" 430 <<
" vpgl_perspective_camera_compute::compute()\n";
435 std::cout <<
"Need at least 4 points for" 436 <<
" vpgl_perspective_camera_compute::compute()\n";
440 std::vector<vgl_homg_point_2d<double> > pi, pg;
441 for (
unsigned i=0; i<num_pts; ++i) {
443 std::cout <<
'('<<image_pts[i].x()<<
", "<<image_pts[i].y()<<
") -> " 444 <<
'('<<ground_pts[i].x()<<
", "<<ground_pts[i].y()<<
')'<<std::endl;
446 pi.emplace_back(image_pts[i].x(),image_pts[i].y());
447 pg.emplace_back(ground_pts[i].x(),ground_pts[i].y());
464 A.set_column(2,
vnl_cross_3d(A.get_column(0), A.get_column(1)));
470 double max_dist = 0.0;
471 for (
unsigned int i=0; i < ground_pts.size(); ++i) {
487 t = -R.transpose()*t;
493 std::vector<vgl_homg_point_3d<double> > h_world_pts;
494 for (
unsigned i = 0; i<num_pts; ++i) {
495 h_world_pts.emplace_back(ground_pts[i].x(),ground_pts[i].y(),0,1);
497 std::cout <<
"behind camera" << std::endl;
506 #endif // vpgl_camera_compute_cxx_ bool vpgl_perspective_decomposition(const vnl_matrix_fixed< T, 3, 4 > &camera_matrix, vpgl_perspective_camera< T > &p_camera)
Decompose camera into parameter blocks.
void set_rotation(const vgl_rotation_3d< T > &R)
vnl_vector< T > vnl_cross_3d(const vnl_vector< T > &v1, const vnl_vector< T > &v2)
A geographic coordinate system.
unsigned int rank() const
vnl_matrix_fixed< T, 3, 3 > as_matrix() const
vnl_vector_fixed< double, 3 > t()
the resulting translation vector.
static bool compute(const std::vector< vgl_homg_point_2d< double > > &image_pts, const std::vector< vgl_homg_point_3d< double > > &world_pts, vpgl_proj_camera< double > &camera)
Compute from two sets of corresponding points.
static bool compute_dlt(const std::vector< vgl_point_2d< double > > &image_pts, const std::vector< vgl_point_3d< double > > &world_pts, vpgl_perspective_camera< double > &camera, double &err)
Uses the direct linear transform algorithm described in "Multiple.
vnl_matrix< double > transpose() const
vnl_vector< T > nullvector() const
void set_camera_center(const vgl_point_3d< T > &camera_center)
vnl_matrix< T > inverse() const
void put(unsigned r, unsigned c, T const &v)
const vpgl_calibration_matrix< T > & get_calibration() const
static vpgl_perspective_camera< double > opt_orient_pos_cal(const vpgl_perspective_camera< double > &camera, const std::vector< vgl_homg_point_3d< double > > &world_points, const std::vector< vgl_point_2d< double > > &image_points, const double xtol=0.0001, const unsigned nevals=10000)
optimize orientation, position and internal calibration(no skew)for a perspective camera.
bool compute(std::vector< vgl_homg_point_2d< double > > const &points1, std::vector< vgl_homg_point_2d< double > > const &points2, vgl_h_matrix_2d< double > &H)
vnl_matrix< T > solve(vnl_matrix< T > const &B) const
vnl_matrix_fixed< T, 1, 1 > vnl_inverse(vnl_matrix_fixed< T, 1, 1 > const &m)
Several routines for computing different kinds of cameras from world-point correspondences.
void set_calibration(const vpgl_calibration_matrix< T > &K)
Setters and getters.
VNL_EXPORT T vnl_det(T const *row0, T const *row1)
Methods for projecting geometric structures onto the image.
vnl_matrix_fixed< T, num_cols, num_rows > transpose() const
vnl_matrix_fixed< T, 3, 3 > get_matrix() const
Get the calibration matrix.
vnl_matrix & fill(double const &)
static vpgl_perspective_camera< double > opt_orient_pos(const vpgl_perspective_camera< double > &camera, const std::vector< vgl_homg_point_3d< double > > &world_points, const std::vector< vgl_point_2d< double > > &image_points)
optimize orientation and position for a perspective camera.
This class implements the perspective camera class as described in Hartley & Zisserman as a finite ca...
bool compute_ok() const
successful computation.
double residual_mean_sq_error()
the residual error.
bool is_behind_camera(const vgl_homg_point_3d< T > &world_point) const
Determine whether the given point lies in front of the principal plane.
static bool compute(const std::vector< vgl_point_2d< double > > &image_pts, const std::vector< vgl_point_3d< double > > &world_pts, vpgl_affine_camera< double > &camera)
Compute from two sets of corresponding points.
unsigned int rows() const
void set_rows(const vnl_vector_fixed< T, 4 > &row1, const vnl_vector_fixed< T, 4 > &row2)
Set the top two rows.
vnl_vector_fixed< T, n > & normalize()
Solve orthogonal Procrustes problem.
static bool compute(const std::vector< vgl_point_2d< double > > &image_pts, const std::vector< vgl_point_3d< double > > &world_pts, const vpgl_calibration_matrix< double > &K, vpgl_perspective_camera< double > &camera)
Compute from two sets of corresponding points.
vnl_matrix_fixed< T, num_cols, num_rows > conjugate_transpose() const
vgl_rotation_3d< double > R()
the resulting rotation matrix.
double length(v const &a)
unsigned int columns() const
Solve min(R,s) ||X-s(RY+t)||, where R is a rotation matrix, X,Y are 3-d points, s is a scalar and t i...
vnl_matrix_fixed & set(unsigned r, unsigned c, T const &v)
Methods for back_projecting from cameras to 3-d geometric structures.
void put(unsigned r, unsigned c, double const &)
double s()
The scale factor, s.