You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
5.9 KiB
195 lines
5.9 KiB
/* |
|
* Software License Agreement (BSD License) |
|
* |
|
* Copyright (c) 2009, Willow Garage, Inc. |
|
* All rights reserved. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions |
|
* are met: |
|
* |
|
* * Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* * Redistributions in binary form must reproduce the above |
|
* copyright notice, this list of conditions and the following |
|
* disclaimer in the documentation and/or other materials provided |
|
* with the distribution. |
|
* * Neither the name of Willow Garage, Inc. nor the names of its |
|
* contributors may be used to endorse or promote products derived |
|
* from this software without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
* POSSIBILITY OF SUCH DAMAGE. |
|
* |
|
*/ |
|
|
|
#include "precomp.hpp" |
|
|
|
// Eigen |
|
#include <Eigen/Core> |
|
|
|
// OpenCV |
|
#include <opencv2/core/eigen.hpp> |
|
#include <opencv2/sfm/robust.hpp> |
|
#include <opencv2/sfm/numeric.hpp> |
|
|
|
// libmv headers |
|
#include "libmv/multiview/robust_fundamental.h" |
|
|
|
using namespace std; |
|
|
|
namespace cv |
|
{ |
|
namespace sfm |
|
{ |
|
|
|
// TODO: unify algorithms |
|
template<typename T> |
|
double |
|
fundamentalFromCorrespondences8PointRobust( const Mat_<T> &_x1, |
|
const Mat_<T> &_x2, |
|
const double max_error, |
|
Mat_<T> _F, |
|
std::vector<int> &_inliers, |
|
const double outliers_probability ) |
|
{ |
|
libmv::Mat x1, x2; |
|
libmv::Mat3 F; |
|
libmv::vector<int> inliers; |
|
|
|
cv2eigen( _x1, x1 ); |
|
cv2eigen( _x2, x2 ); |
|
|
|
T solution_error = |
|
libmv::FundamentalFromCorrespondences8PointRobust( x1, x2, max_error, &F, &inliers, outliers_probability ); |
|
|
|
eigen2cv( F, _F ); |
|
|
|
// transform from libmv::vector to std::vector |
|
int n = inliers.size(); |
|
_inliers.resize(n); |
|
for( int i=0; i < n; ++i ) |
|
{ |
|
_inliers[i] = inliers.at(i); |
|
} |
|
|
|
return static_cast<double>(solution_error); |
|
} |
|
|
|
|
|
double |
|
fundamentalFromCorrespondences8PointRobust( InputArray _x1, |
|
InputArray _x2, |
|
double max_error, |
|
OutputArray _F, |
|
OutputArray _inliers, |
|
double outliers_probability ) |
|
{ |
|
const Mat x1 = _x1.getMat(), x2 = _x2.getMat(); |
|
const int depth = x1.depth(); |
|
CV_Assert(x1.size() == x2.size() && (depth == CV_32F || depth == CV_64F)); |
|
|
|
_F.create(3, 3, depth); |
|
|
|
Mat F = _F.getMat(); |
|
std::vector<int>& inliers = *(std::vector<int>*)_inliers.getObj(); |
|
|
|
double solution_error = 0.0; |
|
|
|
// type |
|
if( depth == CV_32F ) |
|
{ |
|
solution_error = |
|
fundamentalFromCorrespondences8PointRobust<float>( |
|
x1, x2, max_error, F, inliers, outliers_probability); |
|
} |
|
else |
|
{ |
|
solution_error = |
|
fundamentalFromCorrespondences8PointRobust<double>( |
|
x1, x2, max_error, F, inliers, outliers_probability); |
|
} |
|
|
|
return solution_error; |
|
} |
|
|
|
template<typename T> |
|
double |
|
fundamentalFromCorrespondences7PointRobust( const Mat_<T> &_x1, |
|
const Mat_<T> &_x2, |
|
const double max_error, |
|
Mat_<T> _F, |
|
std::vector<int> &_inliers, |
|
const double outliers_probability ) |
|
{ |
|
libmv::Mat x1, x2; |
|
libmv::Mat3 F; |
|
libmv::vector<int> inliers; |
|
|
|
cv2eigen( _x1, x1 ); |
|
cv2eigen( _x2, x2 ); |
|
|
|
T solution_error = |
|
libmv::FundamentalFromCorrespondences7PointRobust( x1, x2, max_error, &F, &inliers, outliers_probability ); |
|
|
|
eigen2cv( F, _F ); |
|
|
|
// transform from libmv::vector to std::vector |
|
int n = inliers.size(); |
|
_inliers.resize(n); |
|
for( int i=0; i < n; ++i ) |
|
{ |
|
_inliers[i] = inliers.at(i); |
|
} |
|
|
|
return static_cast<double>(solution_error); |
|
} |
|
|
|
double |
|
fundamentalFromCorrespondences7PointRobust( InputArray _x1, |
|
InputArray _x2, |
|
double max_error, |
|
OutputArray _F, |
|
OutputArray _inliers, |
|
double outliers_probability ) |
|
{ |
|
const Mat x1 = _x1.getMat(), x2 = _x2.getMat(); |
|
const int depth = x1.depth(); |
|
CV_Assert(x1.size() == x2.size() && (depth == CV_32F || depth == CV_64F)); |
|
|
|
_F.create(3, 3, depth); |
|
|
|
Mat F = _F.getMat(); |
|
std::vector<int>& inliers = *(std::vector<int>*)_inliers.getObj(); |
|
|
|
double solution_error = 0.0; |
|
|
|
// type |
|
if( depth == CV_32F ) |
|
{ |
|
solution_error = |
|
fundamentalFromCorrespondences7PointRobust<float>( |
|
x1, x2, max_error, F, inliers, outliers_probability); |
|
} |
|
else |
|
{ |
|
solution_error = |
|
fundamentalFromCorrespondences7PointRobust<double>( |
|
x1, x2, max_error, F, inliers, outliers_probability); |
|
} |
|
|
|
return solution_error; |
|
} |
|
|
|
} /* namespace sfm */ |
|
} /* namespace cv */ |