Path: blob/master/modules/videostab/src/outlier_rejection.cpp
16339 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.13// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.14// Third party copyrights are property of their respective owners.15//16// Redistribution and use in source and binary forms, with or without modification,17// are permitted provided that the following conditions are met:18//19// * Redistribution's of source code must retain the above copyright notice,20// this list of conditions and the following disclaimer.21//22// * Redistribution's in binary form must reproduce the above copyright notice,23// this list of conditions and the following disclaimer in the documentation24// and/or other materials provided with the distribution.25//26// * The name of the copyright holders may not be used to endorse or promote products27// derived from this software without specific prior written permission.28//29// This software is provided by the copyright holders and contributors "as is" and30// any express or implied warranties, including, but not limited to, the implied31// warranties of merchantability and fitness for a particular purpose are disclaimed.32// In no event shall the Intel Corporation or contributors be liable for any direct,33// indirect, incidental, special, exemplary, or consequential damages34// (including, but not limited to, procurement of substitute goods or services;35// loss of use, data, or profits; or business interruption) however caused36// and on any theory of liability, whether in contract, strict liability,37// or tort (including negligence or otherwise) arising in any way out of38// the use of this software, even if advised of the possibility of such damage.39//40//M*/4142#include "precomp.hpp"43#include "opencv2/videostab/outlier_rejection.hpp"4445namespace cv46{47namespace videostab48{4950void NullOutlierRejector::process(51Size /*frameSize*/, InputArray points0, InputArray points1, OutputArray mask)52{53CV_INSTRUMENT_REGION();5455CV_Assert(points0.type() == points1.type());56CV_Assert(points0.getMat().checkVector(2) == points1.getMat().checkVector(2));5758int npoints = points0.getMat().checkVector(2);59mask.create(1, npoints, CV_8U);60Mat mask_ = mask.getMat();61mask_.setTo(1);62}6364TranslationBasedLocalOutlierRejector::TranslationBasedLocalOutlierRejector()65{66setCellSize(Size(50, 50));67setRansacParams(RansacParams::default2dMotion(MM_TRANSLATION));68}697071void TranslationBasedLocalOutlierRejector::process(72Size frameSize, InputArray points0, InputArray points1, OutputArray mask)73{74CV_INSTRUMENT_REGION();7576CV_Assert(points0.type() == points1.type());77CV_Assert(points0.getMat().checkVector(2) == points1.getMat().checkVector(2));7879int npoints = points0.getMat().checkVector(2);8081const Point2f* points0_ = points0.getMat().ptr<Point2f>();82const Point2f* points1_ = points1.getMat().ptr<Point2f>();8384mask.create(1, npoints, CV_8U);85uchar* mask_ = mask.getMat().ptr<uchar>();8687Size ncells((frameSize.width + cellSize_.width - 1) / cellSize_.width,88(frameSize.height + cellSize_.height - 1) / cellSize_.height);8990// fill grid cells9192grid_.assign(ncells.area(), Cell());9394for (int i = 0; i < npoints; ++i)95{96int cx = std::min(cvRound(points0_[i].x / cellSize_.width), ncells.width - 1);97int cy = std::min(cvRound(points0_[i].y / cellSize_.height), ncells.height - 1);98grid_[cy * ncells.width + cx].push_back(i);99}100101// process each cell102103RNG rng(0);104int niters = ransacParams_.niters();105std::vector<int> inliers;106107for (size_t ci = 0; ci < grid_.size(); ++ci)108{109// estimate translation model at the current cell using RANSAC110111float x1, y1;112const Cell &cell = grid_[ci];113int ninliers, ninliersMax = 0;114float dxBest = 0.f, dyBest = 0.f;115116// find the best hypothesis117118if (!cell.empty())119{120for (int iter = 0; iter < niters; ++iter)121{122int idx = cell[static_cast<unsigned>(rng) % cell.size()];123float dx = points1_[idx].x - points0_[idx].x;124float dy = points1_[idx].y - points0_[idx].y;125126ninliers = 0;127for (size_t i = 0; i < cell.size(); ++i)128{129x1 = points0_[cell[i]].x + dx;130y1 = points0_[cell[i]].y + dy;131if (sqr(x1 - points1_[cell[i]].x) + sqr(y1 - points1_[cell[i]].y) <132sqr(ransacParams_.thresh))133{134ninliers++;135}136}137138if (ninliers > ninliersMax)139{140ninliersMax = ninliers;141dxBest = dx;142dyBest = dy;143}144}145}146147// get the best hypothesis inliers148149ninliers = 0;150inliers.resize(ninliersMax);151for (size_t i = 0; i < cell.size(); ++i)152{153x1 = points0_[cell[i]].x + dxBest;154y1 = points0_[cell[i]].y + dyBest;155if (sqr(x1 - points1_[cell[i]].x) + sqr(y1 - points1_[cell[i]].y) <156sqr(ransacParams_.thresh))157{158inliers[ninliers++] = cell[i];159}160}161162// refine the best hypothesis163164dxBest = dyBest = 0.f;165for (size_t i = 0; i < inliers.size(); ++i)166{167dxBest += points1_[inliers[i]].x - points0_[inliers[i]].x;168dyBest += points1_[inliers[i]].y - points0_[inliers[i]].y;169}170if (!inliers.empty())171{172dxBest /= inliers.size();173dyBest /= inliers.size();174}175176// set mask elements for refined model inliers177178for (size_t i = 0; i < cell.size(); ++i)179{180x1 = points0_[cell[i]].x + dxBest;181y1 = points0_[cell[i]].y + dyBest;182if (sqr(x1 - points1_[cell[i]].x) + sqr(y1 - points1_[cell[i]].y) <183sqr(ransacParams_.thresh))184{185mask_[cell[i]] = 1;186}187else188{189mask_[cell[i]] = 0;190}191}192}193}194195} // namespace videostab196} // namespace cv197198199