1 // This is core/vgl/algo/vgl_fit_cremona_2d.h 2 #ifndef vgl_compute_cremona_2d_h_ 3 #define vgl_compute_cremona_2d_h_ 4 //: 5 // \file 6 // \brief Fit a cremona transform in the plane given a set of corresponding points 7 // 8 // \verbatim 9 // Modifications 10 // Created November 22, 2019 - J.L. Mundy 11 // \endverbatim 12 // 13 // A cremona tranform is a generalization of the 2-d projective transformation 14 // where the map (X,Y) -> (x, y) in Euclidian coordinates is defined by ratios of polynomials. 15 // 16 // P(X, Y) R(X, Y) 17 // x = ------- y = ------ 18 // Q(X, Y) S(X, Y) 19 // 20 // P, Q, R, S are polynomials of degree deg. 21 // 22 // In the case where the highest degree is one, the Cremona transformation with 23 // a common denominator is equivalent to the projective transformation. 24 // 25 // Various constraints on the generality of the transformation are available: 26 // 27 // BI_RATIONAL - full generality 28 // COMMON_DENOMINATOR - the maps to x and to y have the same bi-rational denominator 29 // UNITY_DENOMINATOR - both denominators are 1 - so not a rational form (analogous to affine) 30 // 31 #include <iosfwd> 32 #include <vgl/algo/vgl_norm_trans_2d.h> 33 #include <vgl/vgl_homg_point_2d.h> 34 #ifdef _MSC_VER 35 # include <vcl_msvc_warnings.h> 36 #endif 37 #include <vnl/vnl_matrix.h> 38 #include <vnl/vnl_vector.h> 39 #include "vgl_cremona_trans_2d.h" 40 template <class T, size_t deg> 41 class vgl_compute_cremona_2d 42 { 43 public: 44 enum constraint_t {BI_RATIONAL, COMMON_DENOMINATOR, UNITY_DENOMINATOR, UNKNOWN}; 45 // Constructors/Initializers/Destructors------------------------------------- 46 vgl_compute_cremona_2d()47 vgl_compute_cremona_2d() : constr_type_(BI_RATIONAL) {} 48 ~vgl_compute_cremona_2d() = default; 49 ; 50 51 // Operations---------------------------------------------------------------- 52 53 bool compute_linear(std::vector<vgl_homg_point_2d<T>> const &from_pts, 54 std::vector<vgl_homg_point_2d<T>> const &to_pts, 55 constraint_t ctype = BI_RATIONAL); 56 bool project_linear(T X, T Y, T &x, T &y) const; linear_error()57 T linear_error() { return linear_error_; } 58 59 //: the cremona transformation produced by the linear solution linear_trans()60 vgl_cremona_trans_2d<T, deg> linear_trans() { 61 return vgl_cremona_trans_2d<T, deg>(tr_from_, tr_to_, linear_coeff_); 62 } 63 // internals linear_coeff()64 vnl_vector<T> linear_coeff() const {return linear_coeff_;} tr_from()65 vgl_norm_trans_2d<T> tr_from() const {return tr_from_;} tr_to()66 vgl_norm_trans_2d<T> tr_to() const {return tr_to_;} 67 68 protected : 69 bool normalize(); 70 bool compute_linear_solution_error(); 71 constraint_t constr_type_; 72 std::vector<vgl_homg_point_2d<T> > from_pts_; 73 std::vector<vgl_homg_point_2d<T> > to_pts_; 74 vgl_norm_trans_2d<T> tr_from_; 75 vgl_norm_trans_2d<T> tr_to_; 76 std::vector<vgl_homg_point_2d<T> > norm_from_pts_; 77 std::vector<vgl_homg_point_2d<T> > norm_to_pts_; 78 T linear_error_; 79 vnl_vector<T> linear_coeff_; 80 bool linear_solved_{false}; 81 }; 82 83 #define VGL_COMPUTE_CREMONA_2D_INSTANTIATE(T, deg) extern "please include vgl/algo/vgl_compute_cremona_2d.hxx first" 84 85 #endif // vgl_compute_cremona_2d_h_ 86