Path: blob/master/modules/videostab/test/test_motion_estimation.cpp
16337 views
// This file is part of OpenCV project.1// It is subject to the license terms in the LICENSE file found in the top-level directory2// of this distribution and at http://opencv.org/license.html34#include "test_precomp.hpp"56namespace opencv_test { namespace {78namespace testUtil9{1011cv::RNG rng(/*std::time(0)*/0);1213const float sigma = 1.f;14const float pointsMaxX = 500.f;15const float pointsMaxY = 500.f;16const int testRun = 5000;1718void generatePoints(cv::Mat points);19void addNoise(cv::Mat points);2021cv::Mat generateTransform(const cv::videostab::MotionModel model);2223double performTest(const cv::videostab::MotionModel model, int size);2425}2627void testUtil::generatePoints(cv::Mat points)28{29CV_Assert(!points.empty());30for(int i = 0; i < points.cols; ++i)31{32points.at<float>(0, i) = rng.uniform(0.f, pointsMaxX);33points.at<float>(1, i) = rng.uniform(0.f, pointsMaxY);34points.at<float>(2, i) = 1.f;35}36}3738void testUtil::addNoise(cv::Mat points)39{40CV_Assert(!points.empty());41for(int i = 0; i < points.cols; i++)42{43points.at<float>(0, i) += static_cast<float>(rng.gaussian(sigma));44points.at<float>(1, i) += static_cast<float>(rng.gaussian(sigma));4546}47}484950cv::Mat testUtil::generateTransform(const cv::videostab::MotionModel model)51{52/*----------Params----------*/53const float minAngle = 0.f, maxAngle = static_cast<float>(CV_PI);54const float minScale = 0.5f, maxScale = 2.f;55const float maxTranslation = 100.f;56const float affineCoeff = 3.f;57/*----------Params----------*/5859cv::Mat transform = cv::Mat::eye(3, 3, CV_32F);6061if(model != cv::videostab::MM_ROTATION)62{63transform.at<float>(0,2) = rng.uniform(-maxTranslation, maxTranslation);64transform.at<float>(1,2) = rng.uniform(-maxTranslation, maxTranslation);65}6667if(model != cv::videostab::MM_AFFINE)68{6970if(model != cv::videostab::MM_TRANSLATION_AND_SCALE &&71model != cv::videostab::MM_TRANSLATION)72{73const float angle = rng.uniform(minAngle, maxAngle);7475transform.at<float>(1,1) = transform.at<float>(0,0) = std::cos(angle);76transform.at<float>(0,1) = std::sin(angle);77transform.at<float>(1,0) = -transform.at<float>(0,1);7879}8081if(model == cv::videostab::MM_TRANSLATION_AND_SCALE ||82model == cv::videostab::MM_SIMILARITY)83{84const float scale = rng.uniform(minScale, maxScale);8586transform.at<float>(0,0) *= scale;87transform.at<float>(1,1) *= scale;8889}9091}92else93{94transform.at<float>(0,0) = rng.uniform(-affineCoeff, affineCoeff);95transform.at<float>(0,1) = rng.uniform(-affineCoeff, affineCoeff);96transform.at<float>(1,0) = rng.uniform(-affineCoeff, affineCoeff);97transform.at<float>(1,1) = rng.uniform(-affineCoeff, affineCoeff);98}99100return transform;101}102103104double testUtil::performTest(const cv::videostab::MotionModel model, int size)105{106cv::Ptr<cv::videostab::MotionEstimatorRansacL2> estimator = cv::makePtr<cv::videostab::MotionEstimatorRansacL2>(model);107108estimator->setRansacParams(cv::videostab::RansacParams(size, 3.f*testUtil::sigma /*3 sigma rule*/, 0.5f, 0.5f));109110double disparity = 0.;111112for(int attempt = 0; attempt < testUtil::testRun; attempt++)113{114const cv::Mat transform = testUtil::generateTransform(model);115116const int pointsNumber = testUtil::rng.uniform(10, 100);117118cv::Mat points(3, pointsNumber, CV_32F);119120testUtil::generatePoints(points);121122cv::Mat transformedPoints = transform * points;123124testUtil::addNoise(transformedPoints);125126const cv::Mat src = points.rowRange(0,2).t();127const cv::Mat dst = transformedPoints.rowRange(0,2).t();128129bool isOK = false;130const cv::Mat estTransform = estimator->estimate(src.reshape(2), dst.reshape(2), &isOK);131132CV_Assert(isOK);133const cv::Mat testPoints = estTransform * points;134135const double norm = cv::norm(testPoints, transformedPoints, cv::NORM_INF);136137disparity = std::max(disparity, norm);138}139140return disparity;141142}143144TEST(Regression, MM_TRANSLATION)145{146EXPECT_LT(testUtil::performTest(cv::videostab::MM_TRANSLATION, 2), 7.f);147}148149TEST(Regression, MM_TRANSLATION_AND_SCALE)150{151EXPECT_LT(testUtil::performTest(cv::videostab::MM_TRANSLATION_AND_SCALE, 3), 7.f);152}153154TEST(Regression, MM_ROTATION)155{156EXPECT_LT(testUtil::performTest(cv::videostab::MM_ROTATION, 2), 7.f);157}158159TEST(Regression, MM_RIGID)160{161EXPECT_LT(testUtil::performTest(cv::videostab::MM_RIGID, 3), 7.f);162}163164TEST(Regression, MM_SIMILARITY)165{166EXPECT_LT(testUtil::performTest(cv::videostab::MM_SIMILARITY, 4), 7.f);167}168169TEST(Regression, MM_AFFINE)170{171EXPECT_LT(testUtil::performTest(cv::videostab::MM_AFFINE, 6), 9.f);172}173174}} // namespace175176177