1 // This is core/vpgl/algo/vpgl_camera_convert.h 2 #ifndef vpgl_camera_convert_h_ 3 #define vpgl_camera_convert_h_ 4 //: 5 // \file 6 // \brief Several routines for converting camera types 7 // \author J.L. Mundy 8 // \date July 18, 2005 9 // 10 // Should template this class. 11 12 #include <vector> 13 #ifdef _MSC_VER 14 # include <vcl_msvc_warnings.h> 15 #endif 16 #include <vgl/vgl_fwd.h> 17 #include <vnl/vnl_fwd.h> 18 #include <vpgl/vpgl_calibration_matrix.h> 19 #include <vpgl/vpgl_perspective_camera.h> 20 #include <vpgl/vpgl_proj_camera.h> 21 #include <vpgl/vpgl_affine_camera.h> 22 #include <vpgl/vpgl_rational_camera.h> 23 #include <vpgl/vpgl_local_rational_camera.h> 24 #include <vpgl/vpgl_generic_camera.h> 25 #include <vgl/algo/vgl_h_matrix_3d.h> 26 27 #include <vil/vil_config.h> 28 #if HAS_GEOTIFF 29 #include <vpgl/file_formats/vpgl_geo_camera.h> 30 #endif 31 32 //: Basic least squares solution for a general projective camera given corresponding world and image points. 33 class vpgl_proj_camera_convert 34 { 35 public: 36 //:Find a projective camera that best approximates the rational camera at the world center (lon (deg), lat (deg), elev (meters) ) 37 static bool convert(vpgl_rational_camera<double> const& rat_cam, 38 vgl_point_3d<double> const& world_center, 39 vpgl_proj_camera<double>& camera); 40 41 //:An auxiliary matrix that transforms (normalizes) world points prior to projection by a projective camera. (lon, lat, elevation)->[-1, 1]. 42 static vgl_h_matrix_3d<double> 43 norm_trans(vpgl_rational_camera<double> const& rat_cam); 44 45 private: 46 //:default constructor (is private) 47 vpgl_proj_camera_convert() = delete; 48 }; 49 50 51 //:Various methods for computing a perspective camera 52 class vpgl_perspective_camera_convert 53 { 54 public: 55 56 //: Convert from a rational camera 57 // Put the resulting camera into camera, return true if successful. 58 // The approximation volume defines the region of space (lon (deg), lat (deg), elev (meters)) 59 // where the perspective approximation is valid. Norm trans is a pre-multiplication 60 // of the perspective camera to account for scaling the lon, lat and elevation 61 // to the range [-1, 1] 62 static bool convert( vpgl_rational_camera<double> const& rat_cam, 63 vgl_box_3d<double> const& approximation_volume, 64 vpgl_perspective_camera<double>& camera, 65 vgl_h_matrix_3d<double>& norm_trans); 66 67 //: Convert from rational camera using a local Euclidean coordinate system. 68 static bool convert_local( vpgl_rational_camera<double> const& rat_cam, 69 vgl_box_3d<double> const& approximation_volume, 70 vpgl_perspective_camera<double>& camera, 71 vgl_h_matrix_3d<double>& norm_trans); 72 73 private: 74 vpgl_perspective_camera_convert() = delete; 75 }; 76 77 //:Various methods for converting to a generic camera 78 class vpgl_generic_camera_convert 79 { 80 public: 81 82 //: Convert a local rational camera to a generic camera 83 static bool convert( vpgl_local_rational_camera<double> const& rat_cam, 84 int ni, int nj, 85 vpgl_generic_camera<double> & gen_cam, unsigned level = 0); 86 87 //: Convert a local rational camera to a generic camera, using user-specified z bounds 88 // Note that the z values are relative to the local coordinate system 89 static bool convert( vpgl_local_rational_camera<double> const& rat_cam, 90 int ni, int nj, 91 vpgl_generic_camera<double> & gen_cam, 92 double local_z_min, double local_z_max, unsigned level = 0); 93 static bool convert_bruteforce( vpgl_local_rational_camera<double> const& rat_cam, 94 int gni, int gnj, vpgl_generic_camera<double> & gen_cam, 95 double local_z_min, double local_z_max, unsigned level); 96 //: Convert a proj_camera to a generic camera 97 static bool convert( vpgl_proj_camera<double> const& prj_cam, 98 int ni, int nj, 99 vpgl_generic_camera<double> & gen_cam, unsigned level = 0); 100 101 //: Convert a perspective_camera to a generic camera 102 static bool convert( vpgl_perspective_camera<double> const& per_cam, 103 int ni, int nj, 104 vpgl_generic_camera<double> & gen_cam, unsigned level = 0); 105 #if 0 106 { 107 vpgl_perspective_camera<double> nc_cam(per_cam); 108 vpgl_proj_camera<double>* prj_cam_ptr = 109 dynamic_cast<vpgl_proj_camera<double>*>(&nc_cam); 110 if (!prj_cam_ptr) return false; 111 return convert(*prj_cam_ptr, ni, nj, gen_cam,level); 112 } 113 #endif 114 115 static bool convert_with_margin( vpgl_perspective_camera<double> const& per_cam, 116 int ni, int nj, 117 vpgl_generic_camera<double> & gen_cam, int margin, unsigned level = 0); 118 119 //: Convert an affine_camera to a generic camera 120 static bool convert( vpgl_affine_camera<double> const& aff_cam, 121 int ni, int nj, vpgl_generic_camera<double> & gen_cam, unsigned level = 0); 122 123 //::convert an abstract camera to generic camera 124 static bool convert( vpgl_camera_double_sptr const& camera, int ni, int nj, 125 vpgl_generic_camera<double> & gen_cam, unsigned level = 0); 126 127 #if HAS_GEOTIFF 128 //: Convert a geocam (transformtaion matrix read from a geotiff header + an lvcs) to a generic camera 129 static bool convert( vpgl_geo_camera& geocam, int ni, int nj, double height, 130 vpgl_generic_camera<double> & gen_cam, unsigned level = 0); 131 132 //: Convert a geocam (transformtaion matrix read from a geotiff header + an lvcs) to a generic camera using the specified ray direction (not necessarily nadir rays) 133 // basically creates a camera with parallel rays but the rays can be in any direction 134 static bool convert( vpgl_geo_camera& geocam, int ni, int nj, double height, vgl_vector_3d<double>& dir, 135 vpgl_generic_camera<double> & gen_cam, unsigned level = 0); 136 #endif 137 138 // === utility methods === 139 private: 140 //: interpolate rays to fill next higher resolution pyramid layer 141 static bool 142 upsample_rays(std::vector<vgl_ray_3d<double> > const& ray_nbrs, 143 vgl_ray_3d<double> const& ray, 144 std::vector<vgl_ray_3d<double> >& interp_rays); 145 //: interpolate a span of rays base on a linear interpolation. n_grid is the step distance from r1. r0 and r1 are one unit apart. 146 static vgl_ray_3d<double> interp_pair(vgl_ray_3d<double> const& r0, 147 vgl_ray_3d<double> const& r1, 148 double n_grid); 149 static bool pyramid_est(vpgl_local_rational_camera<double> const& rat_cam, 150 int ni, int nj,int offseti, int offsetj, 151 double local_z_min, double local_z_max, 152 int n_levels,std::vector<int> nr, std::vector<int> nc, 153 std::vector<unsigned int> scl,std::vector<vbl_array_2d<vgl_ray_3d<double> > > & ray_pyr ); 154 155 vpgl_generic_camera_convert() = delete; 156 }; 157 158 //:methods for computing to an affine camera 159 class vpgl_affine_camera_convert 160 { 161 public: 162 163 //: Convert from rational camera using a local Euclidean coordinate system. 164 static bool convert( vpgl_local_rational_camera<double> const& camera_in, 165 vgl_box_3d<double> const& region_of_interest, 166 vpgl_affine_camera<double>& camera_out, 167 unsigned int num_points=10000); 168 169 private: 170 vpgl_affine_camera_convert() = delete; 171 }; 172 173 #endif // vpgl_camera_convert_h_ 174