Commit a3994bc4 authored by Andrey Kamaev's avatar Andrey Kamaev

Merge pull request #671 from cuda-geek/static_assert

Static assert
parents ec15d6f3 4096b545
...@@ -1079,7 +1079,7 @@ protected: ...@@ -1079,7 +1079,7 @@ protected:
void run_func(); void run_func();
void prepare_to_validation( int ); void prepare_to_validation( int );
double sampson_error(const double* f, double x1, double y1, double x2, double y2); double sampson_error(const double* f, double x1, double y1, double x2, double y2);
int method; int method;
int img_size; int img_size;
...@@ -1145,9 +1145,8 @@ void CV_EssentialMatTest::get_test_array_types_and_sizes( int /*test_case_idx*/, ...@@ -1145,9 +1145,8 @@ void CV_EssentialMatTest::get_test_array_types_and_sizes( int /*test_case_idx*/,
int pt_count = MAX(5, cvRound(exp(pt_count_exp))); int pt_count = MAX(5, cvRound(exp(pt_count_exp)));
dims = cvtest::randInt(rng) % 2 + 2; dims = cvtest::randInt(rng) % 2 + 2;
dims = 2; dims = 2;
method = CV_LMEDS << (cvtest::randInt(rng) % 2); method = CV_LMEDS << (cvtest::randInt(rng) % 2);
types[INPUT][0] = CV_MAKETYPE(pt_depth, 1); types[INPUT][0] = CV_MAKETYPE(pt_depth, 1);
...@@ -1192,11 +1191,11 @@ void CV_EssentialMatTest::get_test_array_types_and_sizes( int /*test_case_idx*/, ...@@ -1192,11 +1191,11 @@ void CV_EssentialMatTest::get_test_array_types_and_sizes( int /*test_case_idx*/,
sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(3,1); sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(3,1);
types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_64FC1; types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_64FC1;
sizes[OUTPUT][1] = sizes[REF_OUTPUT][1] = cvSize(pt_count,1); sizes[OUTPUT][1] = sizes[REF_OUTPUT][1] = cvSize(pt_count,1);
types[OUTPUT][1] = types[REF_OUTPUT][1] = CV_8UC1; types[OUTPUT][1] = types[REF_OUTPUT][1] = CV_8UC1;
sizes[OUTPUT][2] = sizes[REF_OUTPUT][2] = cvSize(1,1); sizes[OUTPUT][2] = sizes[REF_OUTPUT][2] = cvSize(1,1);
types[OUTPUT][2] = types[REF_OUTPUT][2] = CV_64FC1; types[OUTPUT][2] = types[REF_OUTPUT][2] = CV_64FC1;
sizes[OUTPUT][3] = sizes[REF_OUTPUT][3] = cvSize(1,1); sizes[OUTPUT][3] = sizes[REF_OUTPUT][3] = cvSize(1,1);
types[OUTPUT][3] = types[REF_OUTPUT][3] = CV_8UC1; types[OUTPUT][3] = types[REF_OUTPUT][3] = CV_8UC1;
} }
...@@ -1289,46 +1288,46 @@ int CV_EssentialMatTest::prepare_test_case( int test_case_idx ) ...@@ -1289,46 +1288,46 @@ int CV_EssentialMatTest::prepare_test_case( int test_case_idx )
void CV_EssentialMatTest::run_func() void CV_EssentialMatTest::run_func()
{ {
Mat _input0(test_mat[INPUT][0]), _input1(test_mat[INPUT][1]); Mat _input0(test_mat[INPUT][0]), _input1(test_mat[INPUT][1]);
Mat K(test_mat[INPUT][4]); Mat K(test_mat[INPUT][4]);
double focal(K.at<double>(0, 0)); double focal(K.at<double>(0, 0));
cv::Point2d pp(K.at<double>(0, 2), K.at<double>(1, 2)); cv::Point2d pp(K.at<double>(0, 2), K.at<double>(1, 2));
RNG& rng = ts->get_rng(); RNG& rng = ts->get_rng();
Mat E, mask1(test_mat[TEMP][1]); Mat E, mask1(test_mat[TEMP][1]);
E = cv::findEssentialMat( _input0, _input1, focal, pp, method, 0.99, MAX(sigma*3, 0.0001), mask1 ); E = cv::findEssentialMat( _input0, _input1, focal, pp, method, 0.99, MAX(sigma*3, 0.0001), mask1 );
if (E.rows > 3) if (E.rows > 3)
{ {
int count = E.rows / 3; int count = E.rows / 3;
int row = (cvtest::randInt(rng) % count) * 3; int row = (cvtest::randInt(rng) % count) * 3;
E = E.rowRange(row, row + 3) * 1.0; E = E.rowRange(row, row + 3) * 1.0;
} }
E.copyTo(test_mat[TEMP][0]); E.copyTo(test_mat[TEMP][0]);
Mat R, t, mask2; Mat R, t, mask2;
recoverPose( E, _input0, _input1, R, t, focal, pp, mask2 ); recoverPose( E, _input0, _input1, R, t, focal, pp, mask2 );
R.copyTo(test_mat[TEMP][2]); R.copyTo(test_mat[TEMP][2]);
t.copyTo(test_mat[TEMP][3]); t.copyTo(test_mat[TEMP][3]);
mask2.copyTo(test_mat[TEMP][4]); mask2.copyTo(test_mat[TEMP][4]);
} }
double CV_EssentialMatTest::sampson_error(const double * f, double x1, double y1, double x2, double y2) double CV_EssentialMatTest::sampson_error(const double * f, double x1, double y1, double x2, double y2)
{ {
double Fx1[3] = { double Fx1[3] = {
f[0] * x1 + f[1] * y1 + f[2], f[0] * x1 + f[1] * y1 + f[2],
f[3] * x1 + f[4] * y1 + f[5], f[3] * x1 + f[4] * y1 + f[5],
f[6] * x1 + f[7] * y1 + f[8] f[6] * x1 + f[7] * y1 + f[8]
}; };
double Ftx2[3] = { double Ftx2[3] = {
f[0] * x2 + f[3] * y2 + f[6], f[0] * x2 + f[3] * y2 + f[6],
f[1] * x2 + f[4] * y2 + f[7], f[1] * x2 + f[4] * y2 + f[7],
f[2] * x2 + f[5] * y2 + f[8] f[2] * x2 + f[5] * y2 + f[8]
}; };
double x2tFx1 = Fx1[0] * x2 + Fx1[1] * y2 + Fx1[2]; double x2tFx1 = Fx1[0] * x2 + Fx1[1] * y2 + Fx1[2];
double error = x2tFx1 * x2tFx1 / (Fx1[0] * Fx1[0] + Fx1[1] * Fx1[1] + Ftx2[0] * Ftx2[0] + Ftx2[1] * Ftx2[1]); double error = x2tFx1 * x2tFx1 / (Fx1[0] * Fx1[0] + Fx1[1] * Fx1[1] + Ftx2[0] * Ftx2[0] + Ftx2[1] * Ftx2[1]);
error = sqrt(error); error = sqrt(error);
return error; return error;
} }
...@@ -1338,7 +1337,7 @@ void CV_EssentialMatTest::prepare_to_validation( int test_case_idx ) ...@@ -1338,7 +1337,7 @@ void CV_EssentialMatTest::prepare_to_validation( int test_case_idx )
const Mat& A = test_mat[INPUT][4]; const Mat& A = test_mat[INPUT][4];
double f0[9], f[9], e[9]; double f0[9], f[9], e[9];
Mat F0(3, 3, CV_64FC1, f0), F(3, 3, CV_64F, f); Mat F0(3, 3, CV_64FC1, f0), F(3, 3, CV_64F, f);
Mat E(3, 3, CV_64F, e); Mat E(3, 3, CV_64F, e);
Mat invA, R=Rt0.colRange(0, 3), T1, T2; Mat invA, R=Rt0.colRange(0, 3), T1, T2;
...@@ -1362,7 +1361,7 @@ void CV_EssentialMatTest::prepare_to_validation( int test_case_idx ) ...@@ -1362,7 +1361,7 @@ void CV_EssentialMatTest::prepare_to_validation( int test_case_idx )
uchar* mtfm2 = test_mat[OUTPUT][1].data; uchar* mtfm2 = test_mat[OUTPUT][1].data;
double* e_prop1 = (double*)test_mat[REF_OUTPUT][0].data; double* e_prop1 = (double*)test_mat[REF_OUTPUT][0].data;
double* e_prop2 = (double*)test_mat[OUTPUT][0].data; double* e_prop2 = (double*)test_mat[OUTPUT][0].data;
Mat E_prop2 = Mat(3, 1, CV_64F, e_prop2); Mat E_prop2 = Mat(3, 1, CV_64F, e_prop2);
int i, pt_count = test_mat[INPUT][2].cols; int i, pt_count = test_mat[INPUT][2].cols;
Mat p1( 1, pt_count, CV_64FC2 ); Mat p1( 1, pt_count, CV_64FC2 );
...@@ -1381,8 +1380,8 @@ void CV_EssentialMatTest::prepare_to_validation( int test_case_idx ) ...@@ -1381,8 +1380,8 @@ void CV_EssentialMatTest::prepare_to_validation( int test_case_idx )
double y1 = p1.at<Point2d>(i).y; double y1 = p1.at<Point2d>(i).y;
double x2 = p2.at<Point2d>(i).x; double x2 = p2.at<Point2d>(i).x;
double y2 = p2.at<Point2d>(i).y; double y2 = p2.at<Point2d>(i).y;
// double t0 = sampson_error(f0, x1, y1, x2, y2); // double t0 = sampson_error(f0, x1, y1, x2, y2);
// double t = sampson_error(f, x1, y1, x2, y2); // double t = sampson_error(f, x1, y1, x2, y2);
double n1 = 1./sqrt(x1*x1 + y1*y1 + 1); double n1 = 1./sqrt(x1*x1 + y1*y1 + 1);
double n2 = 1./sqrt(x2*x2 + y2*y2 + 1); double n2 = 1./sqrt(x2*x2 + y2*y2 + 1);
double t0 = fabs(f0[0]*x2*x1 + f0[1]*x2*y1 + f0[2]*x2 + double t0 = fabs(f0[0]*x2*x1 + f0[1]*x2*y1 + f0[2]*x2 +
...@@ -1394,7 +1393,7 @@ void CV_EssentialMatTest::prepare_to_validation( int test_case_idx ) ...@@ -1394,7 +1393,7 @@ void CV_EssentialMatTest::prepare_to_validation( int test_case_idx )
mtfm1[i] = 1; mtfm1[i] = 1;
mtfm2[i] = !status[i] || t0 > err_level || t < err_level; mtfm2[i] = !status[i] || t0 > err_level || t < err_level;
} }
e_prop1[0] = sqrt(0.5); e_prop1[0] = sqrt(0.5);
e_prop1[1] = sqrt(0.5); e_prop1[1] = sqrt(0.5);
e_prop1[2] = 0; e_prop1[2] = 0;
...@@ -1402,26 +1401,26 @@ void CV_EssentialMatTest::prepare_to_validation( int test_case_idx ) ...@@ -1402,26 +1401,26 @@ void CV_EssentialMatTest::prepare_to_validation( int test_case_idx )
e_prop2[0] = 0; e_prop2[0] = 0;
e_prop2[1] = 0; e_prop2[1] = 0;
e_prop2[2] = 0; e_prop2[2] = 0;
SVD::compute(E, E_prop2); SVD::compute(E, E_prop2);
double* pose_prop1 = (double*)test_mat[REF_OUTPUT][2].data; double* pose_prop1 = (double*)test_mat[REF_OUTPUT][2].data;
double* pose_prop2 = (double*)test_mat[OUTPUT][2].data; double* pose_prop2 = (double*)test_mat[OUTPUT][2].data;
double terr1 = norm(Rt0.col(3) / norm(Rt0.col(3)) + test_mat[TEMP][3]); double terr1 = norm(Rt0.col(3) / norm(Rt0.col(3)) + test_mat[TEMP][3]);
double terr2 = norm(Rt0.col(3) / norm(Rt0.col(3)) - test_mat[TEMP][3]); double terr2 = norm(Rt0.col(3) / norm(Rt0.col(3)) - test_mat[TEMP][3]);
Mat rvec; Mat rvec;
Rodrigues(Rt0.colRange(0, 3), rvec); Rodrigues(Rt0.colRange(0, 3), rvec);
pose_prop1[0] = 0; pose_prop1[0] = 0;
// No check for CV_LMeDS on translation. Since it // No check for CV_LMeDS on translation. Since it
// involves with some degraded problem, when data is exact inliers. // involves with some degraded problem, when data is exact inliers.
pose_prop2[0] = method == CV_LMEDS || pt_count == 5 ? 0 : MIN(terr1, terr2); pose_prop2[0] = method == CV_LMEDS || pt_count == 5 ? 0 : MIN(terr1, terr2);
// int inliers_count = countNonZero(test_mat[TEMP][1]); // int inliers_count = countNonZero(test_mat[TEMP][1]);
// int good_count = countNonZero(test_mat[TEMP][4]); // int good_count = countNonZero(test_mat[TEMP][4]);
test_mat[OUTPUT][3] = true; //good_count >= inliers_count / 2; test_mat[OUTPUT][3] = true; //good_count >= inliers_count / 2;
test_mat[REF_OUTPUT][3] = true; test_mat[REF_OUTPUT][3] = true;
} }
......
...@@ -68,7 +68,7 @@ namespace cv ...@@ -68,7 +68,7 @@ namespace cv
//Rodrigues vector //Rodrigues vector
Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0)); Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0));
//Combines all contructors above. Supports 4x4, 3x3, 1x3, 3x1 sizes of data matrix //Combines all contructors above. Supports 4x4, 3x3, 1x3, 3x1 sizes of data matrix
explicit Affine3(const cv::Mat& data, const Vec3& t = Vec3::all(0)); explicit Affine3(const cv::Mat& data, const Vec3& t = Vec3::all(0));
...@@ -79,13 +79,13 @@ namespace cv ...@@ -79,13 +79,13 @@ namespace cv
//Rotation matrix //Rotation matrix
void rotation(const Mat3& R); void rotation(const Mat3& R);
//Rodrigues vector //Rodrigues vector
void rotation(const Vec3& rvec); void rotation(const Vec3& rvec);
//Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix; //Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
void rotation(const Mat& data); void rotation(const Mat& data);
//Euler angles //Euler angles
void rotation(float_type alpha, float_type beta, float_type gamma); void rotation(float_type alpha, float_type beta, float_type gamma);
...@@ -218,7 +218,7 @@ template<typename T> inline void cv::Affine3<T>::rotation(const Vec3& rvec) ...@@ -218,7 +218,7 @@ template<typename T> inline void cv::Affine3<T>::rotation(const Vec3& rvec)
template<typename T> inline void cv::Affine3<T>::rotation(const cv::Mat& data) 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::DataType<T>::type);
if (data.cols == 3 && data.rows == 3) if (data.cols == 3 && data.rows == 3)
{ {
Mat3 R; Mat3 R;
......
...@@ -764,7 +764,7 @@ inline void SVD::solveZ( InputArray m, OutputArray _dst ) ...@@ -764,7 +764,7 @@ inline void SVD::solveZ( InputArray m, OutputArray _dst )
template<typename _Tp, int m, int n, int nm> inline void template<typename _Tp, int m, int n, int nm> inline void
SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt ) SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt )
{ {
assert( nm == MIN(m, n)); CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector.");
Mat _a(a, false), _u(u, false), _w(w, false), _vt(vt, false); Mat _a(a, false), _u(u, false), _w(w, false), _vt(vt, false);
SVD::compute(_a, _w, _u, _vt); SVD::compute(_a, _w, _u, _vt);
CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]); CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]);
...@@ -773,7 +773,7 @@ template<typename _Tp, int m, int n, int nm> inline void ...@@ -773,7 +773,7 @@ template<typename _Tp, int m, int n, int nm> inline void
template<typename _Tp, int m, int n, int nm> inline void template<typename _Tp, int m, int n, int nm> inline void
SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w ) SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w )
{ {
assert( nm == MIN(m, n)); CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector.");
Mat _a(a, false), _w(w, false); Mat _a(a, false), _w(w, false);
SVD::compute(_a, _w); SVD::compute(_a, _w);
CV_Assert(_w.data == (uchar*)&w.val[0]); CV_Assert(_w.data == (uchar*)&w.val[0]);
...@@ -784,7 +784,7 @@ SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u, ...@@ -784,7 +784,7 @@ SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u,
const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs, const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs,
Matx<_Tp, n, nb>& dst ) Matx<_Tp, n, nb>& dst )
{ {
assert( nm == MIN(m, n)); CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector.");
Mat _u(u, false), _w(w, false), _vt(vt, false), _rhs(rhs, false), _dst(dst, false); Mat _u(u, false), _w(w, false), _vt(vt, false), _rhs(rhs, false), _dst(dst, false);
SVD::backSubst(_w, _u, _vt, _rhs, _dst); SVD::backSubst(_w, _u, _vt, _rhs, _dst);
CV_Assert(_dst.data == (uchar*)&dst.val[0]); CV_Assert(_dst.data == (uchar*)&dst.val[0]);
......
...@@ -58,6 +58,43 @@ ...@@ -58,6 +58,43 @@
# pragma warning(disable:4127) //conditional expression is constant # pragma warning(disable:4127) //conditional expression is constant
#endif #endif
//////////////// static assert /////////////////
#define CVAUX_CONCAT_EXP(a, b) a##b
#define CVAUX_CONCAT(a, b) CVAUX_CONCAT_EXP(a,b)
#ifdef __cplusplus
# if defined(__clang__)
# ifndef __has_extension
# define __has_extension __has_feature /* compatibility, for older versions of clang */
# endif
# if __has_extension(cxx_static_assert)
# define CV_StaticAssert(condition, reason) static_assert((condition), reason " " #condition)
# endif
# elif defined(__GNUC__)
# if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L)
# define CV_StaticAssert(condition, reason) static_assert((condition), reason " " #condition)
# endif
# elif defined(_MSC_VER)
# if _MSC_VER >= 1600 /* MSVC 10 */
# define CV_StaticAssert(condition, reason) static_assert((condition), reason " " #condition)
# endif
# endif
# ifndef CV_StaticAssert
# if defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 2)
# define CV_StaticAssert(condition, reason) ({ extern int __attribute__((error("CV_StaticAssert: " reason " " #condition))) CV_StaticAssert(); ((condition) ? 0 : CV_StaticAssert()); })
# else
namespace cv {
template <bool x> struct CV_StaticAssert_failed;
template <> struct CV_StaticAssert_failed<true> { enum { val = 1 }; };
template<int x> struct CV_StaticAssert_test{};
}
# define CV_StaticAssert(condition, reason)\
typedef cv::CV_StaticAssert_test< sizeof(cv::CV_StaticAssert_failed< static_cast<bool>(condition) >) > CVAUX_CONCAT(CV_StaticAssert_failed_at_, __LINE__)
# endif
# endif
#endif
namespace cv namespace cv
{ {
...@@ -164,28 +201,28 @@ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0) ...@@ -164,28 +201,28 @@ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0)
template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1) template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1)
{ {
assert(channels >= 2); CV_StaticAssert(channels >= 2, "Matx should have at least 2 elaments.");
val[0] = v0; val[1] = v1; val[0] = v0; val[1] = v1;
for(int i = 2; i < channels; i++) val[i] = _Tp(0); 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) template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2)
{ {
assert(channels >= 3); CV_StaticAssert(channels >= 3, "Matx should have at least 3 elaments.");
val[0] = v0; val[1] = v1; val[2] = v2; val[0] = v0; val[1] = v1; val[2] = v2;
for(int i = 3; i < channels; i++) val[i] = _Tp(0); 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) template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
{ {
assert(channels >= 4); CV_StaticAssert(channels >= 4, "Matx should have at least 4 elaments.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
for(int i = 4; i < channels; i++) val[i] = _Tp(0); 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) template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
{ {
assert(channels >= 5); CV_StaticAssert(channels >= 5, "Matx should have at least 5 elaments.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4; 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); for(int i = 5; i < channels; i++) val[i] = _Tp(0);
} }
...@@ -193,7 +230,7 @@ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1 ...@@ -193,7 +230,7 @@ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1
template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, 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 v4, _Tp v5)
{ {
assert(channels >= 6); CV_StaticAssert(channels >= 6, "Matx should have at least 6 elaments.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
val[4] = v4; val[5] = v5; val[4] = v4; val[5] = v5;
for(int i = 6; i < channels; i++) val[i] = _Tp(0); for(int i = 6; i < channels; i++) val[i] = _Tp(0);
...@@ -202,7 +239,7 @@ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1 ...@@ -202,7 +239,7 @@ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1
template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, 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 v4, _Tp v5, _Tp v6)
{ {
assert(channels >= 7); CV_StaticAssert(channels >= 7, "Matx should have at least 7 elaments.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
val[4] = v4; val[5] = v5; val[6] = v6; val[4] = v4; val[5] = v5; val[6] = v6;
for(int i = 7; i < channels; i++) val[i] = _Tp(0); for(int i = 7; i < channels; i++) val[i] = _Tp(0);
...@@ -211,7 +248,7 @@ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1 ...@@ -211,7 +248,7 @@ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1
template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, 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 v4, _Tp v5, _Tp v6, _Tp v7)
{ {
assert(channels >= 8); CV_StaticAssert(channels >= 8, "Matx should have at least 8 elaments.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 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[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
for(int i = 8; i < channels; i++) val[i] = _Tp(0); for(int i = 8; i < channels; i++) val[i] = _Tp(0);
...@@ -221,7 +258,7 @@ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1 ...@@ -221,7 +258,7 @@ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1
_Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v4, _Tp v5, _Tp v6, _Tp v7,
_Tp v8) _Tp v8)
{ {
assert(channels >= 9); CV_StaticAssert(channels >= 9, "Matx should have at least 9 elaments.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 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[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
val[8] = v8; val[8] = v8;
...@@ -232,7 +269,7 @@ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1 ...@@ -232,7 +269,7 @@ template<typename _Tp, int m, int n> inline Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1
_Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v4, _Tp v5, _Tp v6, _Tp v7,
_Tp v8, _Tp v9) _Tp v8, _Tp v9)
{ {
assert(channels >= 10); CV_StaticAssert(channels >= 10, "Matx should have at least 10 elaments.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 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[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
val[8] = v8; val[9] = v9; val[8] = v8; val[9] = v9;
...@@ -245,7 +282,7 @@ inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, ...@@ -245,7 +282,7 @@ inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
_Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v4, _Tp v5, _Tp v6, _Tp v7,
_Tp v8, _Tp v9, _Tp v10, _Tp v11) _Tp v8, _Tp v9, _Tp v10, _Tp v11)
{ {
assert(channels == 12); CV_StaticAssert(channels == 12, "Matx should have at least 12 elaments.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 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[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
...@@ -257,7 +294,7 @@ inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, ...@@ -257,7 +294,7 @@ inline Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
_Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v8, _Tp v9, _Tp v10, _Tp v11,
_Tp v12, _Tp v13, _Tp v14, _Tp v15) _Tp v12, _Tp v13, _Tp v14, _Tp v15)
{ {
assert(channels == 16); CV_StaticAssert(channels == 16, "Matx should have at least 16 elaments.");
val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; 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[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
......
...@@ -100,61 +100,61 @@ void FAST_t(InputArray _img, std::vector<KeyPoint>& keypoints, int threshold, bo ...@@ -100,61 +100,61 @@ void FAST_t(InputArray _img, std::vector<KeyPoint>& keypoints, int threshold, bo
#if CV_SSE2 #if CV_SSE2
if( patternSize == 16 ) if( patternSize == 16 )
{ {
for(; j < img.cols - 16 - 3; j += 16, ptr += 16) for(; j < img.cols - 16 - 3; j += 16, ptr += 16)
{
__m128i m0, m1;
__m128i v0 = _mm_loadu_si128((const __m128i*)ptr);
__m128i v1 = _mm_xor_si128(_mm_subs_epu8(v0, t), delta);
v0 = _mm_xor_si128(_mm_adds_epu8(v0, t), delta);
__m128i x0 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[0])), delta);
__m128i x1 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[quarterPatternSize])), delta);
__m128i x2 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[2*quarterPatternSize])), delta);
__m128i x3 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[3*quarterPatternSize])), delta);
m0 = _mm_and_si128(_mm_cmpgt_epi8(x0, v0), _mm_cmpgt_epi8(x1, v0));
m1 = _mm_and_si128(_mm_cmpgt_epi8(v1, x0), _mm_cmpgt_epi8(v1, x1));
m0 = _mm_or_si128(m0, _mm_and_si128(_mm_cmpgt_epi8(x1, v0), _mm_cmpgt_epi8(x2, v0)));
m1 = _mm_or_si128(m1, _mm_and_si128(_mm_cmpgt_epi8(v1, x1), _mm_cmpgt_epi8(v1, x2)));
m0 = _mm_or_si128(m0, _mm_and_si128(_mm_cmpgt_epi8(x2, v0), _mm_cmpgt_epi8(x3, v0)));
m1 = _mm_or_si128(m1, _mm_and_si128(_mm_cmpgt_epi8(v1, x2), _mm_cmpgt_epi8(v1, x3)));
m0 = _mm_or_si128(m0, _mm_and_si128(_mm_cmpgt_epi8(x3, v0), _mm_cmpgt_epi8(x0, v0)));
m1 = _mm_or_si128(m1, _mm_and_si128(_mm_cmpgt_epi8(v1, x3), _mm_cmpgt_epi8(v1, x0)));
m0 = _mm_or_si128(m0, m1);
int mask = _mm_movemask_epi8(m0);
if( mask == 0 )
continue;
if( (mask & 255) == 0 )
{ {
j -= 8; __m128i m0, m1;
ptr -= 8; __m128i v0 = _mm_loadu_si128((const __m128i*)ptr);
continue; __m128i v1 = _mm_xor_si128(_mm_subs_epu8(v0, t), delta);
} v0 = _mm_xor_si128(_mm_adds_epu8(v0, t), delta);
__m128i x0 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[0])), delta);
__m128i x1 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[quarterPatternSize])), delta);
__m128i x2 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[2*quarterPatternSize])), delta);
__m128i x3 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[3*quarterPatternSize])), delta);
m0 = _mm_and_si128(_mm_cmpgt_epi8(x0, v0), _mm_cmpgt_epi8(x1, v0));
m1 = _mm_and_si128(_mm_cmpgt_epi8(v1, x0), _mm_cmpgt_epi8(v1, x1));
m0 = _mm_or_si128(m0, _mm_and_si128(_mm_cmpgt_epi8(x1, v0), _mm_cmpgt_epi8(x2, v0)));
m1 = _mm_or_si128(m1, _mm_and_si128(_mm_cmpgt_epi8(v1, x1), _mm_cmpgt_epi8(v1, x2)));
m0 = _mm_or_si128(m0, _mm_and_si128(_mm_cmpgt_epi8(x2, v0), _mm_cmpgt_epi8(x3, v0)));
m1 = _mm_or_si128(m1, _mm_and_si128(_mm_cmpgt_epi8(v1, x2), _mm_cmpgt_epi8(v1, x3)));
m0 = _mm_or_si128(m0, _mm_and_si128(_mm_cmpgt_epi8(x3, v0), _mm_cmpgt_epi8(x0, v0)));
m1 = _mm_or_si128(m1, _mm_and_si128(_mm_cmpgt_epi8(v1, x3), _mm_cmpgt_epi8(v1, x0)));
m0 = _mm_or_si128(m0, m1);
int mask = _mm_movemask_epi8(m0);
if( mask == 0 )
continue;
if( (mask & 255) == 0 )
{
j -= 8;
ptr -= 8;
continue;
}
__m128i c0 = _mm_setzero_si128(), c1 = c0, max0 = c0, max1 = c0; __m128i c0 = _mm_setzero_si128(), c1 = c0, max0 = c0, max1 = c0;
for( k = 0; k < N; k++ ) for( k = 0; k < N; k++ )
{ {
__m128i x = _mm_xor_si128(_mm_loadu_si128((const __m128i*)(ptr + pixel[k])), delta); __m128i x = _mm_xor_si128(_mm_loadu_si128((const __m128i*)(ptr + pixel[k])), delta);
m0 = _mm_cmpgt_epi8(x, v0); m0 = _mm_cmpgt_epi8(x, v0);
m1 = _mm_cmpgt_epi8(v1, x); m1 = _mm_cmpgt_epi8(v1, x);
c0 = _mm_and_si128(_mm_sub_epi8(c0, m0), m0); c0 = _mm_and_si128(_mm_sub_epi8(c0, m0), m0);
c1 = _mm_and_si128(_mm_sub_epi8(c1, m1), m1); c1 = _mm_and_si128(_mm_sub_epi8(c1, m1), m1);
max0 = _mm_max_epu8(max0, c0); max0 = _mm_max_epu8(max0, c0);
max1 = _mm_max_epu8(max1, c1); max1 = _mm_max_epu8(max1, c1);
} }
max0 = _mm_max_epu8(max0, max1); max0 = _mm_max_epu8(max0, max1);
int m = _mm_movemask_epi8(_mm_cmpgt_epi8(max0, K16)); int m = _mm_movemask_epi8(_mm_cmpgt_epi8(max0, K16));
for( k = 0; m > 0 && k < 16; k++, m >>= 1 ) for( k = 0; m > 0 && k < 16; k++, m >>= 1 )
if(m & 1) if(m & 1)
{ {
cornerpos[ncorners++] = j+k; cornerpos[ncorners++] = j+k;
if(nonmax_suppression) if(nonmax_suppression)
curr[j+k] = (uchar)cornerScore<patternSize>(ptr+k, pixel, threshold); curr[j+k] = (uchar)cornerScore<patternSize>(ptr+k, pixel, threshold);
} }
} }
} }
#endif #endif
for( ; j < img.cols - 3; j++, ptr++ ) for( ; j < img.cols - 3; j++, ptr++ )
......
...@@ -208,7 +208,6 @@ private: ...@@ -208,7 +208,6 @@ private:
#define SANITY_CHECK_KEYPOINTS(array, ...) ::perf::Regression::addKeypoints(this, #array, array , ## __VA_ARGS__) #define SANITY_CHECK_KEYPOINTS(array, ...) ::perf::Regression::addKeypoints(this, #array, array , ## __VA_ARGS__)
#define SANITY_CHECK_MATCHES(array, ...) ::perf::Regression::addMatches(this, #array, array , ## __VA_ARGS__) #define SANITY_CHECK_MATCHES(array, ...) ::perf::Regression::addMatches(this, #array, array , ## __VA_ARGS__)
#ifdef HAVE_CUDA
class CV_EXPORTS GpuPerf class CV_EXPORTS GpuPerf
{ {
public: public:
...@@ -216,9 +215,6 @@ public: ...@@ -216,9 +215,6 @@ public:
}; };
# define PERF_RUN_GPU() ::perf::GpuPerf::targetDevice() # define PERF_RUN_GPU() ::perf::GpuPerf::targetDevice()
#else
# define PERF_RUN_GPU() false
#endif
/*****************************************************************************************\ /*****************************************************************************************\
......
...@@ -1324,12 +1324,14 @@ void perf::sort(std::vector<cv::KeyPoint>& pts, cv::InputOutputArray descriptors ...@@ -1324,12 +1324,14 @@ void perf::sort(std::vector<cv::KeyPoint>& pts, cv::InputOutputArray descriptors
/*****************************************************************************************\ /*****************************************************************************************\
* ::perf::GpuPerf * ::perf::GpuPerf
\*****************************************************************************************/ \*****************************************************************************************/
#ifdef HAVE_CUDA
bool perf::GpuPerf::targetDevice() bool perf::GpuPerf::targetDevice()
{ {
#ifdef HAVE_CUDA
return !param_run_cpu; return !param_run_cpu;
} #else
return false;
#endif #endif
}
/*****************************************************************************************\ /*****************************************************************************************\
* ::perf::PrintTo * ::perf::PrintTo
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment