diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index 72c7fc8308a44d3ac188cb1fa2135336b39c2f00..91b65f59aad65504ac4f9c9444431f0f480067b2 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -581,7 +581,7 @@ function(ocv_add_perf_tests) __ocv_parse_test_sources(PERF ${ARGN}) # opencv_highgui is required for imread/imwrite - set(perf_deps ${the_module} opencv_ts opencv_highgui ${OPENCV_PERF_${the_module}_DEPS}) + set(perf_deps ${the_module} opencv_ts opencv_highgui ${OPENCV_PERF_${the_module}_DEPS} ${OPENCV_MODULE_opencv_ts_DEPS}) ocv_check_dependencies(${perf_deps}) if(OCV_DEPENDENCIES_FOUND) @@ -632,7 +632,7 @@ function(ocv_add_accuracy_tests) __ocv_parse_test_sources(TEST ${ARGN}) # opencv_highgui is required for imread/imwrite - set(test_deps ${the_module} opencv_ts opencv_highgui ${OPENCV_TEST_${the_module}_DEPS}) + set(test_deps ${the_module} opencv_ts opencv_highgui ${OPENCV_TEST_${the_module}_DEPS} ${OPENCV_MODULE_opencv_ts_DEPS}) ocv_check_dependencies(${test_deps}) if(OCV_DEPENDENCIES_FOUND) diff --git a/modules/calib3d/perf/perf_pnp.cpp b/modules/calib3d/perf/perf_pnp.cpp index 746f548e847e077cdab97445fd21417d7bb705b7..b32b96cae2a6f3c2228be19d02b196a56d78ed21 100644 --- a/modules/calib3d/perf/perf_pnp.cpp +++ b/modules/calib3d/perf/perf_pnp.cpp @@ -1,4 +1,5 @@ #include "perf_precomp.hpp" +#include "opencv2/core/internal.hpp" using namespace std; using namespace cv; @@ -48,7 +49,10 @@ PERF_TEST_P(PointsNum_Algo, solvePnP, declare.in(points3d, points2d); - TEST_CYCLE_N(1000) solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo); + TEST_CYCLE_N(1000) + { + solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, algo); + } SANITY_CHECK(rvec, 1e-6); SANITY_CHECK(tvec, 1e-6); @@ -83,7 +87,10 @@ PERF_TEST(PointsNum_Algo, solveP3P) declare.in(points3d, points2d); - TEST_CYCLE_N(1000) solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, CV_P3P); + TEST_CYCLE_N(1000) + { + solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false, CV_P3P); + } SANITY_CHECK(rvec, 1e-6); SANITY_CHECK(tvec, 1e-6); @@ -117,9 +124,10 @@ PERF_TEST_P(PointsNum, SolvePnPRansac, testing::Values(4, 3*9, 7*13)) Mat rvec; Mat tvec; - solvePnPRansac(object, image, camera_mat, dist_coef, rvec, tvec); - - declare.time(3.0); +#ifdef HAVE_TBB + // limit concurrency to get determenistic result + cv::Ptr one_thread = new tbb::task_scheduler_init(1); +#endif TEST_CYCLE() { diff --git a/modules/calib3d/src/solvepnp.cpp b/modules/calib3d/src/solvepnp.cpp index 125d7a9fa6ef4df0f6d0c0de8cfa38eb1fdbcfe3..25988be48a6cb7d248a1bcfb5b65fdd652089aa5 100644 --- a/modules/calib3d/src/solvepnp.cpp +++ b/modules/calib3d/src/solvepnp.cpp @@ -260,6 +260,8 @@ namespace cv { rvec.copyTo(initRvec); tvec.copyTo(initTvec); + + generator.state = theRNG().state; //to control it somehow... } private: PnPSolver& operator=(const PnPSolver&); diff --git a/modules/features2d/perf/perf_batchDistance.cpp b/modules/features2d/perf/perf_batchDistance.cpp index e95a41c1df4556e1e7a848507dd2510f96cff3b8..aa57d88d0508615b385a585e424ce12725328745 100644 --- a/modules/features2d/perf/perf_batchDistance.cpp +++ b/modules/features2d/perf/perf_batchDistance.cpp @@ -6,17 +6,15 @@ using namespace perf; using std::tr1::make_tuple; using std::tr1::get; -CV_FLAGS(NormType, NORM_L1, NORM_L2, NORM_L2SQR, NORM_HAMMING, NORM_HAMMING2) -CV_ENUM(SourceType, CV_32F, CV_8U) -CV_ENUM(DestinationType, CV_32F, CV_32S) +CV_ENUM(NormType, NORM_L1, NORM_L2, NORM_L2SQR, NORM_HAMMING, NORM_HAMMING2) -typedef std::tr1::tuple Norm_Destination_CrossCheck_t; +typedef std::tr1::tuple Norm_Destination_CrossCheck_t; typedef perf::TestBaseWithParam Norm_Destination_CrossCheck; typedef std::tr1::tuple Norm_CrossCheck_t; typedef perf::TestBaseWithParam Norm_CrossCheck; -typedef std::tr1::tuple Source_CrossCheck_t; +typedef std::tr1::tuple Source_CrossCheck_t; typedef perf::TestBaseWithParam Source_CrossCheck; void generateData( Mat& query, Mat& train, const int sourceType ); @@ -29,27 +27,25 @@ PERF_TEST_P(Norm_Destination_CrossCheck, batchDistance_8U, ) { NormType normType = get<0>(GetParam()); - DestinationType destinationType = get<1>(GetParam()); + int destinationType = get<1>(GetParam()); bool isCrossCheck = get<2>(GetParam()); + int knn = isCrossCheck ? 1 : 0; Mat queryDescriptors; Mat trainDescriptors; Mat dist; Mat ndix; - int knn = 1; generateData(queryDescriptors, trainDescriptors, CV_8U); - if(!isCrossCheck) - { - knn = 0; - } - declare.time(30); TEST_CYCLE() { batchDistance(queryDescriptors, trainDescriptors, dist, destinationType, (isCrossCheck) ? ndix : noArray(), normType, knn, Mat(), 0, isCrossCheck); } + + SANITY_CHECK(dist); + if (isCrossCheck) SANITY_CHECK(ndix); } PERF_TEST_P(Norm_CrossCheck, batchDistance_Dest_32S, @@ -60,25 +56,23 @@ PERF_TEST_P(Norm_CrossCheck, batchDistance_Dest_32S, { NormType normType = get<0>(GetParam()); bool isCrossCheck = get<1>(GetParam()); + int knn = isCrossCheck ? 1 : 0; Mat queryDescriptors; Mat trainDescriptors; Mat dist; Mat ndix; - int knn = 1; generateData(queryDescriptors, trainDescriptors, CV_8U); - if(!isCrossCheck) - { - knn = 0; - } - declare.time(30); TEST_CYCLE() { batchDistance(queryDescriptors, trainDescriptors, dist, CV_32S, (isCrossCheck) ? ndix : noArray(), normType, knn, Mat(), 0, isCrossCheck); } + + SANITY_CHECK(dist); + if (isCrossCheck) SANITY_CHECK(ndix); } PERF_TEST_P(Source_CrossCheck, batchDistance_L2, @@ -87,27 +81,25 @@ PERF_TEST_P(Source_CrossCheck, batchDistance_L2, ) ) { - SourceType sourceType = get<0>(GetParam()); + int sourceType = get<0>(GetParam()); bool isCrossCheck = get<1>(GetParam()); + int knn = isCrossCheck ? 1 : 0; Mat queryDescriptors; Mat trainDescriptors; Mat dist; Mat ndix; - int knn = 1; generateData(queryDescriptors, trainDescriptors, sourceType); - if(!isCrossCheck) - { - knn = 0; - } - declare.time(30); TEST_CYCLE() { batchDistance(queryDescriptors, trainDescriptors, dist, CV_32F, (isCrossCheck) ? ndix : noArray(), NORM_L2, knn, Mat(), 0, isCrossCheck); } + + SANITY_CHECK(dist); + if (isCrossCheck) SANITY_CHECK(ndix); } PERF_TEST_P(Norm_CrossCheck, batchDistance_32F, @@ -118,25 +110,23 @@ PERF_TEST_P(Norm_CrossCheck, batchDistance_32F, { NormType normType = get<0>(GetParam()); bool isCrossCheck = get<1>(GetParam()); + int knn = isCrossCheck ? 1 : 0; Mat queryDescriptors; Mat trainDescriptors; Mat dist; Mat ndix; - int knn = 1; generateData(queryDescriptors, trainDescriptors, CV_32F); - if(!isCrossCheck) - { - knn = 0; - } - declare.time(30); TEST_CYCLE() { batchDistance(queryDescriptors, trainDescriptors, dist, CV_32F, (isCrossCheck) ? ndix : noArray(), normType, knn, Mat(), 0, isCrossCheck); } + + SANITY_CHECK(dist); + if (isCrossCheck) SANITY_CHECK(ndix); } void generateData( Mat& query, Mat& train, const int sourceType ) diff --git a/modules/features2d/perf/perf_fast.cpp b/modules/features2d/perf/perf_fast.cpp index 0abf56b565bf3c758768947356355986f5d4836b..f550f7b33e05638edb5dc94ad9b3cb388062425d 100644 --- a/modules/features2d/perf/perf_fast.cpp +++ b/modules/features2d/perf/perf_fast.cpp @@ -6,15 +6,23 @@ using namespace perf; using std::tr1::make_tuple; using std::tr1::get; -typedef perf::TestBaseWithParam fast; +enum { TYPE_5_8 =FastFeatureDetector::TYPE_5_8, TYPE_7_12 = FastFeatureDetector::TYPE_7_12, TYPE_9_16 = FastFeatureDetector::TYPE_9_16 }; +CV_ENUM(FastType, TYPE_5_8, TYPE_7_12, TYPE_9_16) + +typedef std::tr1::tuple File_Type_t; +typedef perf::TestBaseWithParam fast; #define FAST_IMAGES \ "cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png",\ "stitching/a3.png" -PERF_TEST_P(fast, detectForORB, testing::Values(FAST_IMAGES)) +PERF_TEST_P(fast, detect, testing::Combine( + testing::Values(FAST_IMAGES), + testing::ValuesIn(FastType::all()) + )) { - String filename = getDataPath(GetParam()); + String filename = getDataPath(get<0>(GetParam())); + int type = get<1>(GetParam()); Mat frame = imread(filename, IMREAD_GRAYSCALE); if (frame.empty()) @@ -22,13 +30,11 @@ PERF_TEST_P(fast, detectForORB, testing::Values(FAST_IMAGES)) declare.in(frame); - FastFeatureDetector fd(20, true, FastFeatureDetector::TYPE_5_8); + FastFeatureDetector fd(20, true, type); vector points; TEST_CYCLE() fd.detect(frame, points); - fd = FastFeatureDetector(20, true, FastFeatureDetector::TYPE_7_12); - TEST_CYCLE() fd.detect(frame, points); - fd = FastFeatureDetector(20, true, FastFeatureDetector::TYPE_9_16); - TEST_CYCLE() fd.detect(frame, points); + + SANITY_CHECK_KEYPOINTS(points); } diff --git a/modules/features2d/perf/perf_orb.cpp b/modules/features2d/perf/perf_orb.cpp index d318533ec9084e64798b97ecf275765f6e2baf69..cf7b46b648c48a30b609f73ba081a5f65b7e9ed8 100644 --- a/modules/features2d/perf/perf_orb.cpp +++ b/modules/features2d/perf/perf_orb.cpp @@ -26,6 +26,8 @@ PERF_TEST_P(orb, detect, testing::Values(ORB_IMAGES)) vector points; TEST_CYCLE() detector(frame, mask, points); + + SANITY_CHECK_KEYPOINTS(points); } PERF_TEST_P(orb, extract, testing::Values(ORB_IMAGES)) @@ -46,6 +48,8 @@ PERF_TEST_P(orb, extract, testing::Values(ORB_IMAGES)) Mat descriptors; TEST_CYCLE() detector(frame, mask, points, descriptors, true); + + SANITY_CHECK(descriptors); } PERF_TEST_P(orb, full, testing::Values(ORB_IMAGES)) @@ -64,4 +68,7 @@ PERF_TEST_P(orb, full, testing::Values(ORB_IMAGES)) Mat descriptors; TEST_CYCLE() detector(frame, mask, points, descriptors, false); + + SANITY_CHECK_KEYPOINTS(points); + SANITY_CHECK(descriptors); } diff --git a/modules/ts/CMakeLists.txt b/modules/ts/CMakeLists.txt index c50b396faf4eb7c0e6fc7fc4a4877a9d127276fb..455ef876bd73fa61c0d1d56b0c14ed20d1c82798 100644 --- a/modules/ts/CMakeLists.txt +++ b/modules/ts/CMakeLists.txt @@ -10,7 +10,8 @@ endif() set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE) -ocv_add_module(ts opencv_core) +ocv_add_module(ts opencv_core opencv_features2d) + ocv_glob_module_sources() ocv_module_include_directories() ocv_create_module() diff --git a/modules/ts/include/opencv2/ts/ts_perf.hpp b/modules/ts/include/opencv2/ts/ts_perf.hpp index 449b43450484d96a204cc9372131997eda8d6f70..81d2235d51dc4272fb6e53c1497be1e2de8a4052 100644 --- a/modules/ts/include/opencv2/ts/ts_perf.hpp +++ b/modules/ts/include/opencv2/ts/ts_perf.hpp @@ -2,6 +2,7 @@ #define __OPENCV_TS_PERF_HPP__ #include "opencv2/core/core.hpp" +#include "opencv2/features2d/features2d.hpp" #include "ts_gtest.h" #ifdef HAVE_TBB @@ -165,6 +166,7 @@ class CV_EXPORTS Regression { public: static Regression& add(TestBase* test, const std::string& name, cv::InputArray array, double eps = DBL_EPSILON, ERROR_TYPE err = ERROR_ABSOLUTE); + static Regression& addKeypoints(TestBase* test, const std::string& name, const std::vector& array, double eps = DBL_EPSILON, ERROR_TYPE err = ERROR_ABSOLUTE); static void Init(const std::string& testSuitName, const std::string& ext = ".xml"); Regression& operator() (const std::string& name, cv::InputArray array, double eps = DBL_EPSILON, ERROR_TYPE err = ERROR_ABSOLUTE); @@ -199,6 +201,7 @@ private: }; #define SANITY_CHECK(array, ...) ::perf::Regression::add(this, #array, array , ## __VA_ARGS__) +#define SANITY_CHECK_KEYPOINTS(array, ...) ::perf::Regression::addKeypoints(this, #array, array , ## __VA_ARGS__) /*****************************************************************************************\ diff --git a/modules/ts/src/ts_perf.cpp b/modules/ts/src/ts_perf.cpp index 5467d618daceac11268a92e07a6fb72e5e115de8..24b91f0185a341ae8739bef3350d5a5b4e51ef7d 100644 --- a/modules/ts/src/ts_perf.cpp +++ b/modules/ts/src/ts_perf.cpp @@ -103,6 +103,24 @@ Regression& Regression::add(TestBase* test, const std::string& name, cv::InputAr return instance()(name, array, eps, err); } +Regression& Regression::addKeypoints(TestBase* test, const std::string& name, const std::vector& array, double eps, ERROR_TYPE err) +{ + int len = (int)array.size(); + cv::Mat pt (len, 1, CV_32FC2, (void*)&array[0].pt, sizeof(cv::KeyPoint)); + cv::Mat size (len, 1, CV_32FC1, (void*)&array[0].size, sizeof(cv::KeyPoint)); + cv::Mat angle (len, 1, CV_32FC1, (void*)&array[0].angle, sizeof(cv::KeyPoint)); + cv::Mat response(len, 1, CV_32FC1, (void*)&array[0].response, sizeof(cv::KeyPoint)); + cv::Mat octave (len, 1, CV_32SC1, (void*)&array[0].octave, sizeof(cv::KeyPoint)); + cv::Mat class_id(len, 1, CV_32SC1, (void*)&array[0].class_id, sizeof(cv::KeyPoint)); + + return Regression::add(test, name + "-pt", pt, eps, ERROR_ABSOLUTE) + (name + "-size", size, eps, ERROR_ABSOLUTE) + (name + "-angle", angle, eps, ERROR_ABSOLUTE) + (name + "-response", response, eps, err) + (name + "-octave", octave, eps, ERROR_ABSOLUTE) + (name + "-class_id", class_id, eps, ERROR_ABSOLUTE); +} + void Regression::Init(const std::string& testSuitName, const std::string& ext) { instance().init(testSuitName, ext); @@ -490,6 +508,12 @@ void Regression::verify(cv::FileNode node, cv::InputArray array, double eps, ERR Regression& Regression::operator() (const std::string& name, cv::InputArray array, double eps, ERROR_TYPE err) { + if(!array.empty() && array.depth() == CV_USRTYPE1) + { + ADD_FAILURE() << " Can not check regression for CV_USRTYPE1 data type for " << name; + return *this; + } + std::string nodename = getCurrentTestNodeName(); cv::FileNode n = rootIn[nodename]; @@ -674,6 +698,8 @@ cv::Size TestBase::getSize(cv::InputArray a) bool TestBase::next() { bool has_next = ++currentIter < nIters && totalTime < timeLimit; + cv::theRNG().state = param_seed; //this rng should generate same numbers for each run + #ifdef ANDROID if (log_power_checkpoints) { @@ -948,7 +974,6 @@ void TestBase::SetUp() currentIter = (unsigned int)-1; timeLimit = timeLimitDefault; times.clear(); - cv::theRNG().state = param_seed;//this rng should generate same numbers for each run } void TestBase::TearDown() diff --git a/modules/video/perf/perf_optflowpyrlk.cpp b/modules/video/perf/perf_optflowpyrlk.cpp index b5445330db320e6b8b95d292242eb603d2c1ade5..07d896cf015d142b586bb40096c5a21dc323a013 100644 --- a/modules/video/perf/perf_optflowpyrlk.cpp +++ b/modules/video/perf/perf_optflowpyrlk.cpp @@ -91,6 +91,10 @@ PERF_TEST_P(Path_Idx_Cn_NPoints_WSize, OpticalFlowPyrLK_full, testing::Combine( Size(winSize, winSize), maxLevel, criteria, flags, minEigThreshold); } + + SANITY_CHECK(outPoints); + SANITY_CHECK(status); + SANITY_CHECK(err, 1e-5); } typedef tr1::tuple, int, bool> Path_Idx_Cn_NPoints_WSize_Deriv_t; @@ -166,6 +170,10 @@ PERF_TEST_P(Path_Idx_Cn_NPoints_WSize_Deriv, OpticalFlowPyrLK_self, testing::Com Size(winSize, winSize), maxLevel, criteria, flags, minEigThreshold); } + + SANITY_CHECK(outPoints); + SANITY_CHECK(status); + SANITY_CHECK(err, 1e-5); } CV_ENUM(PyrBorderMode, BORDER_DEFAULT, BORDER_TRANSPARENT);