00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __CAMERA_H
00024 #define __CAMERA_H
00025
00026 #include <cmath>
00027 #include <TooN/TooN.h>
00028 #include <TooN/helpers.h>
00029
00030 template<class T>
00031 inline T SAT(T x){return (x<-1.0/3?-1e9:x);}
00032
00035 namespace Camera {
00036
00039 class Linear {
00040 public:
00042 static const int num_parameters=4;
00043
00046 inline void load(std::istream& is);
00049 inline void save(std::ostream& os);
00050
00052 inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, double scale=1) const;
00054 inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const;
00056 inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe) const;
00057
00060 inline TooN::Matrix<2,2> get_derivative() const;
00061
00063 inline TooN::Matrix<num_parameters,2> get_parameter_derivs() const ;
00064
00068 inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const ;
00069
00073 inline void update(const TooN::Vector<num_parameters>& updates);
00074
00077 inline TooN::Vector<num_parameters>& get_parameters() {return my_camera_parameters;}
00078 inline const TooN::Vector<num_parameters>& get_parameters() const {return my_camera_parameters;}
00079
00080 private:
00081 TooN::Vector<num_parameters> my_camera_parameters;
00082 mutable TooN::Vector<2> my_last_camframe;
00083 };
00084
00085
00088 class Cubic {
00089 public:
00091 static const int num_parameters=5;
00092
00095 inline void load(std::istream& is);
00098 inline void save(std::ostream& os);
00099
00101 inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, double scale=1);
00103 inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const;
00105 inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe);
00106
00109 inline TooN::Matrix<2,2> get_derivative();
00110
00112 inline TooN::Matrix<num_parameters,2> get_parameter_derivs() const ;
00113
00117 inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const ;
00118
00122 inline void update(const TooN::Vector<num_parameters>& updates);
00123
00126 inline TooN::Vector<num_parameters>& get_parameters() {return my_camera_parameters;}
00127 inline const TooN::Vector<num_parameters>& get_parameters() const {return my_camera_parameters;}
00128
00129 private:
00130 TooN::Vector<num_parameters> my_camera_parameters;
00131 mutable TooN::Vector<2> my_last_camframe;
00132 };
00133
00134
00137 class Quintic {
00138 public:
00140 static const int num_parameters=6;
00141
00144 inline void load(std::istream& is);
00147 inline void save(std::ostream& os);
00148
00150 inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, double scale=1) const ;
00152
00153 inline TooN::Vector<2> project_vector(const TooN::Vector<2>& x, const TooN::Vector<2>& d) const {
00154 const double xsq = x*x;
00155 const double& a = my_camera_parameters[4];
00156 const double& b = my_camera_parameters[5];
00157 return (2 * (a + 2*b*xsq) * (x*d) * TooN::diagmult(my_camera_parameters.slice<0,2>(), x) +
00158 (1 + a*xsq + b*xsq*xsq)*TooN::diagmult(my_camera_parameters.slice<0,2>(), d));
00159 }
00160
00161 inline TooN::Vector<2> project_vector(const TooN::Vector<2>& d) const {
00162 return diagmult(my_camera_parameters.slice<0,2>(), d);
00163 }
00164 inline TooN::Vector<2> unproject_vector(const TooN::Vector<2>& d) const {
00165 TooN::Vector<2> v;
00166 v[0] = d[0]/my_camera_parameters[0];
00167 v[1] = d[1]/my_camera_parameters[1];
00168 return v;
00169 }
00170 inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const;
00171 inline std::pair<TooN::Vector<2>, TooN::Matrix<2> > project(const TooN::Vector<2>& camframe, const TooN::Matrix<2>& R) const;
00172
00174 inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe) const;
00175
00176 inline std::pair<TooN::Vector<2>, TooN::Matrix<2> > unproject(const TooN::Vector<2>& imframe, const TooN::Matrix<2>& R) const;
00177
00180 inline TooN::Matrix<2,2> get_derivative() const;
00181 inline TooN::Matrix<2,2> get_derivative(const TooN::Vector<2>& x) const;
00182
00183 inline TooN::Matrix<2,2> get_inv_derivative() const;
00184 inline TooN::Matrix<2,2> get_inv_derivative(const TooN::Vector<2>& x) const;
00185
00187 inline TooN::Matrix<num_parameters,2> get_parameter_derivs() const ;
00188
00192 inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const ;
00193
00197 inline void update(const TooN::Vector<num_parameters>& updates);
00198
00201 inline const TooN::Vector<num_parameters>& get_parameters() const {return my_camera_parameters;}
00204 inline TooN::Vector<num_parameters>& get_parameters() {return my_camera_parameters;}
00205
00206 private:
00207 TooN::Vector<num_parameters> my_camera_parameters;
00208 mutable TooN::Vector<2> my_last_camframe;
00209
00210 inline double sat(double x)
00211 {
00212 double a;
00213 a = (-3*my_camera_parameters[4] - sqrt(9*my_camera_parameters[4]*my_camera_parameters[4] - 20 * my_camera_parameters[5]))/(10*my_camera_parameters[5]);
00214
00215 if(x < a)
00216 return x;
00217 else
00218 return 1e9;
00219 }
00220 };
00221
00232 class Harris{
00233
00234 private:
00235 TooN::Vector<2> radial_distort(const TooN::Vector<2>& camframe) const
00236 {
00237 double r2 = camframe*camframe;
00238 return camframe / sqrt(1 + my_camera_parameters[4] * r2);
00239 }
00240
00241
00242 public:
00244 static const int num_parameters=5;
00245
00248 inline void load(std::istream& is);
00249
00252 inline void save(std::ostream& os)
00253 {
00254 os << my_camera_parameters;
00255 }
00256
00257
00259 inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, double scale=1) const
00260 {
00261 return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00262 }
00263
00265 inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const
00266 {
00267 my_last_camframe = camframe;
00268 return linearproject(radial_distort(camframe));
00269 }
00270
00272 inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe)
00273 {
00274
00275 TooN::Vector<2> mod_camframe;
00276 mod_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00277 mod_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[1];
00278 double rprime2 = mod_camframe*mod_camframe;
00279 my_last_camframe = mod_camframe / sqrt(1 - my_camera_parameters[4] * rprime2);
00280 return my_last_camframe;
00281 }
00282
00285 inline TooN::Matrix<2,2> get_derivative() const
00286 {
00287 return get_derivative(my_last_camframe);
00288 }
00289
00292 inline TooN::Matrix<2,2> get_derivative(const TooN::Vector<2>& pt) const
00293 {
00294 TooN::Matrix<2,2> J;
00295
00296 double xc = pt[0];
00297 double yc = pt[1];
00298
00299 double fu= my_camera_parameters[0];
00300 double fv= my_camera_parameters[1];
00301 double a = my_camera_parameters[4];
00302
00303 double g = 1/sqrt(1 + a * (xc*xc + yc*yc));
00304 double g3= g*g*g;
00305
00306 J[0][0] = fu * (g - a * xc*xc*g3);
00307 J[0][1] = - fu * a * xc * yc * g3;
00308 J[1][0] = - fv * a * xc * yc * g3;
00309 J[1][1] = fv * (g - a * yc*yc*g3);
00310
00311 return J;
00312 }
00313
00315 inline TooN::Matrix<num_parameters,2> get_parameter_derivs() const
00316 {
00317 return get_parameter_derivs_at(my_last_camframe);
00318 }
00319
00322 inline TooN::Matrix<num_parameters,2> get_parameter_derivs_at(const TooN::Vector<2>& pt) const
00323 {
00324 TooN::Vector<2> mod_camframe = radial_distort(pt);
00325
00326 TooN::Matrix<5, 2> result;
00327
00328 double xc = pt[0];
00329 double yc = pt[1];
00330 double r2 = xc*xc + yc*yc;
00331
00332 double fu= my_camera_parameters[0];
00333 double fv= my_camera_parameters[1];
00334 double a = my_camera_parameters[4];
00335
00336 double g = 1/sqrt(1 + a * r2);
00337 double g3= g*g*g;
00338
00339
00340 result[0][0] = mod_camframe[0];
00341 result[1][0] = 0;
00342 result[2][0] = 1;
00343 result[3][0] = 0;
00344 result[4][0] = - fu * xc * r2 / 2 * g3;
00345
00346
00347 result[0][1] = 0;
00348 result[1][1] = mod_camframe[1];
00349 result[2][1] = 0;
00350 result[3][1] = 1;
00351 result[4][1] = - fv * yc * r2 / 2 * g3;
00352
00353 return result;
00354 }
00355
00359 inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const
00360 {
00361 return get_parameter_derivs() * direction;
00362 }
00363
00367
00368
00371 inline TooN::Vector<num_parameters>& get_parameters()
00372 {
00373 return my_camera_parameters;
00374 }
00375 inline const TooN::Vector<num_parameters>& get_parameters() const
00376 {
00377 return my_camera_parameters;
00378 }
00379
00380 private:
00381 TooN::Vector<num_parameters> my_camera_parameters;
00382 mutable TooN::Vector<2> my_last_camframe;
00383 };
00384
00387 class SquareHarris{
00388
00389 private:
00390 TooN::Vector<2> radial_distort(const TooN::Vector<2>& camframe) const
00391 {
00392 double r2 = camframe*camframe;
00393 return camframe / sqrt(1 + my_camera_parameters[4] * r2);
00394 }
00395
00396
00397 public:
00399 static const int num_parameters=5;
00400
00403 inline void load(std::istream& is);
00404
00407 inline void save(std::ostream& os)
00408 {
00409 os << my_camera_parameters;
00410 }
00411
00412
00414 inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, double scale=1) const
00415 {
00416 return TooN::Vector<2>(scale * (camframe* my_camera_parameters[0]) + my_camera_parameters.slice<2,2>());
00417 }
00418
00420 inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const
00421 {
00422 my_last_camframe = camframe;
00423 return linearproject(radial_distort(camframe));
00424 }
00425
00427 inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe)
00428 {
00429
00430 TooN::Vector<2> mod_camframe;
00431 mod_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00432 mod_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[0];
00433 double rprime2 = mod_camframe*mod_camframe;
00434 my_last_camframe = mod_camframe / sqrt(1 - my_camera_parameters[4] * rprime2);
00435 return my_last_camframe;
00436 }
00437
00440 inline TooN::Matrix<2,2> get_derivative() const
00441 {
00442 TooN::Matrix<2,2> J;
00443
00444 double xc = my_last_camframe[0];
00445 double yc = my_last_camframe[1];
00446
00447 double f= my_camera_parameters[0];
00448 double a = my_camera_parameters[4];
00449
00450 double g = 1/sqrt(1 + a * (xc*xc + yc*yc));
00451 double g3= g*g*g;
00452
00453 J[0][0] = f * (g - 2 * a * xc*xc*g3);
00454 J[0][1] = -2 * f * a * xc * yc * g3;
00455 J[1][0] = -2 * f * a * xc * yc * g3;
00456 J[1][1] = f * (g - 2 * a * yc*yc*g3);
00457
00458 return J;
00459 }
00460
00462 inline TooN::Matrix<num_parameters,2> get_parameter_derivs() const
00463 {
00464 TooN::Vector<2> mod_camframe = radial_distort(my_last_camframe);
00465
00466 TooN::Matrix<5, 2> result;
00467
00468 double xc = my_last_camframe[0];
00469 double yc = my_last_camframe[1];
00470 double r2 = xc*xc + yc*yc;
00471
00472 double f= my_camera_parameters[0];
00473 double a = my_camera_parameters[4];
00474
00475 double g = 1/sqrt(1 + a * r2);
00476 double g3= g*g*g;
00477
00478
00479 result[0][0] = mod_camframe[0];
00480 result[1][0] = 0;
00481 result[2][0] = 1;
00482 result[3][0] = 0;
00483 result[4][0] = - f * xc * r2 / 2 * g3;
00484
00485
00486
00487
00488 result[0][1] = mod_camframe[1];
00489 result[1][1] = 0;
00490 result[2][1] = 0;
00491 result[3][1] = 1;
00492 result[4][1] = - f * yc * r2 / 2 * g3;
00493
00494 return result;
00495 }
00496
00500 inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const
00501 {
00502 return get_parameter_derivs() * direction;
00503 }
00504
00508
00509
00512 inline TooN::Vector<num_parameters>& get_parameters()
00513 {
00514 my_camera_parameters[1] = 0;
00515 return my_camera_parameters;
00516 }
00517
00518 private:
00519 TooN::Vector<num_parameters> my_camera_parameters;
00520 mutable TooN::Vector<2> my_last_camframe;
00521 };
00522
00523
00524
00525 }
00526
00527
00528
00529
00531
00533
00534 void Camera::Linear::load(std::istream& is) {
00535 is >> my_camera_parameters;
00536 }
00537
00538 void Camera::Linear::save(std::ostream& os){
00539 os << my_camera_parameters;
00540 }
00541
00542 inline TooN::Vector<2> Camera::Linear::linearproject(const TooN::Vector<2>& camframe, double scale) const {
00543 return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00544 }
00545
00546 inline TooN::Vector<2> Camera::Linear::project(const TooN::Vector<2>& camframe) const {
00547 my_last_camframe = camframe;
00548 return TooN::Vector<2>(diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00549 }
00550
00551 inline TooN::Vector<2> Camera::Linear::unproject(const TooN::Vector<2>& imframe) const {
00552 my_last_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00553 my_last_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[1];
00554 return my_last_camframe;
00555 }
00556
00557 TooN::Matrix<2,2> Camera::Linear::get_derivative() const {
00558 TooN::Matrix<2,2> result;
00559 result(0,0) = my_camera_parameters[0];
00560 result(1,1) = my_camera_parameters[1];
00561 result(0,1) = result(1,0) = 0;
00562 return result;
00563 }
00564
00565 TooN::Matrix<Camera::Linear::num_parameters,2> Camera::Linear::get_parameter_derivs() const {
00566 TooN::Matrix<num_parameters,2> result;
00567 result(0,0) = my_last_camframe[0];
00568 result(0,1) = 0;
00569 result(1,0) = 0;
00570 result(1,1) = my_last_camframe[1];
00571 result(2,0) = 1;
00572 result(2,1) = 0;
00573 result(3,0) = 0;
00574 result(3,1) = 1;
00575 return result;
00576 }
00577
00578 TooN::Vector<Camera::Linear::num_parameters> Camera::Linear::get_parameter_derivs(const TooN::Vector<2>& direction) const {
00579 TooN::Vector<num_parameters> result;
00580 result[0] = my_last_camframe[0] * direction[0];
00581 result[1] = my_last_camframe[1] * direction[1];
00582 result[2] = direction[0];
00583 result[3] = direction[1];
00584
00585 return result;
00586 }
00587
00588 void Camera::Linear::update(const TooN::Vector<num_parameters>& updates){
00589 my_camera_parameters+=updates;
00590 }
00591
00592
00594
00596
00597 void Camera::Cubic::load(std::istream& is) {
00598 is >> my_camera_parameters;
00599 }
00600
00601 void Camera::Cubic::save(std::ostream& os){
00602 os << my_camera_parameters;
00603 }
00604
00605 inline TooN::Vector<2> Camera::Cubic::linearproject(const TooN::Vector<2>& camframe, double scale){
00606 return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00607 }
00608
00609 inline TooN::Vector<2> Camera::Cubic::project(const TooN::Vector<2>& camframe) const{
00610 my_last_camframe = camframe;
00611 TooN::Vector<2> mod_camframe = camframe * (1+SAT(my_camera_parameters[4]*(camframe*camframe)));
00612 return TooN::Vector<2>(diagmult(mod_camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00613 }
00614
00615 inline TooN::Vector<2> Camera::Cubic::unproject(const TooN::Vector<2>& imframe){
00616 TooN::Vector<2> mod_camframe;
00617 mod_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00618 mod_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[1];
00619
00620
00621 double scale = 1+my_camera_parameters[4]*(mod_camframe*mod_camframe);
00622
00623
00624 for(int i=0; i<3; i++){
00625 double error = my_camera_parameters[4]*(mod_camframe*mod_camframe) - scale*scale*(scale-1);
00626 double deriv = (3*scale -2)*scale;
00627 scale += error/deriv;
00628 }
00629 my_last_camframe = mod_camframe/scale;
00630
00631 return my_last_camframe;
00632 }
00633
00634 TooN::Matrix<2,2> Camera::Cubic::get_derivative(){
00635 TooN::Matrix<2,2> result = TooN::Identity;
00636 result *= 1+my_camera_parameters[4]*(my_last_camframe*my_last_camframe);
00637 result += (2*my_camera_parameters[4]*my_last_camframe.as_col()) * my_last_camframe.as_row();
00638 result[0] *= my_camera_parameters[0];
00639 result[1] *= my_camera_parameters[1];
00640 return result;
00641 }
00642
00643 TooN::Matrix<Camera::Cubic::num_parameters,2> Camera::Cubic::get_parameter_derivs() const {
00644 TooN::Vector<2> mod_camframe = my_last_camframe * (1+my_camera_parameters[4]*(my_last_camframe*my_last_camframe));
00645 TooN::Matrix<num_parameters,2> result;
00646 result(0,0) = mod_camframe[0]*my_camera_parameters[0];
00647 result(0,1) = 0;
00648 result(1,0) = 0;
00649 result(1,1) = mod_camframe[1]*my_camera_parameters[1];
00650 result(2,0) = 1*my_camera_parameters[0];
00651 result(2,1) = 0;
00652 result(3,0) = 0;
00653 result(3,1) = 1*my_camera_parameters[1];
00654 result[4] = diagmult(my_last_camframe,my_camera_parameters.slice<0,2>())*(my_last_camframe*my_last_camframe);
00655 return result;
00656 }
00657
00658 TooN::Vector<Camera::Cubic::num_parameters> Camera::Cubic::get_parameter_derivs(const TooN::Vector<2>& direction) const {
00659 TooN::Vector<2> mod_camframe = my_last_camframe * (1+my_camera_parameters[4]*(my_last_camframe*my_last_camframe));
00660 TooN::Vector<num_parameters> result;
00661 result[0] = mod_camframe[0] * direction[0] *my_camera_parameters[0];
00662 result[1] = mod_camframe[1] * direction[1] *my_camera_parameters[1];
00663 result[2] = direction[0] *my_camera_parameters[0];
00664 result[3] = direction[1] *my_camera_parameters[1];
00665 result[4] = (diagmult(my_last_camframe,my_camera_parameters.slice<0,2>())*direction)*(my_last_camframe*my_last_camframe);
00666 return result;
00667 }
00668
00669 void Camera::Cubic::update(const TooN::Vector<num_parameters>& updates){
00670 double fu=my_camera_parameters[0];
00671 double fv=my_camera_parameters[1];
00672 my_camera_parameters[0]+=fu*updates[0];
00673 my_camera_parameters[1]+=fv*updates[1];
00674 my_camera_parameters[2]+=fu*updates[2];
00675 my_camera_parameters[3]+=fv*updates[3];
00676 my_camera_parameters[4]+=updates[4];
00677
00678 }
00679
00681
00683
00684 void Camera::Quintic::load(std::istream& is) {
00685 is >> my_camera_parameters;
00686 }
00687
00688 void Camera::Quintic::save(std::ostream& os){
00689 os << my_camera_parameters;
00690 }
00691
00692 inline TooN::Vector<2> Camera::Quintic::linearproject(const TooN::Vector<2>& camframe, double scale) const {
00693 return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00694 }
00695
00696 inline TooN::Vector<2> Camera::Quintic::project(const TooN::Vector<2>& camframe) const {
00697 my_last_camframe = camframe;
00698 double sc = (camframe*camframe);
00699 TooN::Vector<2> mod_camframe = camframe * (1 + sc*(my_camera_parameters[4] + sc*my_camera_parameters[5]));
00700 return TooN::Vector<2>(diagmult(mod_camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00701 }
00702
00703 inline std::pair<TooN::Vector<2>, TooN::Matrix<2> > Camera::Quintic::project(const TooN::Vector<2>& camframe, const TooN::Matrix<2>& R) const
00704 {
00705 std::pair<TooN::Vector<2>, TooN::Matrix<2> > result;
00706 result.first = this->project(camframe);
00707 const TooN::Matrix<2> J = this->get_derivative();
00708 result.second = J * R * J.T();
00709 return result;
00710 }
00711
00712 inline TooN::Vector<2> Camera::Quintic::unproject(const TooN::Vector<2>& imframe) const {
00713 TooN::Vector<2> mod_camframe;
00714 mod_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00715 mod_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[1];
00716
00717
00718 double scale = mod_camframe*mod_camframe;
00719
00720
00721 for(int i=0; i<3; i++){
00722 double temp=1+scale*(my_camera_parameters[4]+my_camera_parameters[5]*scale);
00723 double error = mod_camframe*mod_camframe - scale*temp*temp;
00724 double deriv = temp*(temp+2*scale*(my_camera_parameters[4]+2*my_camera_parameters[5]*scale));
00725 scale += error/deriv;
00726 }
00727 my_last_camframe = mod_camframe/(1+scale*(my_camera_parameters[4]+my_camera_parameters[5]*scale));
00728
00729
00730
00731 return my_last_camframe;
00732 }
00733
00734 inline std::pair<TooN::Vector<2>, TooN::Matrix<2> > Camera::Quintic::unproject(const TooN::Vector<2>& imframe, const TooN::Matrix<2>& R) const
00735 {
00736 std::pair<TooN::Vector<2>, TooN::Matrix<2> > result;
00737 result.first = this->unproject(imframe);
00738 TooN::Matrix<2> J = get_derivative();
00739 double rdet = 1.0/ (J[0][0] * J[1][1] - J[0][1] * J[1][0]);
00740 TooN::Matrix<2> Jinv;
00741 Jinv[0][0] = rdet * J[1][1];
00742 Jinv[1][1] = rdet * J[0][0];
00743 Jinv[0][1] = -rdet * J[0][1];
00744 Jinv[1][0] = -rdet * J[1][0];
00745 result.second = Jinv * R * Jinv.T();
00746 return result;
00747 }
00748
00749
00750 TooN::Matrix<2,2> Camera::Quintic::get_derivative() const {
00751 TooN::Matrix<2,2> result = TooN::Identity;
00752 double temp1=my_last_camframe*my_last_camframe;
00753 double temp2=my_camera_parameters[5]*temp1;
00754 result *= 1+temp1*(my_camera_parameters[4]+temp2);
00755 result += (2*(my_camera_parameters[4]+2*temp2)*my_last_camframe.as_col()) * my_last_camframe.as_row();
00756 result[0] *= my_camera_parameters[0];
00757 result[1] *= my_camera_parameters[1];
00758 return result;
00759 }
00760
00761
00762
00763 TooN::Matrix<2,2> Camera::Quintic::get_inv_derivative() const {
00764 TooN::Matrix<2,2> result = TooN::Identity;
00765 double temp1=my_last_camframe*my_last_camframe;
00766 double temp2=my_camera_parameters[5]*temp1;
00767 double temp3=2.0*(my_camera_parameters[4]+2.0*temp2);
00768
00769 result *= 1+temp1*(my_camera_parameters[4]+temp2);
00770
00771 result[0][0] += my_last_camframe[1]*my_last_camframe[1]*temp3;
00772 result[0][1] =-(temp3*my_last_camframe[0]*my_last_camframe[1]);
00773
00774 result[1][1] += my_last_camframe[0]*my_last_camframe[0]*temp3;
00775 result[1][0] =-(temp3*my_last_camframe[0]*my_last_camframe[1]);
00776
00777 (result.T())[0] *= my_camera_parameters[1];
00778 (result.T())[1] *= my_camera_parameters[0];
00779
00780 result /= (result[0][0]*result[1][1] - result[1][0]*result[0][1]);
00781
00782 return result;
00783 }
00784
00785 TooN::Matrix<2,2> Camera::Quintic::get_inv_derivative(const TooN::Vector<2>& x) const
00786 {
00787
00788 TooN::Matrix<2,2> result = TooN::Identity;
00789 double temp1=x*x;
00790 double temp2=my_camera_parameters[5]*temp1;
00791 double temp3=2.0*(my_camera_parameters[4]+2.0*temp2);
00792
00793 result *= 1+temp1*(my_camera_parameters[4]+temp2);
00794
00795
00796 result[0][0] += x[1]*x[1]*temp3;
00797 result[0][1] =-(temp3*x[0]*x[1]);
00798
00799 result[1][1] += x[0]*x[0]*temp3;
00800 result[1][0] =-(temp3*x[0]*x[1]);
00801
00802 (result.T())[0] *= my_camera_parameters[1];
00803 (result.T())[1] *= my_camera_parameters[0];
00804
00805 result /= (result[0][0]*result[1][1] - result[1][0]*result[0][1]);
00806
00807 return result;
00808
00809 }
00810
00811 TooN::Matrix<2,2> Camera::Quintic::get_derivative(const TooN::Vector<2>& x) const {
00812 TooN::Matrix<2,2> result = TooN::Identity;
00813 double temp1=x*x;
00814 double temp2=my_camera_parameters[5]*temp1;
00815 result *= 1+temp1*(my_camera_parameters[4]+temp2);
00816
00817 result += (2*(my_camera_parameters[4]+2*temp2)*x.as_col()) * x.as_row();
00818 result[0] *= my_camera_parameters[0];
00819 result[1] *= my_camera_parameters[1];
00820 return result;
00821 }
00822
00823 TooN::Matrix<Camera::Quintic::num_parameters,2> Camera::Quintic::get_parameter_derivs() const {
00824 TooN::Matrix<num_parameters,2> result;
00825 double r2 = my_last_camframe * my_last_camframe;
00826 double r4 = r2 * r2;
00827 TooN::Vector<2> mod_camframe = my_last_camframe * (1+ r2 * (my_camera_parameters[4] + r2 * my_camera_parameters[5]));
00828
00829 result(0,0) = mod_camframe[0];
00830 result(1,0) = 0;
00831 result(2,0) = 1;
00832 result(3,0) = 0;
00833 result(4,0) = my_camera_parameters[0]*my_last_camframe[0]*r2;
00834 result(5,0) = my_camera_parameters[0]*my_last_camframe[0]*r4;
00835
00836 result(0,1) = 0;
00837 result(1,1) = mod_camframe[1];
00838 result(2,1) = 0;
00839 result(3,1) = 1;
00840 result(4,1) = my_camera_parameters[1]*my_last_camframe[1]*r2;
00841 result(5,1) = my_camera_parameters[1]*my_last_camframe[1]*r4;
00842
00843
00844 return result;
00845 }
00846
00847 TooN::Vector<Camera::Quintic::num_parameters> Camera::Quintic::get_parameter_derivs(const TooN::Vector<2>& direction) const {
00848
00849
00850
00851 return get_parameter_derivs() * direction;
00852 }
00853
00854 void Camera::Quintic::update(const TooN::Vector<num_parameters>& updates){
00855 double fu = my_camera_parameters[0];
00856 double fv = my_camera_parameters[1];
00857
00858 my_camera_parameters[0]+=updates[0]*fu;
00859 my_camera_parameters[1]+=updates[1]*fv;
00860 my_camera_parameters[2]+=updates[2]*fu;
00861 my_camera_parameters[3]+=updates[3]*fv;
00862 my_camera_parameters[4]+=updates[4];
00863 my_camera_parameters[5]+=updates[5];
00864 }
00865
00866 #endif