1 // This is brl/bseg/bvpl/kernels/bvpl_kernel_factory.h
2 #ifndef bvpl_kernel_base_h
3 #define bvpl_kernel_base_h
4 //:
5 // \file
6 // \brief A base class for 3D kernel. The kernel is fully described by a rotation axis and an angle
7 // The children of this classes must create a kernel on a "canonical form" i.e. with a default
8 // axis of rotation and a complementary vector here called canonical_paralle_axis_.
9 //
10 // If this two vector are seen as points on the unit sphere, then they lie on the same
11 // parallel (constant polar angle). These vectors determine the zero rotation position as follows:
12 // * The rotation that transforms the canonical_rotation_axis to a new specified rotation axis,
13 // is applied to the kernel (Lets call such rotation R).
14 // * The kernel is rotate around its new rotation such that R*canonical_parallel_axis achieves
15 // the same polar angle as the new rotation axis
16 //
17 // Usage:
18 // - The user can create a kernel in its canonical form through children constructors
19 // - Then, the user call set_rotation_axis(), set_angle() and create() and if one wishes to use
20 // another angle with the same axis, it suffices to call set_angle(angle) and create().
21 // This will save computation time since the rotation_axis has already been set.
22 // - Alternatively, the user can call create(axis, angle). This transforms the canonical kernel according
23 // to new parameters
24 //
25 // \author Isabel Restrepo mir@lems.brown.edu
26 // \date May 29, 2009
27 //
28 // \verbatim
29 // Modifications
30 // <none yet>
31 // \endverbatim
32
33 #include <iostream>
34 #include <map>
35 #include <utility>
36 #include "bvpl_kernel.h"
37 #include "bvpl_kernel_iterator.h"
38 #ifdef _MSC_VER
39 # include <vcl_msvc_warnings.h>
40 #endif
41 #include <vnl/vnl_float_3.h>
42 #include <vgl/algo/vgl_rotation_3d.h>
43 #include <vbl/vbl_ref_count.h>
44
45 class bvpl_kernel_factory;
46 typedef vbl_smart_ptr<bvpl_kernel_factory> bvpl_kernel_factory_sptr;
47
48
49 //: A factory of bvpl_kernels
50 class bvpl_kernel_factory: public vbl_ref_count
51 {
52 public:
53 //Default constructor. Initialize constant member variables
bvpl_kernel_factory()54 bvpl_kernel_factory(): canonical_rotation_axis_(vnl_float_3(1,0,0)), canonical_parallel_axis_(vnl_float_3(0,1,0)){}
55
56 ~bvpl_kernel_factory() override = default;
57
58 //: Returns a kernel described by class variables rotation_axis_, \p angle_
59 // The user can modified the axis and angle using set_rotation_axis() and set_angle()
60 bvpl_kernel create();
61
62 //: Returns a kernel described by inputs; rotation_axis and angle
63 bvpl_kernel create(vnl_float_3 rotation_axis, float angle);
64
65 //: Sets the rotation axis of this kernel
66 void set_rotation_axis(vnl_float_3 rotation_axis);
67
68 //: Sets rotation angle of this kernel
set_angle(float angle)69 void set_angle(float angle) { angle_ =angle; }
70
71 //: Returns the current alignment axis
axis()72 vnl_float_3 axis() const { return rotation_axis_; }
73
74 //: Return current rotation angle around axis()
angle()75 float angle() const { return angle_; }
76
77 //: Returns angular resolution around rotation axis
angular_resolution()78 float angular_resolution() const { return angular_resolution_; }
79
80 //: Return x-y-z maximum coordinate values
max_point()81 vgl_point_3d<int> max_point() const { return max_point_; }
82
83 //: Return x-y-z minimum coordinate values
min_point()84 vgl_point_3d<int> min_point() const { return min_point_; }
85
86 //: returns the rectangular dimensions around the kernel center
87 vgl_vector_3d<int> dim();
88
89 //: Creates a vector of kernels as specified by func
90 template <class F>
91 bvpl_kernel_vector_sptr create_kernel_vector(F func);
92
93 //: Return an xml element
xml_element()94 virtual bxml_data_sptr xml_element()
95 {
96 std::cout << "Calling xml write in parent class, xml data will be NULL" << std::endl;
97 return nullptr;
98 }
99
self()100 virtual bvpl_kernel_factory_sptr self(){return this;}
101
102 protected:
103
104 typedef std::vector<std::pair<vgl_point_3d<float>, bvpl_kernel_dispatch> > kernel_type;
105
106 //: The map of 3d positions and their symbols. This kernel has an axis of rotation, but it is always on zero-rotation position
107 std::vector<std::pair<vgl_point_3d<float>, bvpl_kernel_dispatch> > kernel_;
108
109 //: The map of 3d positions and their symbols in their canonical form (As specified by children)
110 std::vector<std::pair<vgl_point_3d<float>, bvpl_kernel_dispatch> > canonical_kernel_;
111
112 //: The rotation axis for canonical edge
113 const vnl_float_3 canonical_rotation_axis_;//(1,0,0);
114
115 //: Rotation axis of kernel_
116 vnl_float_3 rotation_axis_;
117
118 vnl_float_3 parallel_axis_;
119
120 // parallel_axis_ define a coordinate system for each kernel.
121 // The vector (parallel_axis_ - rotation_axis_) defines the direction of the minor axis of the kernel
122 // The zero-rotation for any rotation axis is that for which parallel_axis_ and rotation_axis_ have constant polar angle
123 const vnl_float_3 canonical_parallel_axis_;//(0,1,0);
124
125 //: Amounts rotation around rotation_axis_
126 float angle_;
127
128 //: Dimensions of the 3D grid
129 vgl_point_3d<int> max_point_;
130
131 //: Dimensions of the 3D grid
132 vgl_point_3d<int> min_point_;
133
134 //: Angular resolutions
135 float angular_resolution_;
136
137 //: Length of a voxel in global coordinates
138 double voxel_length_;
139
140 //: Name that identifies the kernel e.g "edge3d", "gauss"
141 std::string factory_name_;
142
143 //: Creates canonical(default) kernel.
144 // It is described by a canonical axis of rotation and a canonical parallel axis
145 // This is the main function implemented by the children.
146 virtual void create_canonical()=0;
147
148 //: Rounds coordinates of kernel to the nearest integer
149 bvpl_kernel_iterator interpolate(kernel_type const& kernel);
150
151 //: Rotates "class-kernel_" around "class-rotation_axis_" by an "angle"
152 kernel_type rotate(float angle);
153
154 //: Rotates "class-kernel_" using the given rotation matrix
155 kernel_type rotate(const vgl_rotation_3d<float>& R);
156 };
157
158
159 template <class F>
create_kernel_vector(F func)160 bvpl_kernel_vector_sptr bvpl_kernel_factory::create_kernel_vector(F func)
161 {
162 std::vector<vnl_float_3> axes=func.get_axes();
163 std::vector<float> angles = func.get_angles();
164
165 bvpl_kernel_vector_sptr vec_kernel=new bvpl_kernel_vector();
166
167 for (unsigned i=0;i<axes.size();i++)
168 {
169 this->set_rotation_axis(axes[i]);
170 this->set_angle(angles[i]);
171 vec_kernel->kernels_.push_back(new bvpl_kernel(this->create()));
172 }
173 return vec_kernel;
174 }
175
176 #endif
177