Files
featherVoice/TencentCloudHuiyanSDKFace_framework/Libs/YTCv.framework/Headers/matx.hpp
2025-08-08 10:49:36 +08:00

852 lines
23 KiB
C++

// fbc_cv is free software and uses the same licence as OpenCV
// Email: fengbingchun@163.com
#ifndef FBC_CV_CORE_MATX_HPP_
#define FBC_CV_CORE_MATX_HPP_
// reference: include/opencv2/core/matx.hpp
#ifndef __cplusplus
#error matx.hpp header must be compiled as C++
#endif
#include "fbcdef.hpp"
#include "base.hpp"
#include "interface.hpp"
#include "saturate.hpp"
namespace yt_tinycv {
////////////////////////////// Small Matrix ///////////////////////////
// Template class for small matrices whose type and size are known at compilation time
template<typename _Tp, int m, int n> class Matx {
public:
enum {
rows = m,
cols = n,
channels = rows*cols,
shortdim = (m < n ? m : n)
};
typedef _Tp value_type;
typedef Matx<_Tp, m, n> mat_type;
typedef Matx<_Tp, shortdim, 1> diag_type;
//! default constructor
Matx();
Matx(_Tp v0); //!< 1x1 matrix
Matx(_Tp v0, _Tp v1); //!< 1x2 or 2x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2); //!< 1x3 or 3x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 1x4, 2x2 or 4x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 1x5 or 5x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 1x6, 2x3, 3x2 or 6x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 1x7 or 7x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 1x8, 2x4, 4x2 or 8x1 matrix
Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 1x9, 3x3 or 9x1 matrix
explicit Matx(const _Tp* vals); //!< initialize from a plain array
static Matx all(_Tp alpha);
static Matx zeros();
static Matx ones();
static Matx eye();
static Matx diag(const diag_type& d);
//! dot product computed with the default precision
_Tp dot(const Matx<_Tp, m, n>& v) const;
//! dot product computed in double-precision arithmetics
double ddot(const Matx<_Tp, m, n>& v) const;
//! conversion to another data type
template<typename T2> operator Matx<T2, m, n>() const;
//! change the matrix shape
template<int m1, int n1> Matx<_Tp, m1, n1> reshape() const;
//! extract part of the matrix
template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int i, int j) const;
//! extract the matrix row
Matx<_Tp, 1, n> row(int i) const;
//! extract the matrix column
Matx<_Tp, m, 1> col(int i) const;
//! extract the matrix diagonal
diag_type diag() const;
//! element access
const _Tp& operator ()(int i, int j) const;
_Tp& operator ()(int i, int j);
//! 1D element access
const _Tp& operator ()(int i) const;
_Tp& operator ()(int i);
_Tp val[m*n]; //< matrix elements
};
typedef Matx<float, 1, 2> Matx12f;
typedef Matx<double, 1, 2> Matx12d;
typedef Matx<float, 1, 3> Matx13f;
typedef Matx<double, 1, 3> Matx13d;
typedef Matx<float, 1, 4> Matx14f;
typedef Matx<double, 1, 4> Matx14d;
typedef Matx<float, 1, 6> Matx16f;
typedef Matx<double, 1, 6> Matx16d;
typedef Matx<float, 2, 1> Matx21f;
typedef Matx<double, 2, 1> Matx21d;
typedef Matx<float, 3, 1> Matx31f;
typedef Matx<double, 3, 1> Matx31d;
typedef Matx<float, 4, 1> Matx41f;
typedef Matx<double, 4, 1> Matx41d;
typedef Matx<float, 6, 1> Matx61f;
typedef Matx<double, 6, 1> Matx61d;
typedef Matx<float, 2, 2> Matx22f;
typedef Matx<double, 2, 2> Matx22d;
typedef Matx<float, 2, 3> Matx23f;
typedef Matx<double, 2, 3> Matx23d;
typedef Matx<float, 3, 2> Matx32f;
typedef Matx<double, 3, 2> Matx32d;
typedef Matx<float, 3, 3> Matx33f;
typedef Matx<double, 3, 3> Matx33d;
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n>::Matx()
{
for (int i = 0; i < channels; i++) val[i] = _Tp(0);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n>::Matx(_Tp v0)
{
val[0] = v0;
for (int i = 1; i < channels; i++) val[i] = _Tp(0);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1)
{
FBC_StaticAssert(channels >= 2, "Matx should have at least 2 elements.");
val[0] = v0; val[1] = v1;
for (int i = 2; i < channels; i++) val[i] = _Tp(0);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2)
{
FBC_StaticAssert(channels >= 3, "Matx should have at least 3 elements.");
val[0] = v0; val[1] = v1; val[2] = v2;
for (int i = 3; i < channels; i++) val[i] = _Tp(0);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
{
FBC_StaticAssert(channels >= 4, "Matx should have at least 4 elements.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
for (int i = 4; i < channels; i++) val[i] = _Tp(0);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
{
FBC_StaticAssert(channels >= 5, "Matx should have at least 5 elements.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4;
for (int i = 5; i < channels; i++) val[i] = _Tp(0);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
{
FBC_StaticAssert(channels >= 6, "Matx should have at least 6 elements.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
val[4] = v4; val[5] = v5;
for (int i = 6; i < channels; i++) val[i] = _Tp(0);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6)
{
FBC_StaticAssert(channels >= 7, "Matx should have at least 7 elements.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
val[4] = v4; val[5] = v5; val[6] = v6;
for (int i = 7; i < channels; i++) val[i] = _Tp(0);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7)
{
FBC_StaticAssert(channels >= 8, "Matx should have at least 8 elements.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
for (int i = 8; i < channels; i++) val[i] = _Tp(0);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8)
{
FBC_StaticAssert(channels >= 9, "Matx should have at least 9 elements.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
val[8] = v8;
for (int i = 9; i < channels; i++) val[i] = _Tp(0);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n>::Matx(const _Tp* values)
{
for (int i = 0; i < channels; i++) val[i] = values[i];
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha)
{
Matx<_Tp, m, n> M;
for (int i = 0; i < m*n; i++) M.val[i] = alpha;
return M;
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n> Matx<_Tp, m, n>::zeros()
{
return all(0);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n> Matx<_Tp, m, n>::ones()
{
return all(1);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n> Matx<_Tp, m, n>::eye()
{
Matx<_Tp, m, n> M;
for (int i = 0; i < shortdim; i++)
M(i, i) = 1;
return M;
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n> Matx<_Tp, m, n>::diag(const typename Matx<_Tp, m, n>::diag_type& d)
{
Matx<_Tp, m, n> M;
for (int i = 0; i < shortdim; i++)
M(i, i) = d(i, 0);
return M;
}
template<typename _Tp, int m, int n> inline
_Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const
{
_Tp s = 0;
for (int i = 0; i < channels; i++) s += val[i] * M.val[i];
return s;
}
template<typename _Tp, int m, int n> inline
double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const
{
double s = 0;
for (int i = 0; i < channels; i++) s += (double)val[i] * M.val[i];
return s;
}
template<typename _Tp, int m, int n> template<typename T2>
inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const
{
Matx<T2, m, n> M;
for (int i = 0; i < m*n; i++) M.val[i] = saturate_cast<T2>(val[i]);
return M;
}
template<typename _Tp, int m, int n> template<int m1, int n1> inline
Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const
{
FBC_StaticAssert(m1*n1 == m*n, "Input and destnarion matrices must have the same number of elements");
return (const Matx<_Tp, m1, n1>&)*this;
}
template<typename _Tp, int m, int n>
template<int m1, int n1> inline
Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const
{
FBC_Assert(0 <= i && i + m1 <= m && 0 <= j && j + n1 <= n);
Matx<_Tp, m1, n1> s;
for (int di = 0; di < m1; di++)
for (int dj = 0; dj < n1; dj++)
s(di, dj) = (*this)(i + di, j + dj);
return s;
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const
{
FBC_Assert((unsigned)i < (unsigned)m);
return Matx<_Tp, 1, n>(&val[i*n]);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const
{
FBC_Assert((unsigned)j < (unsigned)n);
Matx<_Tp, m, 1> v;
for (int i = 0; i < m; i++)
v.val[i] = val[i*n + j];
return v;
}
template<typename _Tp, int m, int n> inline
typename Matx<_Tp, m, n>::diag_type Matx<_Tp, m, n>::diag() const
{
diag_type d;
for (int i = 0; i < shortdim; i++)
d.val[i] = val[i*n + i];
return d;
}
template<typename _Tp, int m, int n> inline
const _Tp& Matx<_Tp, m, n>::operator()(int i, int j) const
{
FBC_Assert((unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n);
return this->val[i*n + j];
}
template<typename _Tp, int m, int n> inline
_Tp& Matx<_Tp, m, n>::operator ()(int i, int j)
{
FBC_Assert((unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n);
return val[i*n + j];
}
template<typename _Tp, int m, int n> inline
const _Tp& Matx<_Tp, m, n>::operator ()(int i) const
{
FBC_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row");
FBC_Assert((unsigned)i < (unsigned)(m + n - 1));
return val[i];
}
template<typename _Tp, int m, int n> inline
_Tp& Matx<_Tp, m, n>::operator ()(int i)
{
FBC_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row");
FBC_Assert((unsigned)i < (unsigned)(m + n - 1));
return val[i];
}
template<typename _Tp, int m, int n> static inline
double norm(const Matx<_Tp, m, n>& M)
{
return std::sqrt(normL2Sqr<_Tp, double>(M.val, m*n));
}
template<typename _Tp, int m, int n> static inline
double norm(const Matx<_Tp, m, n>& M, int normType)
{
switch (normType) {
case NORM_INF:
return (double)normInf<_Tp, _Tp>(M.val, m*n);
case NORM_L1:
return (double)normL1<_Tp, _Tp>(M.val, m*n);
case NORM_L2SQR:
return (double)normL2Sqr<_Tp, _Tp>(M.val, m*n);
default:
case NORM_L2:
return std::sqrt((double)normL2Sqr<_Tp, _Tp>(M.val, m*n));
}
}
///////////////////////////// Matx out-of-class operators ////////////////////////////////
template<typename _Tp1, typename _Tp2, int m, int n> static inline
Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
{
for (int i = 0; i < m*n; i++)
a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
return a;
}
template<typename _Tp1, typename _Tp2, int m, int n> static inline
Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
{
for (int i = 0; i < m*n; i++)
a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
return a;
}
template<typename _Tp, int m, int n> static inline
Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
{
Matx<_Tp, m, n> M;
for (int i = 0; i < m*n; i++)
M.val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]);
return M;
}
template<typename _Tp, int m, int n> static inline
Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
{
Matx<_Tp, m, n> M;
for (int i = 0; i < m*n; i++)
M.val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]);
return M;
}
template<typename _Tp, int m, int n> static inline
Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha)
{
for (int i = 0; i < m*n; i++)
a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return a;
}
template<typename _Tp, int m, int n> static inline
Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha)
{
for (int i = 0; i < m*n; i++)
a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return a;
}
template<typename _Tp, int m, int n> static inline
Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha)
{
for (int i = 0; i < m*n; i++)
a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return a;
}
template<typename _Tp, int m, int n> static inline
Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha)
{
Matx<_Tp, m, n> M;
for (int i = 0; i < m*n; i++)
M.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return M;
}
template<typename _Tp, int m, int n> static inline
Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha)
{
Matx<_Tp, m, n> M;
for (int i = 0; i < m*n; i++)
M.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return M;
}
template<typename _Tp, int m, int n> static inline
Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha)
{
Matx<_Tp, m, n> M;
for (int i = 0; i < m*n; i++)
M.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return M;
}
template<typename _Tp, int m, int n> static inline
Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a)
{
Matx<_Tp, m, n> M;
for (int i = 0; i < m*n; i++)
M.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return M;
}
template<typename _Tp, int m, int n> static inline
Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a)
{
Matx<_Tp, m, n> M;
for (int i = 0; i < m*n; i++)
M.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return M;
}
template<typename _Tp, int m, int n> static inline
Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a)
{
Matx<_Tp, m, n> M;
for (int i = 0; i < m*n; i++)
M.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return M;
}
template<typename _Tp, int m, int n, int l> static inline
Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b)
{
Matx<_Tp, m, n> M;
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
{
_Tp s = 0;
for (int k = 0; k < l; k++)
s += a(i, k) * b(k, j);
M.val[i*n + j] = s;
}
return M;
}
template<typename _Tp, int m, int n> static inline
bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
{
for (int i = 0; i < m*n; i++)
if (a.val[i] != b.val[i]) return false;
return true;
}
template<typename _Tp, int m, int n> static inline
bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
{
return !(a == b);
}
///////////////////////////////////////// Vec ///////////////////////////////////
// Template class for short numerical vectors, a partial case of Matx
template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1> {
public:
typedef _Tp value_type;
enum {
channels = cn
};
//! default constructor
Vec();
Vec(_Tp v0); //!< 1-element vector constructor
Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2); //!< 3-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 4-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 5-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 6-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 7-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 8-element vector constructor
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 9-element vector constructor
explicit Vec(const _Tp* values);
Vec(const Vec<_Tp, cn>& v);
static Vec all(_Tp alpha);
//! per-element multiplication
Vec mul(const Vec<_Tp, cn>& v) const;
//! conversion to another data type
template<typename T2> operator Vec<T2, cn>() const;
/*! element access */
const _Tp& operator [](int i) const;
_Tp& operator[](int i);
const _Tp& operator ()(int i) const;
_Tp& operator ()(int i);
};
typedef Vec<uchar, 2> Vec2b;
typedef Vec<uchar, 3> Vec3b;
typedef Vec<uchar, 4> Vec4b;
typedef Vec<short, 2> Vec2s;
typedef Vec<short, 3> Vec3s;
typedef Vec<short, 4> Vec4s;
typedef Vec<ushort, 2> Vec2w;
typedef Vec<ushort, 3> Vec3w;
typedef Vec<ushort, 4> Vec4w;
typedef Vec<int, 2> Vec2i;
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;
typedef Vec<int, 6> Vec6i;
typedef Vec<float, 2> Vec2f;
typedef Vec<float, 3> Vec3f;
typedef Vec<float, 4> Vec4f;
typedef Vec<float, 6> Vec6f;
typedef Vec<double, 2> Vec2d;
typedef Vec<double, 3> Vec3d;
typedef Vec<double, 4> Vec4d;
typedef Vec<double, 6> Vec6d;
template<typename _Tp, int cn> inline
Vec<_Tp, cn>::Vec() {}
template<typename _Tp, int cn> inline
Vec<_Tp, cn>::Vec(_Tp v0)
: Matx<_Tp, cn, 1>(v0) {}
template<typename _Tp, int cn> inline
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1)
: Matx<_Tp, cn, 1>(v0, v1) {}
template<typename _Tp, int cn> inline
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2)
: Matx<_Tp, cn, 1>(v0, v1, v2) {}
template<typename _Tp, int cn> inline
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
: Matx<_Tp, cn, 1>(v0, v1, v2, v3) {}
template<typename _Tp, int cn> inline
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
: Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4) {}
template<typename _Tp, int cn> inline
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
: Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5) {}
template<typename _Tp, int cn> inline
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6)
: Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6) {}
template<typename _Tp, int cn> inline
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7)
: Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7) {}
template<typename _Tp, int cn> inline
Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8)
: Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8) {}
template<typename _Tp, int cn> inline
Vec<_Tp, cn>::Vec(const _Tp* values)
: Matx<_Tp, cn, 1>(values) {}
template<typename _Tp, int cn> inline
Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m)
: Matx<_Tp, cn, 1>(m.val) {}
template<typename _Tp, int cn> inline
Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha)
{
Vec v;
for (int i = 0; i < cn; i++) v.val[i] = alpha;
return v;
}
template<typename _Tp, int cn> inline
Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const
{
Vec<_Tp, cn> w;
for (int i = 0; i < cn; i++) w.val[i] = saturate_cast<_Tp>(this->val[i] * v.val[i]);
return w;
}
template<typename _Tp, int cn> template<typename T2> inline
Vec<_Tp, cn>::operator Vec<T2, cn>() const
{
Vec<T2, cn> v;
for (int i = 0; i < cn; i++) v.val[i] = saturate_cast<T2>(this->val[i]);
return v;
}
template<typename _Tp, int cn> inline
const _Tp& Vec<_Tp, cn>::operator [](int i) const
{
FBC_Assert((unsigned)i < (unsigned)cn);
return this->val[i];
}
template<typename _Tp, int cn> inline
_Tp& Vec<_Tp, cn>::operator [](int i)
{
FBC_Assert((unsigned)i < (unsigned)cn);
return this->val[i];
}
template<typename _Tp, int cn> inline
const _Tp& Vec<_Tp, cn>::operator ()(int i) const
{
FBC_Assert((unsigned)i < (unsigned)cn);
return this->val[i];
}
template<typename _Tp, int cn> inline
_Tp& Vec<_Tp, cn>::operator ()(int i)
{
FBC_Assert((unsigned)i < (unsigned)cn);
return this->val[i];
}
////////////////////////////// Vec out-of-class operators ////////////////////////////////
template<typename _Tp1, typename _Tp2, int cn> static inline
Vec<_Tp1, cn>& operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
{
for (int i = 0; i < cn; i++)
a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
return a;
}
template<typename _Tp1, typename _Tp2, int cn> static inline
Vec<_Tp1, cn>& operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
{
for (int i = 0; i < cn; i++)
a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
return a;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn> operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
{
Vec<_Tp, cn> v;
for (int i = 0; i < cn; i++)
v.val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]);
return v;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
{
Vec<_Tp, cn> v;
for (int i = 0; i < cn; i++)
v.val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]);
return v;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, int alpha)
{
for (int i = 0; i < cn; i++)
a[i] = saturate_cast<_Tp>(a[i] * alpha);
return a;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, float alpha)
{
for (int i = 0; i < cn; i++)
a[i] = saturate_cast<_Tp>(a[i] * alpha);
return a;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, double alpha)
{
for (int i = 0; i < cn; i++)
a[i] = saturate_cast<_Tp>(a[i] * alpha);
return a;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, int alpha)
{
double ialpha = 1. / alpha;
for (int i = 0; i < cn; i++)
a[i] = saturate_cast<_Tp>(a[i] * ialpha);
return a;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, float alpha)
{
float ialpha = 1.f / alpha;
for (int i = 0; i < cn; i++)
a[i] = saturate_cast<_Tp>(a[i] * ialpha);
return a;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, double alpha)
{
double ialpha = 1. / alpha;
for (int i = 0; i < cn; i++)
a[i] = saturate_cast<_Tp>(a[i] * ialpha);
return a;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, int alpha)
{
Vec<_Tp, cn> v;
for (int i = 0; i < cn; i++)
v.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return v;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn> operator * (int alpha, const Vec<_Tp, cn>& a)
{
Vec<_Tp, cn> v;
for (int i = 0; i < cn; i++)
v.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return v;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, float alpha)
{
Vec<_Tp, cn> v;
for (int i = 0; i < cn; i++)
v.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return v;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn> operator * (float alpha, const Vec<_Tp, cn>& a)
{
Vec<_Tp, cn> v;
for (int i = 0; i < cn; i++)
v.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return v;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, double alpha)
{
Vec<_Tp, cn> v;
for (int i = 0; i < cn; i++)
v.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return v;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn> operator * (double alpha, const Vec<_Tp, cn>& a)
{
Vec<_Tp, cn> v;
for (int i = 0; i < cn; i++)
v.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
return v;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, int alpha)
{
Vec<_Tp, cn> v;
double ialpha = 1. / alpha;
for (int i = 0; i < cn; i++)
v.val[i] = saturate_cast<_Tp>(a.val[i] * ialpha);
return v;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, float alpha)
{
Vec<_Tp, cn> v;
float ialpha = 1.f / alpha;
for (int i = 0; i < cn; i++)
v.val[i] = saturate_cast<_Tp>(a.val[i] * ialpha);
return v;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, double alpha)
{
Vec<_Tp, cn> v;
double ialpha = 1. / alpha;
for (int i = 0; i < cn; i++)
v.val[i] = saturate_cast<_Tp>(a.val[i] * ialpha);
return v;
}
template<typename _Tp, int cn> static inline
Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a)
{
Vec<_Tp, cn> t;
for (int i = 0; i < cn; i++) t.val[i] = saturate_cast<_Tp>(-a.val[i]);
return t;
}
} //yt_tinycv
#endif //FBC_CV_CORE_MATX_HPP_