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
00128 private:
00129 TooN::Vector<num_parameters> my_camera_parameters;
00130 mutable TooN::Vector<2> my_last_camframe;
00131 };
00132
00133
00136 class Quintic {
00137 public:
00139 static const int num_parameters=6;
00140
00143 inline void load(std::istream& is);
00146 inline void save(std::ostream& os);
00147
00149 inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, double scale=1) const ;
00151
00152 inline TooN::Vector<2> project_vector(const TooN::Vector<2>& x, const TooN::Vector<2>& d) const {
00153 const double xsq = x*x;
00154 const double& a = my_camera_parameters[4];
00155 const double& b = my_camera_parameters[5];
00156 return (2 * (a + 2*b*xsq) * (x*d) * TooN::diagmult(my_camera_parameters.slice<0,2>(), x) +
00157 (1 + a*xsq + b*xsq*xsq)*TooN::diagmult(my_camera_parameters.slice<0,2>(), d));
00158 }
00159
00160 inline TooN::Vector<2> project_vector(const TooN::Vector<2>& d) const {
00161 return diagmult(my_camera_parameters.slice<0,2>(), d);
00162 }
00163 inline TooN::Vector<2> unproject_vector(const TooN::Vector<2>& d) const {
00164 TooN::Vector<2> v;
00165 v[0] = d[0]/my_camera_parameters[0];
00166 v[1] = d[1]/my_camera_parameters[1];
00167 return v;
00168 }
00169 inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const;
00170 inline std::pair<TooN::Vector<2>, TooN::Matrix<2> > project(const TooN::Vector<2>& camframe, const TooN::Matrix<2>& R) const;
00171
00173 inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe) const;
00174
00175 inline std::pair<TooN::Vector<2>, TooN::Matrix<2> > unproject(const TooN::Vector<2>& imframe, const TooN::Matrix<2>& R) const;
00176
00179 inline TooN::Matrix<2,2> get_derivative() const;
00180 inline TooN::Matrix<2,2> get_derivative(const TooN::Vector<2>& x) const;
00181
00182 inline TooN::Matrix<2,2> get_inv_derivative() const;
00183 inline TooN::Matrix<2,2> get_inv_derivative(const TooN::Vector<2>& x) const;
00184
00186 inline TooN::Matrix<num_parameters,2> get_parameter_derivs() const ;
00187
00191 inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const ;
00192
00196 inline void update(const TooN::Vector<num_parameters>& updates);
00197
00200 inline const TooN::Vector<num_parameters>& get_parameters() const {return my_camera_parameters;}
00203 inline TooN::Vector<num_parameters>& get_parameters() {return my_camera_parameters;}
00204
00205 private:
00206 TooN::Vector<num_parameters> my_camera_parameters;
00207 mutable TooN::Vector<2> my_last_camframe;
00208
00209 inline double sat(double x)
00210 {
00211 double a;
00212 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]);
00213
00214 if(x < a)
00215 return x;
00216 else
00217 return 1e9;
00218 }
00219 };
00220
00231 class Harris{
00232
00233 private:
00234 TooN::Vector<2> radial_distort(const TooN::Vector<2>& camframe) const
00235 {
00236 double r2 = camframe*camframe;
00237 return camframe / sqrt(1 + my_camera_parameters[4] * r2);
00238 }
00239
00240
00241 public:
00243 static const int num_parameters=5;
00244
00247 inline void load(std::istream& is);
00248
00251 inline void save(std::ostream& os)
00252 {
00253 os << my_camera_parameters;
00254 }
00255
00256
00258 inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, double scale=1) const
00259 {
00260 return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00261 }
00262
00264 inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const
00265 {
00266 my_last_camframe = camframe;
00267 return linearproject(radial_distort(camframe));
00268 }
00269
00271 inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe)
00272 {
00273
00274 TooN::Vector<2> mod_camframe;
00275 mod_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00276 mod_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[1];
00277 double rprime2 = mod_camframe*mod_camframe;
00278 my_last_camframe = mod_camframe / sqrt(1 - my_camera_parameters[4] * rprime2);
00279 return my_last_camframe;
00280 }
00281
00284 inline TooN::Matrix<2,2> get_derivative() const
00285 {
00286 TooN::Matrix<2,2> J;
00287
00288 double xc = my_last_camframe[0];
00289 double yc = my_last_camframe[1];
00290
00291 double fu= my_camera_parameters[0];
00292 double fv= my_camera_parameters[1];
00293 double a = my_camera_parameters[4];
00294
00295 double g = 1/sqrt(1 + a * (xc*xc + yc*yc));
00296 double g3= g*g*g;
00297
00298 J[0][0] = fu * (g - 2 * a * xc*xc*g3);
00299 J[0][1] = -2 * fu * a * xc * yc * g3;
00300 J[1][0] = -2 * fv * a * xc * yc * g3;
00301 J[1][1] = fv * (g - 2 * a * yc*yc*g3);
00302
00303 return J;
00304 }
00305
00307 inline TooN::Matrix<num_parameters,2> get_parameter_derivs() const
00308 {
00309 TooN::Vector<2> mod_camframe = radial_distort(my_last_camframe);
00310
00311 TooN::Matrix<5, 2> result;
00312
00313 double xc = my_last_camframe[0];
00314 double yc = my_last_camframe[1];
00315 double r2 = xc*xc + yc*yc;
00316
00317 double fu= my_camera_parameters[0];
00318 double fv= my_camera_parameters[1];
00319 double a = my_camera_parameters[4];
00320
00321 double g = 1/sqrt(1 + a * r2);
00322 double g3= g*g*g;
00323
00324
00325 result[0][0] = mod_camframe[0];
00326 result[1][0] = 0;
00327 result[2][0] = 1;
00328 result[3][0] = 0;
00329 result[4][0] = - fu * xc * r2 / 2 * g3;
00330
00331
00332
00333
00334 result[0][1] = 0;
00335 result[1][1] = mod_camframe[1];
00336 result[2][1] = 0;
00337 result[3][1] = 1;
00338 result[4][1] = - fv * yc * r2 / 2 * g3;
00339
00340 return result;
00341 }
00342
00346 inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const
00347 {
00348 return get_parameter_derivs() * direction;
00349 }
00350
00354
00355
00358 inline TooN::Vector<num_parameters>& get_parameters()
00359 {
00360 return my_camera_parameters;
00361 }
00362
00363 private:
00364 TooN::Vector<num_parameters> my_camera_parameters;
00365 mutable TooN::Vector<2> my_last_camframe;
00366 };
00367
00370 class SquareHarris{
00371
00372 private:
00373 TooN::Vector<2> radial_distort(const TooN::Vector<2>& camframe) const
00374 {
00375 double r2 = camframe*camframe;
00376 return camframe / sqrt(1 + my_camera_parameters[4] * r2);
00377 }
00378
00379
00380 public:
00382 static const int num_parameters=5;
00383
00386 inline void load(std::istream& is);
00387
00390 inline void save(std::ostream& os)
00391 {
00392 os << my_camera_parameters;
00393 }
00394
00395
00397 inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, double scale=1) const
00398 {
00399 return TooN::Vector<2>(scale * (camframe* my_camera_parameters[0]) + my_camera_parameters.slice<2,2>());
00400 }
00401
00403 inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const
00404 {
00405 my_last_camframe = camframe;
00406 return linearproject(radial_distort(camframe));
00407 }
00408
00410 inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe)
00411 {
00412
00413 TooN::Vector<2> mod_camframe;
00414 mod_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00415 mod_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[0];
00416 double rprime2 = mod_camframe*mod_camframe;
00417 my_last_camframe = mod_camframe / sqrt(1 - my_camera_parameters[4] * rprime2);
00418 return my_last_camframe;
00419 }
00420
00423 inline TooN::Matrix<2,2> get_derivative() const
00424 {
00425 TooN::Matrix<2,2> J;
00426
00427 double xc = my_last_camframe[0];
00428 double yc = my_last_camframe[1];
00429
00430 double f= my_camera_parameters[0];
00431 double a = my_camera_parameters[4];
00432
00433 double g = 1/sqrt(1 + a * (xc*xc + yc*yc));
00434 double g3= g*g*g;
00435
00436 J[0][0] = f * (g - 2 * a * xc*xc*g3);
00437 J[0][1] = -2 * f * a * xc * yc * g3;
00438 J[1][0] = -2 * f * a * xc * yc * g3;
00439 J[1][1] = f * (g - 2 * a * yc*yc*g3);
00440
00441 return J;
00442 }
00443
00445 inline TooN::Matrix<num_parameters,2> get_parameter_derivs() const
00446 {
00447 TooN::Vector<2> mod_camframe = radial_distort(my_last_camframe);
00448
00449 TooN::Matrix<5, 2> result;
00450
00451 double xc = my_last_camframe[0];
00452 double yc = my_last_camframe[1];
00453 double r2 = xc*xc + yc*yc;
00454
00455 double f= my_camera_parameters[0];
00456 double a = my_camera_parameters[4];
00457
00458 double g = 1/sqrt(1 + a * r2);
00459 double g3= g*g*g;
00460
00461
00462 result[0][0] = mod_camframe[0];
00463 result[1][0] = 0;
00464 result[2][0] = 1;
00465 result[3][0] = 0;
00466 result[4][0] = - f * xc * r2 / 2 * g3;
00467
00468
00469
00470
00471 result[0][1] = mod_camframe[1];
00472 result[1][1] = 0;
00473 result[2][1] = 0;
00474 result[3][1] = 1;
00475 result[4][1] = - f * yc * r2 / 2 * g3;
00476
00477 return result;
00478 }
00479
00483 inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const
00484 {
00485 return get_parameter_derivs() * direction;
00486 }
00487
00491
00492
00495 inline TooN::Vector<num_parameters>& get_parameters()
00496 {
00497 my_camera_parameters[1] = 0;
00498 return my_camera_parameters;
00499 }
00500
00501 private:
00502 TooN::Vector<num_parameters> my_camera_parameters;
00503 mutable TooN::Vector<2> my_last_camframe;
00504 };
00505
00506
00507
00508 }
00509
00510
00511
00512
00514
00516
00517 void Camera::Linear::load(std::istream& is) {
00518 is >> my_camera_parameters;
00519 }
00520
00521 void Camera::Linear::save(std::ostream& os){
00522 os << my_camera_parameters;
00523 }
00524
00525 inline TooN::Vector<2> Camera::Linear::linearproject(const TooN::Vector<2>& camframe, double scale) const {
00526 return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00527 }
00528
00529 inline TooN::Vector<2> Camera::Linear::project(const TooN::Vector<2>& camframe) const {
00530 my_last_camframe = camframe;
00531 return TooN::Vector<2>(diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00532 }
00533
00534 inline TooN::Vector<2> Camera::Linear::unproject(const TooN::Vector<2>& imframe) const {
00535 my_last_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00536 my_last_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[1];
00537 return my_last_camframe;
00538 }
00539
00540 TooN::Matrix<2,2> Camera::Linear::get_derivative() const {
00541 TooN::Matrix<2,2> result;
00542 result(0,0) = my_camera_parameters[0];
00543 result(1,1) = my_camera_parameters[1];
00544 result(0,1) = result(1,0) = 0;
00545 return result;
00546 }
00547
00548 TooN::Matrix<Camera::Linear::num_parameters,2> Camera::Linear::get_parameter_derivs() const {
00549 TooN::Matrix<num_parameters,2> result;
00550 result(0,0) = my_last_camframe[0];
00551 result(0,1) = 0;
00552 result(1,0) = 0;
00553 result(1,1) = my_last_camframe[1];
00554 result(2,0) = 1;
00555 result(2,1) = 0;
00556 result(3,0) = 0;
00557 result(3,1) = 1;
00558 return result;
00559 }
00560
00561 TooN::Vector<Camera::Linear::num_parameters> Camera::Linear::get_parameter_derivs(const TooN::Vector<2>& direction) const {
00562 TooN::Vector<num_parameters> result;
00563 result[0] = my_last_camframe[0] * direction[0];
00564 result[1] = my_last_camframe[1] * direction[1];
00565 result[2] = direction[0];
00566 result[3] = direction[1];
00567
00568 return result;
00569 }
00570
00571 void Camera::Linear::update(const TooN::Vector<num_parameters>& updates){
00572 my_camera_parameters+=updates;
00573 }
00574
00575
00577
00579
00580 void Camera::Cubic::load(std::istream& is) {
00581 is >> my_camera_parameters;
00582 }
00583
00584 void Camera::Cubic::save(std::ostream& os){
00585 os << my_camera_parameters;
00586 }
00587
00588 inline TooN::Vector<2> Camera::Cubic::linearproject(const TooN::Vector<2>& camframe, double scale){
00589 return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00590 }
00591
00592 inline TooN::Vector<2> Camera::Cubic::project(const TooN::Vector<2>& camframe) const{
00593 my_last_camframe = camframe;
00594 TooN::Vector<2> mod_camframe = camframe * (1+SAT(my_camera_parameters[4]*(camframe*camframe)));
00595 return TooN::Vector<2>(diagmult(mod_camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00596 }
00597
00598 inline TooN::Vector<2> Camera::Cubic::unproject(const TooN::Vector<2>& imframe){
00599 TooN::Vector<2> mod_camframe;
00600 mod_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00601 mod_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[1];
00602
00603
00604 double scale = 1+my_camera_parameters[4]*(mod_camframe*mod_camframe);
00605
00606
00607 for(int i=0; i<3; i++){
00608 double error = my_camera_parameters[4]*(mod_camframe*mod_camframe) - scale*scale*(scale-1);
00609 double deriv = (3*scale -2)*scale;
00610 scale += error/deriv;
00611 }
00612 my_last_camframe = mod_camframe/scale;
00613
00614 return my_last_camframe;
00615 }
00616
00617 TooN::Matrix<2,2> Camera::Cubic::get_derivative(){
00618 TooN::Matrix<2,2> result;
00619 Identity(result,1+my_camera_parameters[4]*(my_last_camframe*my_last_camframe));
00620 result += (2*my_camera_parameters[4]*my_last_camframe.as_col()) * my_last_camframe.as_row();
00621 result[0] *= my_camera_parameters[0];
00622 result[1] *= my_camera_parameters[1];
00623 return result;
00624 }
00625
00626 TooN::Matrix<Camera::Cubic::num_parameters,2> Camera::Cubic::get_parameter_derivs() const {
00627 TooN::Vector<2> mod_camframe = my_last_camframe * (1+my_camera_parameters[4]*(my_last_camframe*my_last_camframe));
00628 TooN::Matrix<num_parameters,2> result;
00629 result(0,0) = mod_camframe[0]*my_camera_parameters[0];
00630 result(0,1) = 0;
00631 result(1,0) = 0;
00632 result(1,1) = mod_camframe[1]*my_camera_parameters[1];
00633 result(2,0) = 1*my_camera_parameters[0];
00634 result(2,1) = 0;
00635 result(3,0) = 0;
00636 result(3,1) = 1*my_camera_parameters[1];
00637 result[4] = diagmult(my_last_camframe,my_camera_parameters.slice<0,2>())*(my_last_camframe*my_last_camframe);
00638 return result;
00639 }
00640
00641 TooN::Vector<Camera::Cubic::num_parameters> Camera::Cubic::get_parameter_derivs(const TooN::Vector<2>& direction) const {
00642 TooN::Vector<2> mod_camframe = my_last_camframe * (1+my_camera_parameters[4]*(my_last_camframe*my_last_camframe));
00643 TooN::Vector<num_parameters> result;
00644 result[0] = mod_camframe[0] * direction[0] *my_camera_parameters[0];
00645 result[1] = mod_camframe[1] * direction[1] *my_camera_parameters[1];
00646 result[2] = direction[0] *my_camera_parameters[0];
00647 result[3] = direction[1] *my_camera_parameters[1];
00648 result[4] = (diagmult(my_last_camframe,my_camera_parameters.slice<0,2>())*direction)*(my_last_camframe*my_last_camframe);
00649 return result;
00650 }
00651
00652 void Camera::Cubic::update(const TooN::Vector<num_parameters>& updates){
00653 double fu=my_camera_parameters[0];
00654 double fv=my_camera_parameters[1];
00655 my_camera_parameters[0]+=fu*updates[0];
00656 my_camera_parameters[1]+=fv*updates[1];
00657 my_camera_parameters[2]+=fu*updates[2];
00658 my_camera_parameters[3]+=fv*updates[3];
00659 my_camera_parameters[4]+=updates[4];
00660
00661 }
00662
00664
00666
00667 void Camera::Quintic::load(std::istream& is) {
00668 is >> my_camera_parameters;
00669 }
00670
00671 void Camera::Quintic::save(std::ostream& os){
00672 os << my_camera_parameters;
00673 }
00674
00675 inline TooN::Vector<2> Camera::Quintic::linearproject(const TooN::Vector<2>& camframe, double scale) const {
00676 return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00677 }
00678
00679 inline TooN::Vector<2> Camera::Quintic::project(const TooN::Vector<2>& camframe) const {
00680 my_last_camframe = camframe;
00681 double sc = (camframe*camframe);
00682 TooN::Vector<2> mod_camframe = camframe * (1 + sc*(my_camera_parameters[4] + sc*my_camera_parameters[5]));
00683 return TooN::Vector<2>(diagmult(mod_camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00684 }
00685
00686 inline std::pair<TooN::Vector<2>, TooN::Matrix<2> > Camera::Quintic::project(const TooN::Vector<2>& camframe, const TooN::Matrix<2>& R) const
00687 {
00688 std::pair<TooN::Vector<2>, TooN::Matrix<2> > result;
00689 result.first = this->project(camframe);
00690 const TooN::Matrix<2> J = this->get_derivative();
00691 result.second = J * R * J.T();
00692 return result;
00693 }
00694
00695 inline TooN::Vector<2> Camera::Quintic::unproject(const TooN::Vector<2>& imframe) const {
00696 TooN::Vector<2> mod_camframe;
00697 mod_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00698 mod_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[1];
00699
00700
00701 double scale = mod_camframe*mod_camframe;
00702
00703
00704 for(int i=0; i<3; i++){
00705 double temp=1+scale*(my_camera_parameters[4]+my_camera_parameters[5]*scale);
00706 double error = mod_camframe*mod_camframe - scale*temp*temp;
00707 double deriv = temp*(temp+2*scale*(my_camera_parameters[4]+2*my_camera_parameters[5]*scale));
00708 scale += error/deriv;
00709 }
00710 my_last_camframe = mod_camframe/(1+scale*(my_camera_parameters[4]+my_camera_parameters[5]*scale));
00711
00712
00713
00714 return my_last_camframe;
00715 }
00716
00717 inline std::pair<TooN::Vector<2>, TooN::Matrix<2> > Camera::Quintic::unproject(const TooN::Vector<2>& imframe, const TooN::Matrix<2>& R) const
00718 {
00719 std::pair<TooN::Vector<2>, TooN::Matrix<2> > result;
00720 result.first = this->unproject(imframe);
00721 TooN::Matrix<2> J = get_derivative();
00722 double rdet = 1.0/ (J[0][0] * J[1][1] - J[0][1] * J[1][0]);
00723 TooN::Matrix<2> Jinv;
00724 Jinv[0][0] = rdet * J[1][1];
00725 Jinv[1][1] = rdet * J[0][0];
00726 Jinv[0][1] = -rdet * J[0][1];
00727 Jinv[1][0] = -rdet * J[1][0];
00728 result.second = Jinv * R * Jinv.T();
00729 return result;
00730 }
00731
00732
00733 TooN::Matrix<2,2> Camera::Quintic::get_derivative() const {
00734 TooN::Matrix<2,2> result;
00735 double temp1=my_last_camframe*my_last_camframe;
00736 double temp2=my_camera_parameters[5]*temp1;
00737 Identity(result,1+temp1*(my_camera_parameters[4]+temp2));
00738 result += (2*(my_camera_parameters[4]+2*temp2)*my_last_camframe.as_col()) * my_last_camframe.as_row();
00739 result[0] *= my_camera_parameters[0];
00740 result[1] *= my_camera_parameters[1];
00741 return result;
00742 }
00743
00744
00745
00746 TooN::Matrix<2,2> Camera::Quintic::get_inv_derivative() const {
00747 TooN::Matrix<2,2> result;
00748 double temp1=my_last_camframe*my_last_camframe;
00749 double temp2=my_camera_parameters[5]*temp1;
00750 double temp3=2.0*(my_camera_parameters[4]+2.0*temp2);
00751
00752 Identity(result,1+temp1*(my_camera_parameters[4]+temp2));
00753
00754 result[0][0] += my_last_camframe[1]*my_last_camframe[1]*temp3;
00755 result[0][1] =-(temp3*my_last_camframe[0]*my_last_camframe[1]);
00756
00757 result[1][1] += my_last_camframe[0]*my_last_camframe[0]*temp3;
00758 result[1][0] =-(temp3*my_last_camframe[0]*my_last_camframe[1]);
00759
00760 (result.T())[0] *= my_camera_parameters[1];
00761 (result.T())[1] *= my_camera_parameters[0];
00762
00763 result /= (result[0][0]*result[1][1] - result[1][0]*result[0][1]);
00764
00765 return result;
00766 }
00767
00768 TooN::Matrix<2,2> Camera::Quintic::get_inv_derivative(const TooN::Vector<2>& x) const
00769 {
00770
00771 TooN::Matrix<2,2> result;
00772 double temp1=x*x;
00773 double temp2=my_camera_parameters[5]*temp1;
00774 double temp3=2.0*(my_camera_parameters[4]+2.0*temp2);
00775
00776 Identity(result,1+temp1*(my_camera_parameters[4]+temp2));
00777
00778 result[0][0] += x[1]*x[1]*temp3;
00779 result[0][1] =-(temp3*x[0]*x[1]);
00780
00781 result[1][1] += x[0]*x[0]*temp3;
00782 result[1][0] =-(temp3*x[0]*x[1]);
00783
00784 (result.T())[0] *= my_camera_parameters[1];
00785 (result.T())[1] *= my_camera_parameters[0];
00786
00787 result /= (result[0][0]*result[1][1] - result[1][0]*result[0][1]);
00788
00789 return result;
00790
00791 }
00792
00793 TooN::Matrix<2,2> Camera::Quintic::get_derivative(const TooN::Vector<2>& x) const {
00794 TooN::Matrix<2,2> result;
00795 double temp1=x*x;
00796 double temp2=my_camera_parameters[5]*temp1;
00797 Identity(result,1+temp1*(my_camera_parameters[4]+temp2));
00798 result += (2*(my_camera_parameters[4]+2*temp2)*x.as_col()) * x.as_row();
00799 result[0] *= my_camera_parameters[0];
00800 result[1] *= my_camera_parameters[1];
00801 return result;
00802 }
00803
00804 TooN::Matrix<Camera::Quintic::num_parameters,2> Camera::Quintic::get_parameter_derivs() const {
00805 TooN::Matrix<num_parameters,2> result;
00806 double r2 = my_last_camframe * my_last_camframe;
00807 double r4 = r2 * r2;
00808 TooN::Vector<2> mod_camframe = my_last_camframe * (1+ r2 * (my_camera_parameters[4] + r2 * my_camera_parameters[5]));
00809
00810 result(0,0) = mod_camframe[0];
00811 result(1,0) = 0;
00812 result(2,0) = 1;
00813 result(3,0) = 0;
00814 result(4,0) = my_camera_parameters[0]*my_last_camframe[0]*r2;
00815 result(5,0) = my_camera_parameters[0]*my_last_camframe[0]*r4;
00816
00817 result(0,1) = 0;
00818 result(1,1) = mod_camframe[1];
00819 result(2,1) = 0;
00820 result(3,1) = 1;
00821 result(4,1) = my_camera_parameters[1]*my_last_camframe[1]*r2;
00822 result(5,1) = my_camera_parameters[1]*my_last_camframe[1]*r4;
00823
00824
00825 return result;
00826 }
00827
00828 TooN::Vector<Camera::Quintic::num_parameters> Camera::Quintic::get_parameter_derivs(const TooN::Vector<2>& direction) const {
00829
00830
00831
00832 return get_parameter_derivs() * direction;
00833 }
00834
00835 void Camera::Quintic::update(const TooN::Vector<num_parameters>& updates){
00836 double fu = my_camera_parameters[0];
00837 double fv = my_camera_parameters[1];
00838
00839 my_camera_parameters[0]+=updates[0]*fu;
00840 my_camera_parameters[1]+=updates[1]*fv;
00841 my_camera_parameters[2]+=updates[2]*fu;
00842 my_camera_parameters[3]+=updates[3]*fv;
00843 my_camera_parameters[4]+=updates[4];
00844 my_camera_parameters[5]+=updates[5];
00845 }
00846
00847 #endif