summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/geometry/point_transforms_abstract.h
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/geometry/point_transforms_abstract.h')
-rw-r--r--ml/dlib/dlib/geometry/point_transforms_abstract.h797
1 files changed, 797 insertions, 0 deletions
diff --git a/ml/dlib/dlib/geometry/point_transforms_abstract.h b/ml/dlib/dlib/geometry/point_transforms_abstract.h
new file mode 100644
index 000000000..492ae745c
--- /dev/null
+++ b/ml/dlib/dlib/geometry/point_transforms_abstract.h
@@ -0,0 +1,797 @@
+// Copyright (C) 2003 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#undef DLIB_POINT_TrANSFORMS_ABSTRACT_Hh_
+#ifdef DLIB_POINT_TrANSFORMS_ABSTRACT_Hh_
+
+#include "../matrix/matrix_abstract.h"
+#include "vector_abstract.h"
+#include "rectangle_abstract.h"
+#include "drectangle_abstract.h"
+#include <vector>
+
+namespace dlib
+{
+
+// ----------------------------------------------------------------------------------------
+
+ class point_transform_affine
+ {
+ /*!
+ WHAT THIS OBJECT REPRESENTS
+ This is an object that takes 2D points or vectors and
+ applies an affine transformation to them.
+
+ THREAD SAFETY
+ It is safe for multiple threads to make concurrent accesses to this object
+ without synchronization.
+ !*/
+ public:
+
+ point_transform_affine (
+ );
+ /*!
+ ensures
+ - This object will perform the identity transform. That is, given a point
+ as input it will return the same point as output.
+ !*/
+
+ point_transform_affine (
+ const matrix<double,2,2>& m,
+ const dlib::vector<double,2>& b
+ );
+ /*!
+ ensures
+ - #get_m() == m
+ - #get_b() == b
+ - When (*this)(p) is invoked it will return a point P such that:
+ - P == m*p + b
+ !*/
+
+ const dlib::vector<double,2> operator() (
+ const dlib::vector<double,2>& p
+ ) const;
+ /*!
+ ensures
+ - applies the affine transformation defined by this object's constructor
+ to p and returns the result.
+ !*/
+
+ const matrix<double,2,2>& get_m(
+ ) const;
+ /*!
+ ensures
+ - returns the transformation matrix used by this object.
+ !*/
+
+ const dlib::vector<double,2>& get_b(
+ ) const;
+ /*!
+ ensures
+ - returns the offset vector used by this object.
+ !*/
+
+ };
+
+ void serialize (const point_transform_affine& item, std::ostream& out);
+ void deserialize (point_transform_affine& item, std::istream& in);
+ /*!
+ provides serialization support
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ point_transform_affine operator* (
+ const point_transform_affine& lhs,
+ const point_transform_affine& rhs
+ );
+ /*!
+ ensures
+ - returns a transformation TFORM(x) that is equivalent to lhs(rhs(x)). That
+ is, for all valid x: TFORM(x) == lhs(rhs(x)).
+ !*/
+
+ // ----------------------------------------------------------------------------------------
+
+ point_transform_affine inv (
+ const point_transform_affine& trans
+ );
+ /*!
+ ensures
+ - If trans is an invertible transformation then this function returns a new
+ transformation that is the inverse of trans.
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ template <typename T>
+ point_transform_affine find_affine_transform (
+ const std::vector<dlib::vector<T,2> >& from_points,
+ const std::vector<dlib::vector<T,2> >& to_points
+ );
+ /*!
+ requires
+ - from_points.size() == to_points.size()
+ - from_points.size() >= 3
+ ensures
+ - returns a point_transform_affine object, T, such that for all valid i:
+ length(T(from_points[i]) - to_points[i])
+ is minimized as often as possible. That is, this function finds the affine
+ transform that maps points in from_points to points in to_points. If no
+ affine transform exists which performs this mapping exactly then the one
+ which minimizes the mean squared error is selected. Additionally, if many
+ equally good transformations exist, then the transformation with the smallest
+ squared parameters is selected (i.e. if you wrote the transformation as a
+ matrix then we say we select the transform with minimum Frobenius norm among
+ all possible solutions).
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ template <typename T>
+ point_transform_affine find_similarity_transform (
+ const std::vector<dlib::vector<T,2> >& from_points,
+ const std::vector<dlib::vector<T,2> >& to_points
+ );
+ /*!
+ requires
+ - from_points.size() == to_points.size()
+ - from_points.size() >= 2
+ ensures
+ - This function is just like find_affine_transform() except it finds the best
+ similarity transform instead of a full affine transform. This means that it
+ optimizes over only the space of rotations, scale changes, and translations.
+ So for example, if you mapped the 3 vertices of a triangle through a
+ similarity transform then the output would still be the same triangle.
+ However, the triangle itself may be larger or smaller, rotated, or at a
+ different location in the coordinate system. This is not the case for a
+ general affine transform which can stretch points in ways that cause, for
+ example, an equilateral triangle to turn into an isosceles triangle.
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ class rectangle_transform
+ {
+ /*!
+ WHAT THIS OBJECT REPRESENTS
+ This object is just a point_transform_affine wrapped up so that it can
+ transform rectangle objects. It will take a rectangle and transform it
+ according to an affine transformation.
+
+ THREAD SAFETY
+ It is safe for multiple threads to make concurrent accesses to this object
+ without synchronization.
+ !*/
+ public:
+
+ rectangle_transform (
+ );
+ /*!
+ ensures
+ - This object will perform the identity transform. That is, given a rectangle
+ as input it will return the same rectangle as output.
+ !*/
+
+ rectangle_transform (
+ const point_transform_affine& tform
+ );
+ /*!
+ ensures
+ - #get_tform() == tform
+ !*/
+
+ drectangle operator() (
+ const drectangle& r
+ ) const;
+ /*!
+ ensures
+ - Applies the transformation get_tform() to r and returns the resulting
+ rectangle. If the transformation doesn't have any rotation then the
+ transformation simply maps the corners of the rectangle according to
+ get_tform() and returns the exact result. However, since
+ dlib::drectangle can't represent rotated rectangles, if there is any
+ rotation in the affine transform we will attempt to produce the most
+ faithful possible outputs by ensuring the output rectangle has the
+ correct center point and that its area and aspect ratio match the correct
+ rotated rectangle's as much as possible.
+ !*/
+
+ rectangle operator() (
+ const rectangle& r
+ ) const;
+ /*!
+ ensures
+ - returns (*this)(drectangle(r))
+ !*/
+
+ const point_transform_affine& get_tform(
+ ) const;
+ /*!
+ ensures
+ - returns the affine transformation this object uses to transform rectangles.
+ !*/
+
+ };
+
+ void serialize (const rectangle_transform& item, std::ostream& out);
+ void deserialize (rectangle_transform& item, std::istream& in);
+ /*!
+ provides serialization support
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ class point_transform_projective
+ {
+ /*!
+ WHAT THIS OBJECT REPRESENTS
+ This is an object that takes 2D points or vectors and
+ applies a projective transformation to them.
+
+ THREAD SAFETY
+ It is safe for multiple threads to make concurrent accesses to this object
+ without synchronization.
+ !*/
+
+ public:
+
+ point_transform_projective (
+ );
+ /*!
+ ensures
+ - This object will perform the identity transform. That is, given a point
+ as input it will return the same point as output.
+ !*/
+
+ point_transform_projective (
+ const matrix<double,3,3>& m
+ );
+ /*!
+ ensures
+ - #get_m() == m
+ !*/
+
+ point_transform_projective (
+ const point_transform_affine& tran
+ );
+ /*!
+ ensures
+ - This object will perform exactly the same transformation as the given
+ affine transform.
+ !*/
+
+ const dlib::vector<double,2> operator() (
+ const dlib::vector<double,2>& p
+ ) const;
+ /*!
+ ensures
+ - Applies the projective transformation defined by this object's constructor
+ to p and returns the result. To define this precisely:
+ - let p_h == the point p in homogeneous coordinates. That is:
+ - p_h.x() == p.x()
+ - p_h.y() == p.y()
+ - p_h.z() == 1
+ - let x == get_m()*p_h
+ - Then this function returns the value x/x.z()
+ !*/
+
+ const matrix<double,3,3>& get_m(
+ ) const;
+ /*!
+ ensures
+ - returns the transformation matrix used by this object.
+ !*/
+
+ };
+
+ void serialize (const point_transform_projective& item, std::ostream& out);
+ void deserialize (point_transform_projective& item, std::istream& in);
+ /*!
+ provides serialization support
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ point_transform_projective operator* (
+ const point_transform_projective& lhs,
+ const point_transform_projective& rhs
+ );
+ /*!
+ ensures
+ - returns a transformation TFORM(x) that is equivalent to lhs(rhs(x)). That
+ is, for all valid x: TFORM(x) == lhs(rhs(x)).
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ point_transform_projective inv (
+ const point_transform_projective& trans
+ );
+ /*!
+ ensures
+ - If trans is an invertible transformation then this function returns a new
+ transformation that is the inverse of trans.
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ point_transform_projective find_projective_transform (
+ const std::vector<dlib::vector<double,2> >& from_points,
+ const std::vector<dlib::vector<double,2> >& to_points
+ );
+ /*!
+ requires
+ - from_points.size() == to_points.size()
+ - from_points.size() >= 4
+ ensures
+ - returns a point_transform_projective object, T, such that for all valid i:
+ length(T(from_points[i]) - to_points[i])
+ is minimized as often as possible. That is, this function finds the projective
+ transform that maps points in from_points to points in to_points. If no
+ projective transform exists which performs this mapping exactly then the one
+ which minimizes the mean squared error is selected.
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ class point_transform
+ {
+ /*!
+ WHAT THIS OBJECT REPRESENTS
+ This is an object that takes 2D points or vectors and
+ rotates them around the origin by a given angle and then
+ translates them.
+
+ THREAD SAFETY
+ It is safe for multiple threads to make concurrent accesses to this object
+ without synchronization.
+ !*/
+ public:
+
+ point_transform (
+ );
+ /*!
+ ensures
+ - This object will perform the identity transform. That is, given a point
+ as input it will return the same point as output.
+ !*/
+
+ point_transform (
+ const double& angle,
+ const dlib::vector<double,2>& translate
+ )
+ /*!
+ ensures
+ - When (*this)(p) is invoked it will return a point P such that:
+ - P is the point p rotated counter-clockwise around the origin
+ angle radians and then shifted by having translate added to it.
+ (Note that this is counter clockwise with respect to the normal
+ coordinate system with positive y going up and positive x going
+ to the right)
+ !*/
+
+ template <typename T>
+ const dlib::vector<T,2> operator() (
+ const dlib::vector<T,2>& p
+ ) const;
+ /*!
+ ensures
+ - rotates p, then translates it and returns the result. The output
+ of this function is therefore equal to get_m()*p + get_b().
+ !*/
+
+ const matrix<double,2,2> get_m(
+ ) const;
+ /*!
+ ensures
+ - returns the transformation matrix used by this object.
+ !*/
+
+ const dlib::vector<double,2> get_b(
+ ) const;
+ /*!
+ ensures
+ - returns the offset vector used by this object.
+ !*/
+
+ };
+
+ void serialize (const point_transform& item, std::ostream& out);
+ void deserialize (point_transform& item, std::istream& in);
+ /*!
+ provides serialization support
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ class point_rotator
+ {
+ /*!
+ WHAT THIS OBJECT REPRESENTS
+ This is an object that takes 2D points or vectors and
+ rotates them around the origin by a given angle.
+
+ THREAD SAFETY
+ It is safe for multiple threads to make concurrent accesses to this object
+ without synchronization.
+ !*/
+ public:
+
+ point_rotator (
+ );
+ /*!
+ ensures
+ - This object will perform the identity transform. That is, given a point
+ as input it will return the same point as output.
+ !*/
+
+ point_rotator (
+ const double& angle
+ );
+ /*!
+ ensures
+ - When (*this)(p) is invoked it will return a point P such that:
+ - P is the point p rotated counter-clockwise around the origin
+ angle radians.
+ (Note that this is counter clockwise with respect to the normal
+ coordinate system with positive y going up and positive x going
+ to the right)
+ !*/
+
+ template <typename T>
+ const dlib::vector<T,2> operator() (
+ const dlib::vector<T,2>& p
+ ) const;
+ /*!
+ ensures
+ - rotates p and returns the result. The output of this function is
+ therefore equal to get_m()*p.
+ !*/
+
+ const matrix<double,2,2> get_m(
+ ) const;
+ /*!
+ ensures
+ - returns the transformation matrix used by this object.
+ !*/
+ };
+
+ void serialize (const point_rotator& item, std::ostream& out);
+ void deserialize (point_rotator& item, std::istream& in);
+ /*!
+ provides serialization support
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ template <typename T>
+ const dlib::vector<T,2> rotate_point (
+ const dlib::vector<T,2> center,
+ const dlib::vector<T,2> p,
+ double angle
+ );
+ /*!
+ ensures
+ - returns a point P such that:
+ - P is the point p rotated counter-clockwise around the given
+ center point by angle radians.
+ (Note that this is counter clockwise with respect to the normal
+ coordinate system with positive y going up and positive x going
+ to the right)
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ matrix<double,2,2> rotation_matrix (
+ double angle
+ );
+ /*!
+ ensures
+ - returns a rotation matrix which rotates points around the origin in a
+ counter-clockwise direction by angle radians.
+ (Note that this is counter clockwise with respect to the normal
+ coordinate system with positive y going up and positive x going
+ to the right)
+ Or in other words, this function returns a matrix M such that, given a
+ point P, M*P gives a point which is P rotated by angle radians around
+ the origin in a counter-clockwise direction.
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ class point_transform_affine3d
+ {
+ /*!
+ WHAT THIS OBJECT REPRESENTS
+ This is an object that takes 3D points or vectors and
+ applies an affine transformation to them.
+
+ THREAD SAFETY
+ It is safe for multiple threads to make concurrent accesses to this object
+ without synchronization.
+ !*/
+ public:
+
+ point_transform_affine3d (
+ );
+ /*!
+ ensures
+ - This object will perform the identity transform. That is, given a point
+ as input it will return the same point as output.
+ !*/
+
+ point_transform_affine3d (
+ const matrix<double,3,3>& m,
+ const dlib::vector<double,3>& b
+ );
+ /*!
+ ensures
+ - #get_m() == m
+ - #get_b() == b
+ - When (*this)(p) is invoked it will return a point P such that:
+ - P == m*p + b
+ !*/
+
+ const dlib::vector<double,3> operator() (
+ const dlib::vector<double,3>& p
+ ) const;
+ /*!
+ ensures
+ - applies the affine transformation defined by this object's constructor
+ to p and returns the result.
+ !*/
+
+ const matrix<double,3,3>& get_m(
+ ) const;
+ /*!
+ ensures
+ - returns the transformation matrix used by this object.
+ !*/
+
+ const dlib::vector<double,3>& get_b(
+ ) const;
+ /*!
+ ensures
+ - returns the offset vector used by this object.
+ !*/
+
+ };
+
+ void serialize (const point_transform_affine3d& item, std::ostream& out);
+ void deserialize (point_transform_affine3d& item, std::istream& in);
+ /*!
+ provides serialization support
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ point_transform_affine3d operator* (
+ const point_transform_affine3d& lhs,
+ const point_transform_affine3d& rhs
+ );
+ /*!
+ ensures
+ - returns a transformation TFORM(x) that is equivalent to lhs(rhs(x)). That
+ is, for all valid x: TFORM(x) == lhs(rhs(x)).
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ point_transform_affine3d operator* (
+ const point_transform_affine3d& lhs,
+ const point_transform_affine& rhs
+ );
+ /*!
+ ensures
+ - returns a transformation TFORM(x) that is equivalent to lhs(rhs(x)). That
+ is, for all valid x: TFORM(x) == lhs(rhs(x)).
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ point_transform_affine3d inv (
+ const point_transform_affine3d& trans
+ );
+ /*!
+ ensures
+ - If trans is an invertible transformation then this function returns a new
+ transformation that is the inverse of trans.
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ point_transform_affine3d rotate_around_x (
+ double angle
+ );
+ /*!
+ ensures
+ - Returns a transformation that rotates a point around the x axis in a
+ counter-clockwise direction by angle radians. That is, the rotation appears
+ counter-clockwise when the x axis points toward the observer, the coordinate
+ system is right-handed, and the angle is positive.
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ point_transform_affine3d rotate_around_y (
+ double angle
+ );
+ /*!
+ ensures
+ - Returns a transformation that rotates a point around the y axis in a
+ counter-clockwise direction by angle radians. That is, the rotation appears
+ counter-clockwise when the y axis points toward the observer, the coordinate
+ system is right-handed, and the angle is positive.
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ point_transform_affine3d rotate_around_z (
+ double angle
+ );
+ /*!
+ ensures
+ - Returns a transformation that rotates a point around the z axis in a
+ counter-clockwise direction by angle radians. That is, the rotation appears
+ counter-clockwise when the z axis points toward the observer, the coordinate
+ system is right-handed, and the angle is positive.
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ point_transform_affine3d translate_point (
+ const vector<double,3>& delta
+ );
+ /*!
+ ensures
+ - returns a transformation that simply translates points by adding delta to
+ them. That is, this function returns:
+ point_transform_affine3d(identity_matrix<double>(3),delta);
+ !*/
+
+ point_transform_affine3d translate_point (
+ double x,
+ double y,
+ double z
+ );
+ /*!
+ ensures
+ - returns translate_point(vector<double>(x,y,z))
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+ class camera_transform
+ {
+ /*!
+ WHAT THIS OBJECT REPRESENTS
+ This object maps 3D points into the image plane of a camera. Therefore,
+ you can use it to compute 2D representations of 3D data from the point of
+ view of some camera in 3D space.
+
+ THREAD SAFETY
+ It is safe for multiple threads to make concurrent accesses to this object
+ without synchronization.
+ !*/
+
+ public:
+
+ camera_transform (
+ );
+ /*!
+ ensures
+ - #get_camera_pos() == vector<double>(1,1,1)
+ - #get_camera_looking_at() == vector<double>(0,0,0)
+ - #get_camera_up_direction() == vector<double>(0,0,1)
+ - #get_camera_field_of_view() == 90
+ - #get_num_pixels() == 1
+ !*/
+
+ camera_transform (
+ const vector<double>& camera_pos,
+ const vector<double>& camera_looking_at,
+ const vector<double>& camera_up_direction,
+ const double camera_field_of_view,
+ const unsigned long num_pixels
+ );
+ /*!
+ requires
+ - 0 < camera_field_of_view < 180
+ ensures
+ - #get_camera_pos() == camera_pos
+ - #get_camera_looking_at() == camera_looking_at
+ - #get_camera_up_direction() == camera_up_direction
+ - #get_camera_field_of_view() == camera_field_of_view
+ - #get_num_pixels() == num_pixels
+ !*/
+
+ dpoint operator() (
+ const vector<double>& p
+ ) const;
+ /*!
+ ensures
+ - Maps the given 3D point p into the 2D image plane defined by the camera
+ parameters given to this object's constructor. The 2D point in the image
+ plane is returned.
+ !*/
+
+ dpoint operator() (
+ const vector<double>& p,
+ double& scale,
+ double& distance
+ ) const;
+ /*!
+ ensures
+ - Maps the given 3D point p into the 2D image plane defined by the camera
+ parameters given to this object's constructor. The 2D point in the image
+ plane is returned.
+ - #scale == a number that tells you how large things are at the point p.
+ Objects further from the camera appear smaller, in particular, they
+ appear #scale times their normal size.
+ - #distance == how far away the point is from the image plane. Objects in
+ front of the camera will have a positive distance and those behind a
+ negative distance.
+ !*/
+
+ vector<double> get_camera_pos(
+ ) const;
+ /*!
+ ensures
+ - returns the position, in 3D space, of the camera. When operator() is
+ invoked it maps 3D points into the image plane of this camera.
+ !*/
+
+ vector<double> get_camera_looking_at(
+ ) const;
+ /*!
+ ensures
+ - returns the point in 3D space the camera is pointed at.
+ !*/
+
+ vector<double> get_camera_up_direction(
+ ) const;
+ /*!
+ ensures
+ - returns a vector that defines what direction is "up" for the camera.
+ This means that as you travel from the bottom of the image plane to the
+ top you will be traveling in the direction of this vector. Note that
+ get_camera_up_direction() doesn't need to be orthogonal to the camera's
+ line of sight (i.e. get_camera_looking_at()-get_camera_pos()), it just
+ needs to not be an exact multiple of the line of sight. Any necessary
+ orthogonalization will be taken care of internally.
+ !*/
+
+ double get_camera_field_of_view(
+ ) const;
+ /*!
+ ensures
+ - returns the field of view of the camera in degrees.
+ !*/
+
+ unsigned long get_num_pixels(
+ ) const;
+ /*!
+ ensures
+ - 3D points that fall within the field of view of the camera are mapped by
+ operator() into the pixel coordinates of a get_num_pixels() by
+ get_num_pixels() image. Therefore, you can use the output of operator()
+ to index into an image. However, you still need to perform bounds
+ checking as there might be 3D points outside the field of view of the
+ camera and those will be mapped to 2D points outside the image.
+ !*/
+
+ };
+
+ void serialize (const camera_transform& item, std::ostream& out);
+ void deserialize (camera_transform& item, std::istream& in);
+ /*!
+ provides serialization support
+ !*/
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_POINT_TrANSFORMS_ABSTRACT_Hh_
+
+