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