init: 64 bits version of the webcam
This commit is contained in:
@ -41,8 +41,8 @@
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_CORE_AFFINE3_HPP__
|
||||
#define __OPENCV_CORE_AFFINE3_HPP__
|
||||
#ifndef OPENCV_CORE_AFFINE3_HPP
|
||||
#define OPENCV_CORE_AFFINE3_HPP
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -55,7 +55,72 @@ namespace cv
|
||||
//! @{
|
||||
|
||||
/** @brief Affine transform
|
||||
@todo document
|
||||
*
|
||||
* It represents a 4x4 homogeneous transformation matrix \f$T\f$
|
||||
*
|
||||
* \f[T =
|
||||
* \begin{bmatrix}
|
||||
* R & t\\
|
||||
* 0 & 1\\
|
||||
* \end{bmatrix}
|
||||
* \f]
|
||||
*
|
||||
* where \f$R\f$ is a 3x3 rotation matrix and \f$t\f$ is a 3x1 translation vector.
|
||||
*
|
||||
* You can specify \f$R\f$ either by a 3x3 rotation matrix or by a 3x1 rotation vector,
|
||||
* which is converted to a 3x3 rotation matrix by the Rodrigues formula.
|
||||
*
|
||||
* To construct a matrix \f$T\f$ representing first rotation around the axis \f$r\f$ with rotation
|
||||
* angle \f$|r|\f$ in radian (right hand rule) and then translation by the vector \f$t\f$, you can use
|
||||
*
|
||||
* @code
|
||||
* cv::Vec3f r, t;
|
||||
* cv::Affine3f T(r, t);
|
||||
* @endcode
|
||||
*
|
||||
* If you already have the rotation matrix \f$R\f$, then you can use
|
||||
*
|
||||
* @code
|
||||
* cv::Matx33f R;
|
||||
* cv::Affine3f T(R, t);
|
||||
* @endcode
|
||||
*
|
||||
* To extract the rotation matrix \f$R\f$ from \f$T\f$, use
|
||||
*
|
||||
* @code
|
||||
* cv::Matx33f R = T.rotation();
|
||||
* @endcode
|
||||
*
|
||||
* To extract the translation vector \f$t\f$ from \f$T\f$, use
|
||||
*
|
||||
* @code
|
||||
* cv::Vec3f t = T.translation();
|
||||
* @endcode
|
||||
*
|
||||
* To extract the rotation vector \f$r\f$ from \f$T\f$, use
|
||||
*
|
||||
* @code
|
||||
* cv::Vec3f r = T.rvec();
|
||||
* @endcode
|
||||
*
|
||||
* Note that since the mapping from rotation vectors to rotation matrices
|
||||
* is many to one. The returned rotation vector is not necessarily the one
|
||||
* you used before to set the matrix.
|
||||
*
|
||||
* If you have two transformations \f$T = T_1 * T_2\f$, use
|
||||
*
|
||||
* @code
|
||||
* cv::Affine3f T, T1, T2;
|
||||
* T = T2.concatenate(T1);
|
||||
* @endcode
|
||||
*
|
||||
* To get the inverse transform of \f$T\f$, use
|
||||
*
|
||||
* @code
|
||||
* cv::Affine3f T, T_inv;
|
||||
* T_inv = T.inv();
|
||||
* @endcode
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
class Affine3
|
||||
@ -66,54 +131,136 @@ namespace cv
|
||||
typedef Matx<float_type, 4, 4> Mat4;
|
||||
typedef Vec<float_type, 3> Vec3;
|
||||
|
||||
//! Default constructor. It represents a 4x4 identity matrix.
|
||||
Affine3();
|
||||
|
||||
//! Augmented affine matrix
|
||||
Affine3(const Mat4& affine);
|
||||
|
||||
//! Rotation matrix
|
||||
/**
|
||||
* The resulting 4x4 matrix is
|
||||
*
|
||||
* \f[
|
||||
* \begin{bmatrix}
|
||||
* R & t\\
|
||||
* 0 & 1\\
|
||||
* \end{bmatrix}
|
||||
* \f]
|
||||
*
|
||||
* @param R 3x3 rotation matrix.
|
||||
* @param t 3x1 translation vector.
|
||||
*/
|
||||
Affine3(const Mat3& R, const Vec3& t = Vec3::all(0));
|
||||
|
||||
//! Rodrigues vector
|
||||
/**
|
||||
* Rodrigues vector.
|
||||
*
|
||||
* The last row of the current matrix is set to [0,0,0,1].
|
||||
*
|
||||
* @param rvec 3x1 rotation vector. Its direction indicates the rotation axis and its length
|
||||
* indicates the rotation angle in radian (using right hand rule).
|
||||
* @param t 3x1 translation vector.
|
||||
*/
|
||||
Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0));
|
||||
|
||||
//! Combines all contructors above. Supports 4x4, 4x3, 3x3, 1x3, 3x1 sizes of data matrix
|
||||
/**
|
||||
* Combines all constructors above. Supports 4x4, 3x4, 3x3, 1x3, 3x1 sizes of data matrix.
|
||||
*
|
||||
* The last row of the current matrix is set to [0,0,0,1] when data is not 4x4.
|
||||
*
|
||||
* @param data 1-channel matrix.
|
||||
* when it is 4x4, it is copied to the current matrix and t is not used.
|
||||
* When it is 3x4, it is copied to the upper part 3x4 of the current matrix and t is not used.
|
||||
* When it is 3x3, it is copied to the upper left 3x3 part of the current matrix.
|
||||
* When it is 3x1 or 1x3, it is treated as a rotation vector and the Rodrigues formula is used
|
||||
* to compute a 3x3 rotation matrix.
|
||||
* @param t 3x1 translation vector. It is used only when data is neither 4x4 nor 3x4.
|
||||
*/
|
||||
explicit Affine3(const Mat& data, const Vec3& t = Vec3::all(0));
|
||||
|
||||
//! From 16th element array
|
||||
//! From 16-element array
|
||||
explicit Affine3(const float_type* vals);
|
||||
|
||||
//! Create identity transform
|
||||
//! Create an 4x4 identity transform
|
||||
static Affine3 Identity();
|
||||
|
||||
//! Rotation matrix
|
||||
/**
|
||||
* Rotation matrix.
|
||||
*
|
||||
* Copy the rotation matrix to the upper left 3x3 part of the current matrix.
|
||||
* The remaining elements of the current matrix are not changed.
|
||||
*
|
||||
* @param R 3x3 rotation matrix.
|
||||
*
|
||||
*/
|
||||
void rotation(const Mat3& R);
|
||||
|
||||
//! Rodrigues vector
|
||||
/**
|
||||
* Rodrigues vector.
|
||||
*
|
||||
* It sets the upper left 3x3 part of the matrix. The remaining part is unaffected.
|
||||
*
|
||||
* @param rvec 3x1 rotation vector. The direction indicates the rotation axis and
|
||||
* its length indicates the rotation angle in radian (using the right thumb convention).
|
||||
*/
|
||||
void rotation(const Vec3& rvec);
|
||||
|
||||
//! Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
|
||||
/**
|
||||
* Combines rotation methods above. Supports 3x3, 1x3, 3x1 sizes of data matrix.
|
||||
*
|
||||
* It sets the upper left 3x3 part of the matrix. The remaining part is unaffected.
|
||||
*
|
||||
* @param data 1-channel matrix.
|
||||
* When it is a 3x3 matrix, it sets the upper left 3x3 part of the current matrix.
|
||||
* When it is a 1x3 or 3x1 matrix, it is used as a rotation vector. The Rodrigues formula
|
||||
* is used to compute the rotation matrix and sets the upper left 3x3 part of the current matrix.
|
||||
*/
|
||||
void rotation(const Mat& data);
|
||||
|
||||
/**
|
||||
* Copy the 3x3 matrix L to the upper left part of the current matrix
|
||||
*
|
||||
* It sets the upper left 3x3 part of the matrix. The remaining part is unaffected.
|
||||
*
|
||||
* @param L 3x3 matrix.
|
||||
*/
|
||||
void linear(const Mat3& L);
|
||||
|
||||
/**
|
||||
* Copy t to the first three elements of the last column of the current matrix
|
||||
*
|
||||
* It sets the upper right 3x1 part of the matrix. The remaining part is unaffected.
|
||||
*
|
||||
* @param t 3x1 translation vector.
|
||||
*/
|
||||
void translation(const Vec3& t);
|
||||
|
||||
//! @return the upper left 3x3 part
|
||||
Mat3 rotation() const;
|
||||
|
||||
//! @return the upper left 3x3 part
|
||||
Mat3 linear() const;
|
||||
|
||||
//! @return the upper right 3x1 part
|
||||
Vec3 translation() const;
|
||||
|
||||
//! Rodrigues vector
|
||||
//! Rodrigues vector.
|
||||
//! @return a vector representing the upper left 3x3 rotation matrix of the current matrix.
|
||||
//! @warning Since the mapping between rotation vectors and rotation matrices is many to one,
|
||||
//! this function returns only one rotation vector that represents the current rotation matrix,
|
||||
//! which is not necessarily the same one set by `rotation(const Vec3& rvec)`.
|
||||
Vec3 rvec() const;
|
||||
|
||||
//! @return the inverse of the current matrix.
|
||||
Affine3 inv(int method = cv::DECOMP_SVD) const;
|
||||
|
||||
//! a.rotate(R) is equivalent to Affine(R, 0) * a;
|
||||
Affine3 rotate(const Mat3& R) const;
|
||||
|
||||
//! a.rotate(R) is equivalent to Affine(rvec, 0) * a;
|
||||
//! a.rotate(rvec) is equivalent to Affine(rvec, 0) * a;
|
||||
Affine3 rotate(const Vec3& rvec) const;
|
||||
|
||||
//! a.translate(t) is equivalent to Affine(E, t) * a;
|
||||
//! a.translate(t) is equivalent to Affine(E, t) * a, where E is an identity matrix
|
||||
Affine3 translate(const Vec3& t) const;
|
||||
|
||||
//! a.concatenate(affine) is equivalent to affine * a;
|
||||
@ -136,6 +283,7 @@ namespace cv
|
||||
template<typename T> static
|
||||
Affine3<T> operator*(const Affine3<T>& affine1, const Affine3<T>& affine2);
|
||||
|
||||
//! V is a 3-element vector with member fields x, y and z
|
||||
template<typename T, typename V> static
|
||||
V operator*(const Affine3<T>& affine, const V& vector);
|
||||
|
||||
@ -153,15 +301,24 @@ namespace cv
|
||||
typedef _Tp channel_type;
|
||||
|
||||
enum { generic_type = 0,
|
||||
depth = DataType<channel_type>::depth,
|
||||
channels = 16,
|
||||
fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
|
||||
type = CV_MAKETYPE(depth, channels)
|
||||
fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
|
||||
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
|
||||
,depth = DataType<channel_type>::depth
|
||||
,type = CV_MAKETYPE(depth, channels)
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef Vec<channel_type, channels> vec_type;
|
||||
};
|
||||
|
||||
namespace traits {
|
||||
template<typename _Tp>
|
||||
struct Depth< Affine3<_Tp> > { enum { value = Depth<_Tp>::value }; };
|
||||
template<typename _Tp>
|
||||
struct Type< Affine3<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 16) }; };
|
||||
} // namespace
|
||||
|
||||
//! @} core
|
||||
|
||||
}
|
||||
@ -169,7 +326,7 @@ namespace cv
|
||||
//! @cond IGNORED
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementaiton
|
||||
// Implementation
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3()
|
||||
@ -202,7 +359,8 @@ cv::Affine3<T>::Affine3(const Vec3& _rvec, const Vec3& t)
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3(const cv::Mat& data, const Vec3& t)
|
||||
{
|
||||
CV_Assert(data.type() == cv::DataType<T>::type);
|
||||
CV_Assert(data.type() == cv::traits::Type<T>::value);
|
||||
CV_Assert(data.channels() == 1);
|
||||
|
||||
if (data.cols == 4 && data.rows == 4)
|
||||
{
|
||||
@ -213,11 +371,13 @@ cv::Affine3<T>::Affine3(const cv::Mat& data, const Vec3& t)
|
||||
{
|
||||
rotation(data(Rect(0, 0, 3, 3)));
|
||||
translation(data(Rect(3, 0, 1, 3)));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotation(data);
|
||||
translation(t);
|
||||
}
|
||||
|
||||
rotation(data);
|
||||
translation(t);
|
||||
matrix.val[12] = matrix.val[13] = matrix.val[14] = 0;
|
||||
matrix.val[15] = 1;
|
||||
}
|
||||
@ -241,40 +401,36 @@ void cv::Affine3<T>::rotation(const Mat3& R)
|
||||
template<typename T> inline
|
||||
void cv::Affine3<T>::rotation(const Vec3& _rvec)
|
||||
{
|
||||
double rx = _rvec[0], ry = _rvec[1], rz = _rvec[2];
|
||||
double theta = std::sqrt(rx*rx + ry*ry + rz*rz);
|
||||
double theta = norm(_rvec);
|
||||
|
||||
if (theta < DBL_EPSILON)
|
||||
rotation(Mat3::eye());
|
||||
else
|
||||
{
|
||||
const double I[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
|
||||
|
||||
double c = std::cos(theta);
|
||||
double s = std::sin(theta);
|
||||
double c1 = 1. - c;
|
||||
double itheta = (theta != 0) ? 1./theta : 0.;
|
||||
|
||||
rx *= itheta; ry *= itheta; rz *= itheta;
|
||||
Point3_<T> r = _rvec*itheta;
|
||||
|
||||
double rrt[] = { rx*rx, rx*ry, rx*rz, rx*ry, ry*ry, ry*rz, rx*rz, ry*rz, rz*rz };
|
||||
double _r_x_[] = { 0, -rz, ry, rz, 0, -rx, -ry, rx, 0 };
|
||||
Mat3 R;
|
||||
Mat3 rrt( r.x*r.x, r.x*r.y, r.x*r.z, r.x*r.y, r.y*r.y, r.y*r.z, r.x*r.z, r.y*r.z, r.z*r.z );
|
||||
Mat3 r_x( 0, -r.z, r.y, r.z, 0, -r.x, -r.y, r.x, 0 );
|
||||
|
||||
// R = cos(theta)*I + (1 - cos(theta))*r*rT + sin(theta)*[r_x]
|
||||
// where [r_x] is [0 -rz ry; rz 0 -rx; -ry rx 0]
|
||||
for(int k = 0; k < 9; ++k)
|
||||
R.val[k] = static_cast<float_type>(c*I[k] + c1*rrt[k] + s*_r_x_[k]);
|
||||
Mat3 R = c*Mat3::eye() + c1*rrt + s*r_x;
|
||||
|
||||
rotation(R);
|
||||
}
|
||||
}
|
||||
|
||||
//Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
|
||||
//Combines rotation methods above. Supports 3x3, 1x3, 3x1 sizes of data matrix;
|
||||
template<typename T> inline
|
||||
void cv::Affine3<T>::rotation(const cv::Mat& data)
|
||||
{
|
||||
CV_Assert(data.type() == cv::DataType<T>::type);
|
||||
CV_Assert(data.type() == cv::traits::Type<T>::value);
|
||||
CV_Assert(data.channels() == 1);
|
||||
|
||||
if (data.cols == 3 && data.rows == 3)
|
||||
{
|
||||
@ -289,7 +445,7 @@ void cv::Affine3<T>::rotation(const cv::Mat& data)
|
||||
rotation(_rvec);
|
||||
}
|
||||
else
|
||||
CV_Assert(!"Input marix can be 3x3, 1x3 or 3x1");
|
||||
CV_Error(Error::StsError, "Input matrix can only be 3x3, 1x3 or 3x1");
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
@ -488,21 +644,21 @@ cv::Vec3d cv::operator*(const cv::Affine3d& affine, const cv::Vec3d& v)
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>& affine)
|
||||
{
|
||||
cv::Mat(4, 4, cv::DataType<T>::type, affine.matrix().data()).copyTo(matrix);
|
||||
cv::Mat(4, 4, cv::traits::Type<T>::value, affine.matrix().data()).copyTo(matrix);
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3(const Eigen::Transform<T, 3, Eigen::Affine>& affine)
|
||||
{
|
||||
Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> a = affine;
|
||||
cv::Mat(4, 4, cv::DataType<T>::type, a.matrix().data()).copyTo(matrix);
|
||||
cv::Mat(4, 4, cv::traits::Type<T>::value, a.matrix().data()).copyTo(matrix);
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const
|
||||
{
|
||||
Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> r;
|
||||
cv::Mat hdr(4, 4, cv::DataType<T>::type, r.matrix().data());
|
||||
cv::Mat hdr(4, 4, cv::traits::Type<T>::value, r.matrix().data());
|
||||
cv::Mat(matrix, false).copyTo(hdr);
|
||||
return r;
|
||||
}
|
||||
@ -519,4 +675,4 @@ cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine>() const
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __OPENCV_CORE_AFFINE3_HPP__ */
|
||||
#endif /* OPENCV_CORE_AFFINE3_HPP */
|
||||
|
||||
Reference in New Issue
Block a user