1 // This is brl/bbas/vsph/vsph_camera_bounds.h 2 #ifndef vsph_camera_bounds_h_ 3 #define vsph_camera_bounds_h_ 4 //: 5 // \file 6 // \brief Methods for computing various bounds on cameras and scenes 7 // \author J. L. Mundy 8 // \date September 18, 2010 9 10 #include <iostream> 11 #include <vector> 12 #ifdef _MSC_VER 13 # include <vcl_msvc_warnings.h> 14 #endif 15 #include <vgl/vgl_point_3d.h> 16 #include <vgl/vgl_vector_3d.h> 17 #include <vgl/vgl_ray_3d.h> 18 #include <vgl/vgl_box_3d.h> 19 #include <vgl/algo/vgl_rotation_3d.h> 20 #include <vpgl/vpgl_generic_camera.h> 21 #include <vpgl/vpgl_perspective_camera.h> 22 23 class vsph_camera_bounds 24 { 25 public: 26 //: the solid angle for a pixel. 27 // Applies only to perspective camera. 28 // Cone is tangent to pixel. 29 // Angles in radians and steradians 30 static void pixel_solid_angle(vpgl_perspective_camera<double> const& cam, 31 unsigned u, unsigned v, 32 vgl_ray_3d<double>& cone_axis, 33 double& cone_half_angle, 34 double& solid_angle); 35 36 37 //: the solid angle (and cone half angle) for the pixel at the principal point. 38 // Applies only to a perspective camera. 39 // Cone is tangent to the pixel. 40 // Angles in radians and steradians 41 static void pixel_solid_angle(vpgl_perspective_camera<double> const& cam, 42 double& cone_half_angle, 43 double& solid_angle); 44 45 //: the solid angle for an image. 46 // Applies only to perspective camera. 47 // The cone axis passes through principal point, i.e. principal ray. 48 // The cone is tangent to the square defined by the image diagonal. 49 // Angles in radians and steradians 50 static void image_solid_angle(vpgl_perspective_camera<double> const& cam, 51 vgl_ray_3d<double>& cone_axis, 52 double& cone_half_angle, 53 double& solid_angle); 54 55 56 //: the solid angle for an image. 57 // Applies only to perspective camera. 58 // The cone axis passes through principal point, i.e. principal ray. 59 // The cone is tangent to the square defined by the image diagonal. 60 // Code axis is not returned. 61 // Angles in radians and steradians 62 static void image_solid_angle(vpgl_perspective_camera<double> const& cam, 63 double& cone_half_angle, 64 double& solid_angle); 65 //: the solid angle for a scene bounding box. 66 // The cone is tangent to the 3-d scene box. 67 // Angles in radians and steradians 68 static bool box_solid_angle(vpgl_perspective_camera<double> const& cam, 69 vgl_box_3d<double> const& box, 70 vgl_ray_3d<double>& cone_axis, 71 double& cone_half_angle, 72 double& solid_angle); 73 74 //: The angular interval of the rotation about the principal axis that bounds a pixel at the smallest image radius, i.e., 1/2 the smallest image dimension. 75 // The angular wedge is tangent to the pixel 76 static double rotation_angle_interval(vpgl_perspective_camera<double> const& cam); 77 78 //: conversion between solid angle and cone half angle 79 static double solid_angle(double cone_half_angle); 80 81 //: conversion between solid angle and cone half angle 82 static double cone_half_angle(double solid_angle); 83 84 //: The relative rotation and translation between camera \p c0 and \p c1 85 // In more detail, the relative transformation aligns c1 with the 86 // identity camera 87 static void relative_transf(vpgl_perspective_camera<double> const& c0, 88 vpgl_perspective_camera<double> const& c1, 89 vgl_rotation_3d<double>& rel_rot, 90 vgl_vector_3d<double>& rel_trans); 91 92 //: For cameras with nearly parallel rays a pixel backprojects to a cylinder. The cylinder circumscribes the pixel. Returns false if (u, v) are out of bounds. 93 static bool pixel_cylinder(vpgl_generic_camera<double> const& cam, 94 unsigned u, unsigned v, 95 vgl_ray_3d<double>& cylinder_axis, 96 double& cylinder_radius); 97 98 //: The (world coordinates) 2d Bounding Box for a camera at a specific Z plane 99 // \returns false if plane and camera do not intersect 100 static bool planar_bounding_box(vpgl_perspective_camera<double> const& c, 101 vgl_box_2d<double>& bbox, 102 double z_plane=0.0); 103 104 //: The union of the planar bounding boxes at specific z plane for each camera passed in 105 static bool planar_bounding_box(std::vector<vpgl_perspective_camera<double> > const& cams, 106 vgl_box_2d<double>& bbox, 107 double z_plane=0.0); 108 109 private: 110 //: constructor private - class contains static methods only 111 vsph_camera_bounds() = delete; 112 //: destructor private - class contains static methods only 113 ~vsph_camera_bounds() = delete; 114 }; 115 116 //: scan the principal ray over a cone defined by the half apex angle. 117 // It is assumed the cone axis is the positive z direction. 118 // Returns a 3-d rotation from the positive z direction to the current 119 // iterator rotation state. The cone is scanned in uniform steps 120 // defined by the increment. The actual number of samples is returned 121 // by n_samples. The input is the goal number of samples. 122 class principal_ray_scan 123 { 124 public: 125 principal_ray_scan(double cone_half_angle, unsigned& n_samples); 126 ~principal_ray_scan() = default; 127 //: number of scan states n_states()128 unsigned n_states() const {return theta_.size();} 129 //: reset the scan state 130 void reset(); 131 //:the next scan state. Returns false if done 132 bool next(); 133 //: the camera rotation corresponding to the current state of the principal ray. 134 // \p alpha is an additional rotation about the principal ray, $-\pi<\alpha<=\pi$, default 0. 135 vgl_rotation_3d<double> rot(double alpha = 0.0) const {return rot(index_, alpha);} 136 //: rotation for a given scan index 137 vgl_rotation_3d<double> rot(unsigned i, double alpha = 0.0) const; 138 //: spherical elevation angle for current state theta()139 double theta() const {return theta_[index_];} 140 //: spherical elevation angle for a given scan index theta(unsigned i)141 double theta(unsigned i) const {return theta_[i];} 142 //: spherical azimuth angle for current state phi()143 double phi() const {return phi_[index_];} 144 //: spherical azimuth angle for a given scan index phi(unsigned i)145 double phi(unsigned i) const {return phi_[i];} 146 //: point on the unit sphere for current scan state pt_on_unit_sphere()147 vgl_point_3d<double> pt_on_unit_sphere() const {return pt_on_unit_sphere(index_);} 148 //: point on the unit sphere for a given scan index 149 vgl_point_3d<double> pt_on_unit_sphere(unsigned i) const; 150 151 private: 152 principal_ray_scan() = default; 153 int index_; 154 std::vector<double> theta_; 155 std::vector<double> phi_; 156 }; 157 158 #endif // vsph_camera_bounds_h_ 159