From d99a1a4e889a49f579cd9bdf41eed049ae5a2b62 Mon Sep 17 00:00:00 2001 From: ZhangJiahui Date: Thu, 5 Mar 2020 17:03:20 +0800 Subject: [PATCH 1/8] copy from opencv to fix --- .../graph-cut-ransac/include/ImathRoots.h | 219 ++++++++++++++++++ .../solver_fundamental_matrix_seven_point.h | 30 +-- 2 files changed, 234 insertions(+), 15 deletions(-) create mode 100644 src/pymagsac/graph-cut-ransac/include/ImathRoots.h diff --git a/src/pymagsac/graph-cut-ransac/include/ImathRoots.h b/src/pymagsac/graph-cut-ransac/include/ImathRoots.h new file mode 100644 index 0000000..036b7f7 --- /dev/null +++ b/src/pymagsac/graph-cut-ransac/include/ImathRoots.h @@ -0,0 +1,219 @@ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// 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 Industrial Light & Magic 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. +// +/////////////////////////////////////////////////////////////////////////// + + + +#ifndef INCLUDED_IMATHROOTS_H +#define INCLUDED_IMATHROOTS_H + +//--------------------------------------------------------------------- +// +// Functions to solve linear, quadratic or cubic equations +// +//--------------------------------------------------------------------- + +#include "ImathMath.h" +#include "ImathNamespace.h" +#include + +IMATH_INTERNAL_NAMESPACE_HEADER_ENTER + +//-------------------------------------------------------------------------- +// Find the real solutions of a linear, quadratic or cubic equation: +// +// function equation solved +// +// solveLinear (a, b, x) a * x + b == 0 +// solveQuadratic (a, b, c, x) a * x*x + b * x + c == 0 +// solveNormalizedCubic (r, s, t, x) x*x*x + r * x*x + s * x + t == 0 +// solveCubic (a, b, c, d, x) a * x*x*x + b * x*x + c * x + d == 0 +// +// Return value: +// +// 3 three real solutions, stored in x[0], x[1] and x[2] +// 2 two real solutions, stored in x[0] and x[1] +// 1 one real solution, stored in x[1] +// 0 no real solutions +// -1 all real numbers are solutions +// +// Notes: +// +// * It is possible that an equation has real solutions, but that the +// solutions (or some intermediate result) are not representable. +// In this case, either some of the solutions returned are invalid +// (nan or infinity), or, if floating-point exceptions have been +// enabled with Iex::mathExcOn(), an Iex::MathExc exception is +// thrown. +// +// * Cubic equations are solved using Cardano's Formula; even though +// only real solutions are produced, some intermediate results are +// complex (std::complex). +// +//-------------------------------------------------------------------------- + +template int solveLinear (T a, T b, T &x); +template int solveQuadratic (T a, T b, T c, T x[2]); +template int solveNormalizedCubic (T r, T s, T t, T x[3]); +template int solveCubic (T a, T b, T c, T d, T x[3]); + + +//--------------- +// Implementation +//--------------- + +template +int +solveLinear (T a, T b, T &x) +{ + if (a != 0) + { + x = -b / a; + return 1; + } + else if (b != 0) + { + return 0; + } + else + { + return -1; + } +} + + +template +int +solveQuadratic (T a, T b, T c, T x[2]) +{ + if (a == 0) + { + return solveLinear (b, c, x[0]); + } + else + { + T D = b * b - 4 * a * c; + + if (D > 0) + { + T s = Math::sqrt (D); + T q = -(b + (b > 0 ? 1 : -1) * s) / T(2); + + x[0] = q / a; + x[1] = c / q; + return 2; + } + if (D == 0) + { + x[0] = -b / (2 * a); + return 1; + } + else + { + return 0; + } + } +} + + +template +int +solveNormalizedCubic (T r, T s, T t, T x[3]) +{ + T p = (3 * s - r * r) / 3; + T q = 2 * r * r * r / 27 - r * s / 3 + t; + T p3 = p / 3; + T q2 = q / 2; + T D = p3 * p3 * p3 + q2 * q2; + + if (D == 0 && p3 == 0) + { + x[0] = -r / 3; + x[1] = -r / 3; + x[2] = -r / 3; + return 1; + } + + std::complex u = std::pow (-q / 2 + std::sqrt (std::complex (D)), + T (1) / T (3)); + + std::complex v = -p / (T (3) * u); + + const T sqrt3 = T (1.73205080756887729352744634150587); // enough digits + // for long double + std::complex y0 (u + v); + + std::complex y1 (-(u + v) / T (2) + + (u - v) / T (2) * std::complex (0, sqrt3)); + + std::complex y2 (-(u + v) / T (2) - + (u - v) / T (2) * std::complex (0, sqrt3)); + + if (D > 0) + { + x[0] = y0.real() - r / 3; + return 1; + } + else if (D == 0) + { + x[0] = y0.real() - r / 3; + x[1] = y1.real() - r / 3; + return 2; + } + else + { + x[0] = y0.real() - r / 3; + x[1] = y1.real() - r / 3; + x[2] = y2.real() - r / 3; + return 3; + } +} + + +template +int +solveCubic (T a, T b, T c, T d, T x[3]) +{ + if (a == 0) + { + return solveQuadratic (b, c, d, x); + } + else + { + return solveNormalizedCubic (b / a, c / a, d / a, x); + } +} + +IMATH_INTERNAL_NAMESPACE_HEADER_EXIT + +#endif // INCLUDED_IMATHROOTS_H diff --git a/src/pymagsac/graph-cut-ransac/include/solver_fundamental_matrix_seven_point.h b/src/pymagsac/graph-cut-ransac/include/solver_fundamental_matrix_seven_point.h index 089abf4..7586efd 100644 --- a/src/pymagsac/graph-cut-ransac/include/solver_fundamental_matrix_seven_point.h +++ b/src/pymagsac/graph-cut-ransac/include/solver_fundamental_matrix_seven_point.h @@ -32,9 +32,10 @@ // Please contact the author of this library if you have any questions. // Author: Daniel Barath (barath.daniel@sztaki.mta.hu) #pragma once - +#include #include "solver_engine.h" #include "fundamental_estimator.h" +#include "ImathRoots.h" namespace gcransac { @@ -85,7 +86,9 @@ namespace gcransac Eigen::MatrixXd coefficients(sample_number_, 9); const double *data_ptr = reinterpret_cast(data_.data); const int cols = data_.cols; - double c[4]; + double c[4], r[3] = {0}; + Mat coeffs( 1, 4, CV_64F, c ); + Mat roots( 1, 3, CV_64F, r ); double t0, t1, t2; int i, n; @@ -168,9 +171,9 @@ namespace gcransac t1 = f2[3] * f2[8] - f2[5] * f2[6]; t2 = f2[3] * f2[7] - f2[4] * f2[6]; - c[0] = f2[0] * t0 - f2[1] * t1 + f2[2] * t2; + c[3] = f2[0] * t0 - f2[1] * t1 + f2[2] * t2; - c[1] = f1[0] * t0 - f1[1] * t1 + f1[2] * t2 - + c[2] = f1[0] * t0 - f1[1] * t1 + f1[2] * t2 - f1[3] * (f2[1] * f2[8] - f2[2] * f2[7]) + f1[4] * (f2[0] * f2[8] - f2[2] * f2[6]) - f1[5] * (f2[0] * f2[7] - f2[1] * f2[6]) + @@ -182,7 +185,7 @@ namespace gcransac t1 = f1[3] * f1[8] - f1[5] * f1[6]; t2 = f1[3] * f1[7] - f1[4] * f1[6]; - c[2] = f2[0] * t0 - f2[1] * t1 + f2[2] * t2 - + c[1] = f2[0] * t0 - f2[1] * t1 + f2[2] * t2 - f2[3] * (f1[1] * f1[8] - f1[2] * f1[7]) + f2[4] * (f1[0] * f1[8] - f1[2] * f1[6]) - f2[5] * (f1[0] * f1[7] - f1[1] * f1[6]) + @@ -190,20 +193,17 @@ namespace gcransac f2[7] * (f1[0] * f1[5] - f1[2] * f1[3]) + f2[8] * (f1[0] * f1[4] - f1[1] * f1[3]); - c[3] = f1[0] * t0 - f1[1] * t1 + f1[2] * t2; - - // solve the cubic equation; there can be 1 to 3 roots ... - Eigen::Matrix polynomial; - for (auto i = 0; i < 4; ++i) - polynomial(i) = c[i]; - Eigen::PolynomialSolver psolve(polynomial); + c[0] = f1[0] * t0 - f1[1] * t1 + f1[2] * t2; - std::vector real_roots; - psolve.realRoots(real_roots); + // n = real_roots.size(); + int n = solveCubic( coeffs, roots ); - n = real_roots.size(); if (n < 1 || n > 3) return false; + + std::vector real_roots; + for(int i = 0; i < n; i++) + real_roots[i] = r[i]; double f[8]; for (const double &root : real_roots) From f23aeb5e5c7c49ea91a46bcf5fe3d04ca56adbae Mon Sep 17 00:00:00 2001 From: zjhthu Date: Thu, 5 Mar 2020 18:55:13 +0800 Subject: [PATCH 2/8] can run --- .../graph-cut-ransac/include/ImathRoots.h | 219 ------------------ .../graph-cut-ransac/include/mathfunc.h | 171 ++++++++++++++ .../solver_fundamental_matrix_seven_point.h | 21 +- 3 files changed, 183 insertions(+), 228 deletions(-) delete mode 100644 src/pymagsac/graph-cut-ransac/include/ImathRoots.h create mode 100644 src/pymagsac/graph-cut-ransac/include/mathfunc.h diff --git a/src/pymagsac/graph-cut-ransac/include/ImathRoots.h b/src/pymagsac/graph-cut-ransac/include/ImathRoots.h deleted file mode 100644 index 036b7f7..0000000 --- a/src/pymagsac/graph-cut-ransac/include/ImathRoots.h +++ /dev/null @@ -1,219 +0,0 @@ -/////////////////////////////////////////////////////////////////////////// -// -// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas -// Digital Ltd. LLC -// -// 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 Industrial Light & Magic 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. -// -/////////////////////////////////////////////////////////////////////////// - - - -#ifndef INCLUDED_IMATHROOTS_H -#define INCLUDED_IMATHROOTS_H - -//--------------------------------------------------------------------- -// -// Functions to solve linear, quadratic or cubic equations -// -//--------------------------------------------------------------------- - -#include "ImathMath.h" -#include "ImathNamespace.h" -#include - -IMATH_INTERNAL_NAMESPACE_HEADER_ENTER - -//-------------------------------------------------------------------------- -// Find the real solutions of a linear, quadratic or cubic equation: -// -// function equation solved -// -// solveLinear (a, b, x) a * x + b == 0 -// solveQuadratic (a, b, c, x) a * x*x + b * x + c == 0 -// solveNormalizedCubic (r, s, t, x) x*x*x + r * x*x + s * x + t == 0 -// solveCubic (a, b, c, d, x) a * x*x*x + b * x*x + c * x + d == 0 -// -// Return value: -// -// 3 three real solutions, stored in x[0], x[1] and x[2] -// 2 two real solutions, stored in x[0] and x[1] -// 1 one real solution, stored in x[1] -// 0 no real solutions -// -1 all real numbers are solutions -// -// Notes: -// -// * It is possible that an equation has real solutions, but that the -// solutions (or some intermediate result) are not representable. -// In this case, either some of the solutions returned are invalid -// (nan or infinity), or, if floating-point exceptions have been -// enabled with Iex::mathExcOn(), an Iex::MathExc exception is -// thrown. -// -// * Cubic equations are solved using Cardano's Formula; even though -// only real solutions are produced, some intermediate results are -// complex (std::complex). -// -//-------------------------------------------------------------------------- - -template int solveLinear (T a, T b, T &x); -template int solveQuadratic (T a, T b, T c, T x[2]); -template int solveNormalizedCubic (T r, T s, T t, T x[3]); -template int solveCubic (T a, T b, T c, T d, T x[3]); - - -//--------------- -// Implementation -//--------------- - -template -int -solveLinear (T a, T b, T &x) -{ - if (a != 0) - { - x = -b / a; - return 1; - } - else if (b != 0) - { - return 0; - } - else - { - return -1; - } -} - - -template -int -solveQuadratic (T a, T b, T c, T x[2]) -{ - if (a == 0) - { - return solveLinear (b, c, x[0]); - } - else - { - T D = b * b - 4 * a * c; - - if (D > 0) - { - T s = Math::sqrt (D); - T q = -(b + (b > 0 ? 1 : -1) * s) / T(2); - - x[0] = q / a; - x[1] = c / q; - return 2; - } - if (D == 0) - { - x[0] = -b / (2 * a); - return 1; - } - else - { - return 0; - } - } -} - - -template -int -solveNormalizedCubic (T r, T s, T t, T x[3]) -{ - T p = (3 * s - r * r) / 3; - T q = 2 * r * r * r / 27 - r * s / 3 + t; - T p3 = p / 3; - T q2 = q / 2; - T D = p3 * p3 * p3 + q2 * q2; - - if (D == 0 && p3 == 0) - { - x[0] = -r / 3; - x[1] = -r / 3; - x[2] = -r / 3; - return 1; - } - - std::complex u = std::pow (-q / 2 + std::sqrt (std::complex (D)), - T (1) / T (3)); - - std::complex v = -p / (T (3) * u); - - const T sqrt3 = T (1.73205080756887729352744634150587); // enough digits - // for long double - std::complex y0 (u + v); - - std::complex y1 (-(u + v) / T (2) + - (u - v) / T (2) * std::complex (0, sqrt3)); - - std::complex y2 (-(u + v) / T (2) - - (u - v) / T (2) * std::complex (0, sqrt3)); - - if (D > 0) - { - x[0] = y0.real() - r / 3; - return 1; - } - else if (D == 0) - { - x[0] = y0.real() - r / 3; - x[1] = y1.real() - r / 3; - return 2; - } - else - { - x[0] = y0.real() - r / 3; - x[1] = y1.real() - r / 3; - x[2] = y2.real() - r / 3; - return 3; - } -} - - -template -int -solveCubic (T a, T b, T c, T d, T x[3]) -{ - if (a == 0) - { - return solveQuadratic (b, c, d, x); - } - else - { - return solveNormalizedCubic (b / a, c / a, d / a, x); - } -} - -IMATH_INTERNAL_NAMESPACE_HEADER_EXIT - -#endif // INCLUDED_IMATHROOTS_H diff --git a/src/pymagsac/graph-cut-ransac/include/mathfunc.h b/src/pymagsac/graph-cut-ransac/include/mathfunc.h new file mode 100644 index 0000000..b5e98f4 --- /dev/null +++ b/src/pymagsac/graph-cut-ransac/include/mathfunc.h @@ -0,0 +1,171 @@ +#pragma once +#include +#include +using namespace cv; +/* + Finds real roots of cubic, quadratic or linear equation. + The original code has been taken from Ken Turkowski web page + (http://www.worldserver.com/turk/opensource/) and adopted for OpenCV. + Here is the copyright notice. + + ----------------------------------------------------------------------- + Copyright (C) 1978-1999 Ken Turkowski. + + All rights reserved. + + Warranty Information + Even though I have reviewed this software, I make no warranty + or representation, either express or implied, with respect to this + software, its quality, accuracy, merchantability, or fitness for a + particular purpose. As a result, this software is provided "as is," + and you, its user, are assuming the entire risk as to its quality + and accuracy. + + This code may be used and freely distributed as long as it includes + this copyright notice and the above warranty information. + ----------------------------------------------------------------------- +*/ + +int solveCubic( Mat& coeffs, Mat& roots ) +{ + + const int n0 = 3; + int ctype = coeffs.type(); + + CV_Assert( ctype == CV_32F || ctype == CV_64F ); + CV_Assert( (coeffs.size() == Size(n0, 1) || + coeffs.size() == Size(n0+1, 1) || + coeffs.size() == Size(1, n0) || + coeffs.size() == Size(1, n0+1)) ); + + + int i = -1, n = 0; + double a0 = 1., a1, a2, a3; + double x0 = 0., x1 = 0., x2 = 0.; + int ncoeffs = coeffs.rows + coeffs.cols - 1; + + if( ctype == CV_32FC1 ) + { + if( ncoeffs == 4 ) + a0 = coeffs.at(++i); + + a1 = coeffs.at(i+1); + a2 = coeffs.at(i+2); + a3 = coeffs.at(i+3); + } + else + { + if( ncoeffs == 4 ) + a0 = coeffs.at(++i); + + a1 = coeffs.at(i+1); + a2 = coeffs.at(i+2); + a3 = coeffs.at(i+3); + } + + + if( a0 == 0 ) + { + if( a1 == 0 ) + { + if( a2 == 0 ) + n = a3 == 0 ? -1 : 0; + else + { + // linear equation + x0 = -a3/a2; + n = 1; + } + } + else + { + // quadratic equation + double d = a2*a2 - 4*a1*a3; + if( d >= 0 ) + { + d = std::sqrt(d); + double q1 = (-a2 + d) * 0.5; + double q2 = (a2 + d) * -0.5; + if( fabs(q1) > fabs(q2) ) + { + x0 = q1 / a1; + x1 = a3 / q1; + } + else + { + x0 = q2 / a1; + x1 = a3 / q2; + } + n = d > 0 ? 2 : 1; + } + } + } + else + { + a0 = 1./a0; + a1 *= a0; + a2 *= a0; + a3 *= a0; + + double Q = (a1 * a1 - 3 * a2) * (1./9); + double R = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) * (1./54); + double Qcubed = Q * Q * Q; + double d = Qcubed - R * R; + + if( d > 0 ) + { + double theta = acos(R / sqrt(Qcubed)); + double sqrtQ = sqrt(Q); + double t0 = -2 * sqrtQ; + double t1 = theta * (1./3); + double t2 = a1 * (1./3); + x0 = t0 * cos(t1) - t2; + x1 = t0 * cos(t1 + (2.*CV_PI/3)) - t2; + x2 = t0 * cos(t1 + (4.*CV_PI/3)) - t2; + n = 3; + } + else if( d == 0 ) + { + if(R >= 0) + { + x0 = -2*pow(R, 1./3) - a1/3; + x1 = pow(R, 1./3) - a1/3; + } + else + { + x0 = 2*pow(-R, 1./3) - a1/3; + x1 = -pow(-R, 1./3) - a1/3; + } + x2 = 0; + n = x0 == x1 ? 1 : 2; + x1 = x0 == x1 ? 0 : x1; + } + else + { + double e; + d = sqrt(-d); + e = pow(d + fabs(R), 1./3); + if( R > 0 ) + e = -e; + x0 = (e + Q / e) - a1 * (1./3); + n = 1; + } + } + + if( roots.type() == CV_32FC1 ) + { + roots.at(0) = (float)x0; + roots.at(1) = (float)x1; + roots.at(2) = (float)x2; + } + else + { + roots.at(0) = x0; + roots.at(1) = x1; + roots.at(2) = x2; + } + + return n; +} + + diff --git a/src/pymagsac/graph-cut-ransac/include/solver_fundamental_matrix_seven_point.h b/src/pymagsac/graph-cut-ransac/include/solver_fundamental_matrix_seven_point.h index 7586efd..6e81990 100644 --- a/src/pymagsac/graph-cut-ransac/include/solver_fundamental_matrix_seven_point.h +++ b/src/pymagsac/graph-cut-ransac/include/solver_fundamental_matrix_seven_point.h @@ -32,10 +32,10 @@ // Please contact the author of this library if you have any questions. // Author: Daniel Barath (barath.daniel@sztaki.mta.hu) #pragma once -#include +#include #include "solver_engine.h" #include "fundamental_estimator.h" -#include "ImathRoots.h" +#include "mathfunc.h" namespace gcransac { @@ -87,8 +87,8 @@ namespace gcransac const double *data_ptr = reinterpret_cast(data_.data); const int cols = data_.cols; double c[4], r[3] = {0}; - Mat coeffs( 1, 4, CV_64F, c ); - Mat roots( 1, 3, CV_64F, r ); + cv::Mat coeffs( 1, 4, CV_64F, c ); + cv::Mat roots( 1, 3, CV_64F, r ); double t0, t1, t2; int i, n; @@ -195,15 +195,18 @@ namespace gcransac c[0] = f1[0] * t0 - f1[1] * t1 + f1[2] * t2; - // n = real_roots.size(); - int n = solveCubic( coeffs, roots ); + //std::cout<<"c[0] "< 3) return false; - std::vector real_roots; - for(int i = 0; i < n; i++) + std::vector real_roots(n); + for(i = 0; i < n; i++) real_roots[i] = r[i]; + //std::cout<<"after copy cubic"< Date: Thu, 5 Mar 2020 18:58:19 +0800 Subject: [PATCH 3/8] remove debug info --- .../include/solver_fundamental_matrix_seven_point.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/pymagsac/graph-cut-ransac/include/solver_fundamental_matrix_seven_point.h b/src/pymagsac/graph-cut-ransac/include/solver_fundamental_matrix_seven_point.h index 6e81990..cebc5e6 100644 --- a/src/pymagsac/graph-cut-ransac/include/solver_fundamental_matrix_seven_point.h +++ b/src/pymagsac/graph-cut-ransac/include/solver_fundamental_matrix_seven_point.h @@ -32,7 +32,6 @@ // Please contact the author of this library if you have any questions. // Author: Daniel Barath (barath.daniel@sztaki.mta.hu) #pragma once -#include #include "solver_engine.h" #include "fundamental_estimator.h" #include "mathfunc.h" @@ -195,10 +194,7 @@ namespace gcransac c[0] = f1[0] * t0 - f1[1] * t1 + f1[2] * t2; - //std::cout<<"c[0] "< 3) return false; @@ -206,7 +202,6 @@ namespace gcransac std::vector real_roots(n); for(i = 0; i < n; i++) real_roots[i] = r[i]; - //std::cout<<"after copy cubic"< Date: Sat, 13 Jun 2020 17:38:56 +0800 Subject: [PATCH 4/8] add essential --- src/pymagsac/src/bindings.cpp | 102 +++++++++++++++++++++++++++++ src/pymagsac/src/magsac_python.cpp | 72 ++++++++++++++++++++ 2 files changed, 174 insertions(+) diff --git a/src/pymagsac/src/bindings.cpp b/src/pymagsac/src/bindings.cpp index 7f5e909..3a50b8e 100644 --- a/src/pymagsac/src/bindings.cpp +++ b/src/pymagsac/src/bindings.cpp @@ -69,6 +69,96 @@ py::tuple findFundamentalMatrix(py::array_t x1y1_, ptr2[i] = F[i]; return py::make_tuple(F_,inliers_); } + +py::tuple findEssentialMatrix(py::array_t x1y1_, + py::array_t x2y2_, + py::array_t K1_, + py::array_t K2_, + double sigma_th, + double conf, + int max_iters, + int partition_num, + int core_num) { + py::buffer_info buf1 = x1y1_.request(); + size_t NUM_TENTS = buf1.shape[0]; + size_t DIM = buf1.shape[1]; + + if (DIM != 2) { + throw std::invalid_argument( "x1y1 should be an array with dims [n,2], n>=7" ); + } + if (NUM_TENTS < 7) { + throw std::invalid_argument( "x1y1 should be an array with dims [n,2], n>=7"); + } + py::buffer_info buf1a = x2y2_.request(); + size_t NUM_TENTSa = buf1a.shape[0]; + size_t DIMa = buf1a.shape[1]; + + if (DIMa != 2) { + throw std::invalid_argument( "x2y2 should be an array with dims [n,2], n>=7" ); + } + if (NUM_TENTSa != NUM_TENTS) { + throw std::invalid_argument( "x1y1 and x2y2 should be the same size"); + } + + py::buffer_info bufk1 = K1_.request(); + if (bufk1.shape[0]!= 3 || bufk1.shape[1] != 3){ + throw std::invalid_argument( "K1 should be an array with dims [3,3]" ); + } + + py::buffer_info bufk2 = K2_.request(); + if (bufk2.shape[0]!= 3 || bufk2.shape[1] != 3){ + throw std::invalid_argument( "K2 should be an array with dims [3,3]" ); + } + + + double *ptr1 = (double *) buf1.ptr; + std::vector x1y1; + x1y1.assign(ptr1, ptr1 + buf1.size); + + double *ptr1a = (double *) buf1a.ptr; + std::vector x2y2; + x2y2.assign(ptr1a, ptr1a + buf1a.size); + + double *ptrk1 = (double *) bufk1.ptr; + std::vector K1; + K1.assign(ptrk1, ptrk1 + bufk1.size); + + double *ptrk2 = (double *) bufk2.ptr; + std::vector K2; + K2.assign(ptrk2, ptrk2 + bufk2.size); + + + + std::vector E(9); + std::vector inliers(NUM_TENTS); + + int num_inl = findEssentialMatrix_(x1y1, + x2y2, + inliers, + E, + K1, + K2, + sigma_th, + conf, + max_iters, + partition_num, + core_num); + + py::array_t inliers_ = py::array_t(NUM_TENTS); + py::buffer_info buf3 = inliers_.request(); + bool *ptr3 = (bool *)buf3.ptr; + for (size_t i = 0; i < NUM_TENTS; i++) + ptr3[i] = inliers[i]; + if (num_inl == 0){ + return py::make_tuple(pybind11::cast(Py_None),inliers_); + } + py::array_t E_ = py::array_t({3,3}); + py::buffer_info buf2 = E_.request(); + double *ptr2 = (double *)buf2.ptr; + for (size_t i = 0; i < 9; i++) + ptr2[i] = E[i]; + return py::make_tuple(E_,inliers_); +} py::tuple findHomography(py::array_t x1y1_, py::array_t x2y2_, @@ -143,6 +233,7 @@ PYBIND11_PLUGIN(pymagsac) { :toctree: _generate findFundamentalMatrix, + findEssentialMatrix, findHomography, )doc"); @@ -154,6 +245,17 @@ PYBIND11_PLUGIN(pymagsac) { py::arg("conf") = 0.99, py::arg("max_iters") = 10000, py::arg("partition_num") = 2); + + m.def("findEssentialMatrix", &findEssentialMatrix, R"doc(some doc)doc", + py::arg("x1y1"), + py::arg("x2y2"), + py::arg("K1"), + py::arg("K2"), + py::arg("sigma_th") = 1.0, + py::arg("conf") = 0.99, + py::arg("max_iters") = 10000, + py::arg("partition_num") = 2, + py::arg("core_num") = 1); m.def("findHomography", &findHomography, R"doc(some doc)doc", diff --git a/src/pymagsac/src/magsac_python.cpp b/src/pymagsac/src/magsac_python.cpp index 51c4730..601c82d 100644 --- a/src/pymagsac/src/magsac_python.cpp +++ b/src/pymagsac/src/magsac_python.cpp @@ -76,6 +76,78 @@ int findFundamentalMatrix_(std::vector& srcPts, return num_inliers; } +int findEssentialMatrix_(std::vector& srcPts, + std::vector& dstPts, + std::vector& inliers, + std::vector& E, + std::vector& intrinsics_src; + std::vector& intrinsics_dst; + double sigma_max, + double conf, + int max_iters, + int partition_num, + int core_num = 1) +{ + + magsac::utils::DefaultEssentialMatrixEstimator estimator(Eigen::Map(intrinsics_src.data()), + Eigen::Map(intrinsics_dst.data()), + 0.1); // The robust homography estimator class containing the + gcransac::EssentialMatrix model; // The estimated model + + MAGSAC magsac; + magsac.setMaximumThreshold(sigma_max); // The maximum noise scale sigma allowed + //magsac.setInterruptingThreshold(sigma_th / 3.0f); // The threshold used for speeding up the procedure + magsac.setCoreNumber(core_num); // The number of cores used to speed up sigma-consensus + magsac.setPartitionNumber(partition_num); // The number partitions used for speeding up sigma consensus. As the value grows, the algorithm become slower and, usually, more accurate. + magsac.setIterationLimit(max_iters); + //magsac.setTerminationCriterion(MAGSAC::TerminationCriterion::RansacCriterion, + // sigma_th); // Use the standard RANSAC termination criterion since the MAGSAC one is too pessimistic and, thus, runs too long sometimes + + int num_tents = srcPts.size()/2; + cv::Mat points(num_tents, 4, CV_64F); + for (int i = 0; i < num_tents; ++i) { + points.at(i, 0) = srcPts[2*i]; + points.at(i, 1) = srcPts[2*i + 1]; + points.at(i, 2) = dstPts[2*i]; + points.at(i, 3) = dstPts[2*i + 1]; + } + gcransac::sampler::UniformSampler main_sampler(&points); + + bool success = magsac.run(points, // The data points + conf, // The required confidence in the results + estimator, // The used estimator + main_sampler, // The sampler used for selecting minimal samples in each iteration + model, // The estimated model + max_iters); // The number of iterations + inliers.resize(num_tents); + if (!success) { + for (auto pt_idx = 0; pt_idx < points.rows; ++pt_idx) { + inliers[pt_idx] = false; + } + E.resize(9); + for (int i = 0; i < 3; i++){ + for (int j = 0; j < 3; j++){ + E[i*3+j] = 0; + } + } + return 0; + } + int num_inliers = 0; + for (auto pt_idx = 0; pt_idx < points.rows; ++pt_idx) { + const int is_inlier = estimator.residual(points.row(pt_idx), model.descriptor) <= sigma_max; + inliers[pt_idx] = (bool)is_inlier; + num_inliers+=is_inlier; + } + + E.resize(9); + for (int i = 0; i < 3; i++){ + for (int j = 0; j < 3; j++){ + E[i*3+j] = (double)model.descriptor(i,j); + } + } + return num_inliers; +} + int findHomography_(std::vector& srcPts, std::vector& dstPts, From 093d2adb9a88c134c54a285b7af09080eb2a637f Mon Sep 17 00:00:00 2001 From: zjhthu Date: Mon, 15 Jun 2020 17:06:22 +0800 Subject: [PATCH 5/8] run essential --- src/pymagsac/include/magsac_python.hpp | 11 +++++++++++ src/pymagsac/src/magsac_python.cpp | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/pymagsac/include/magsac_python.hpp b/src/pymagsac/include/magsac_python.hpp index b0c53f6..62c3a43 100644 --- a/src/pymagsac/include/magsac_python.hpp +++ b/src/pymagsac/include/magsac_python.hpp @@ -13,6 +13,17 @@ int findFundamentalMatrix_(std::vector& srcPts, int max_iters = 10000, int partition_num = 5); +int findEssentialMatrix_(std::vector& srcPts, + std::vector& dstPts, + std::vector& inliers, + std::vector& E, + std::vector& intrinsics_src, + std::vector& intrinsics_dst, + double sigma_th = 3.0, + double conf = 0.99, + int max_iters = 10000, + int partition_num = 5, + int core_num = 1); int findHomography_(std::vector& srcPts, diff --git a/src/pymagsac/src/magsac_python.cpp b/src/pymagsac/src/magsac_python.cpp index 601c82d..cd7a6b2 100644 --- a/src/pymagsac/src/magsac_python.cpp +++ b/src/pymagsac/src/magsac_python.cpp @@ -80,8 +80,8 @@ int findEssentialMatrix_(std::vector& srcPts, std::vector& dstPts, std::vector& inliers, std::vector& E, - std::vector& intrinsics_src; - std::vector& intrinsics_dst; + std::vector& intrinsics_src, + std::vector& intrinsics_dst, double sigma_max, double conf, int max_iters, From 9c784d5178267c0e6d78d89a44ff532254432a4f Mon Sep 17 00:00:00 2001 From: ZhangJiahui Date: Tue, 16 Jun 2020 16:34:06 +0800 Subject: [PATCH 6/8] adapted from official magsac --- src/pymagsac/include/estimators.h | 2 +- src/pymagsac/include/magsac.h | 5 +++++ src/pymagsac/src/bindings.cpp | 9 ++++++--- src/pymagsac/src/magsac_python.cpp | 5 +++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/pymagsac/include/estimators.h b/src/pymagsac/include/estimators.h index b5b1d30..58a1978 100644 --- a/src/pymagsac/include/estimators.h +++ b/src/pymagsac/include/estimators.h @@ -128,7 +128,7 @@ namespace magsac { // The default estimator for essential matrix fitting typedef estimator::EssentialMatrixEstimator // The solver used for fitting a model to a non-minimal sample + gcransac::estimator::solver::FundamentalMatrixEightPointSolver> // The solver used for fitting a model to a non-minimal sample DefaultEssentialMatrixEstimator; // The default estimator for fundamental matrix fitting diff --git a/src/pymagsac/include/magsac.h b/src/pymagsac/include/magsac.h index e27f67e..3c78de3 100644 --- a/src/pymagsac/include/magsac.h +++ b/src/pymagsac/include/magsac.h @@ -59,6 +59,11 @@ class MAGSAC { reference_inlier_outlier_threshold = threshold_; } + + double getReferenceThreshold() + { + return interrupting_threshold; + } void applyPostProcessing(bool value_) { diff --git a/src/pymagsac/src/bindings.cpp b/src/pymagsac/src/bindings.cpp index 3a50b8e..ec3e9b0 100644 --- a/src/pymagsac/src/bindings.cpp +++ b/src/pymagsac/src/bindings.cpp @@ -78,7 +78,8 @@ py::tuple findEssentialMatrix(py::array_t x1y1_, double conf, int max_iters, int partition_num, - int core_num) { + int core_num, + int minimum_inlier_ratio_in_validity_check) { py::buffer_info buf1 = x1y1_.request(); size_t NUM_TENTS = buf1.shape[0]; size_t DIM = buf1.shape[1]; @@ -142,7 +143,8 @@ py::tuple findEssentialMatrix(py::array_t x1y1_, conf, max_iters, partition_num, - core_num); + core_num, + minimum_inlier_ratio_in_validity_check); py::array_t inliers_ = py::array_t(NUM_TENTS); py::buffer_info buf3 = inliers_.request(); @@ -255,7 +257,8 @@ PYBIND11_PLUGIN(pymagsac) { py::arg("conf") = 0.99, py::arg("max_iters") = 10000, py::arg("partition_num") = 2, - py::arg("core_num") = 1); + py::arg("core_num") = 1), + py::arg("minimum_inlier_ratio_in_validity_check") = 0.1; m.def("findHomography", &findHomography, R"doc(some doc)doc", diff --git a/src/pymagsac/src/magsac_python.cpp b/src/pymagsac/src/magsac_python.cpp index 601c82d..101c355 100644 --- a/src/pymagsac/src/magsac_python.cpp +++ b/src/pymagsac/src/magsac_python.cpp @@ -86,12 +86,13 @@ int findEssentialMatrix_(std::vector& srcPts, double conf, int max_iters, int partition_num, - int core_num = 1) + int core_num = 1, + int minimum_inlier_ratio_in_validity_check = 0.1) { magsac::utils::DefaultEssentialMatrixEstimator estimator(Eigen::Map(intrinsics_src.data()), Eigen::Map(intrinsics_dst.data()), - 0.1); // The robust homography estimator class containing the + minimum_inlier_ratio_in_validity_check); // The robust homography estimator class containing the gcransac::EssentialMatrix model; // The estimated model MAGSAC magsac; From 4a0e2c97c78b79b5f589400aeb8e5ffb41c21837 Mon Sep 17 00:00:00 2001 From: zjhthu Date: Fri, 19 Jun 2020 14:41:21 +0800 Subject: [PATCH 7/8] better params for essential --- .gitignore | 1 + src/pymagsac/graph-cut-ransac/include/types.h | 2 +- src/pymagsac/include/magsac.h | 11 +++++++---- src/pymagsac/include/magsac_python.hpp | 4 +++- src/pymagsac/src/bindings.cpp | 17 ++++++++++------- src/pymagsac/src/magsac_python.cpp | 19 ++++++++++++++----- 6 files changed, 36 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index c1e46e3..261ecef 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ build docs/_build tests/bin +dist/ # Python *.egg-info diff --git a/src/pymagsac/graph-cut-ransac/include/types.h b/src/pymagsac/graph-cut-ransac/include/types.h index 83543e7..dc3c056 100644 --- a/src/pymagsac/graph-cut-ransac/include/types.h +++ b/src/pymagsac/graph-cut-ransac/include/types.h @@ -142,4 +142,4 @@ namespace gcransac } }; } -} \ No newline at end of file +} diff --git a/src/pymagsac/include/magsac.h b/src/pymagsac/include/magsac.h index 3c78de3..a271524 100644 --- a/src/pymagsac/include/magsac.h +++ b/src/pymagsac/include/magsac.h @@ -41,7 +41,8 @@ class MAGSAC ModelEstimator& estimator_, gcransac::sampler::Sampler &sampler_, gcransac::Model &obtained_model_, - int &iteration_number_); + int &iteration_number_, + ModelScore &model_score_); // The score of the estimated model bool scoreLess( const ModelScore &score_1_, @@ -137,7 +138,8 @@ bool MAGSAC::run( ModelEstimator& estimator_, gcransac::sampler::Sampler &sampler_, gcransac::Model& obtained_model_, - int& iteration_number_) + int& iteration_number_, + ModelScore &model_score_) { // Initialize variables std::chrono::time_point start, end; // Variables for time measuring: start and end times @@ -195,8 +197,8 @@ bool MAGSAC::run( } // If the method was not able to generate any usable models, break the cycle. - if (unsuccessful_model_generations >= max_unsuccessful_model_generations) - break; + //if (unsuccessful_model_generations >= max_unsuccessful_model_generations) + // break; // Select the so-far-the-best from the estimated models for (const auto &model : models) @@ -258,6 +260,7 @@ bool MAGSAC::run( obtained_model_ = so_far_the_best_model; iteration_number_ = iteration; + model_score_ = so_far_the_best_score; return so_far_the_best_score.score > 0; } diff --git a/src/pymagsac/include/magsac_python.hpp b/src/pymagsac/include/magsac_python.hpp index 62c3a43..0a501c4 100644 --- a/src/pymagsac/include/magsac_python.hpp +++ b/src/pymagsac/include/magsac_python.hpp @@ -23,7 +23,9 @@ int findEssentialMatrix_(std::vector& srcPts, double conf = 0.99, int max_iters = 10000, int partition_num = 5, - int core_num = 1); + int core_num = 1, + double minimum_inlier_ratio_in_validity_check = 0.1, + double normalizing_multiplier = 1e-3); int findHomography_(std::vector& srcPts, diff --git a/src/pymagsac/src/bindings.cpp b/src/pymagsac/src/bindings.cpp index ec3e9b0..4a3701b 100644 --- a/src/pymagsac/src/bindings.cpp +++ b/src/pymagsac/src/bindings.cpp @@ -79,7 +79,8 @@ py::tuple findEssentialMatrix(py::array_t x1y1_, int max_iters, int partition_num, int core_num, - int minimum_inlier_ratio_in_validity_check) { + double minimum_inlier_ratio_in_validity_check, + double normalizing_multiplier){ py::buffer_info buf1 = x1y1_.request(); size_t NUM_TENTS = buf1.shape[0]; size_t DIM = buf1.shape[1]; @@ -144,7 +145,8 @@ py::tuple findEssentialMatrix(py::array_t x1y1_, max_iters, partition_num, core_num, - minimum_inlier_ratio_in_validity_check); + minimum_inlier_ratio_in_validity_check, + normalizing_multiplier); py::array_t inliers_ = py::array_t(NUM_TENTS); py::buffer_info buf3 = inliers_.request(); @@ -253,12 +255,13 @@ PYBIND11_PLUGIN(pymagsac) { py::arg("x2y2"), py::arg("K1"), py::arg("K2"), - py::arg("sigma_th") = 1.0, - py::arg("conf") = 0.99, + py::arg("sigma_th") = 1e-4, + py::arg("conf") = 0.999999, py::arg("max_iters") = 10000, - py::arg("partition_num") = 2, - py::arg("core_num") = 1), - py::arg("minimum_inlier_ratio_in_validity_check") = 0.1; + py::arg("partition_num") = 20, + py::arg("core_num") = 1, + py::arg("minimum_inlier_ratio_in_validity_check") = 0.1, + py::arg("normalizing_multiplier") = 1e-3); m.def("findHomography", &findHomography, R"doc(some doc)doc", diff --git a/src/pymagsac/src/magsac_python.cpp b/src/pymagsac/src/magsac_python.cpp index a5bb99f..f7b978c 100644 --- a/src/pymagsac/src/magsac_python.cpp +++ b/src/pymagsac/src/magsac_python.cpp @@ -41,12 +41,14 @@ int findFundamentalMatrix_(std::vector& srcPts, } gcransac::sampler::UniformSampler main_sampler(&points); + ModelScore score; bool success = magsac.run(points, // The data points conf, // The required confidence in the results estimator, // The used estimator main_sampler, // The sampler used for selecting minimal samples in each iteration model, // The estimated model - max_iters); // The number of iterations + max_iters, // The number of iterations + score); // The score of the estimated model inliers.resize(num_tents); if (!success) { for (auto pt_idx = 0; pt_idx < points.rows; ++pt_idx) { @@ -87,12 +89,14 @@ int findEssentialMatrix_(std::vector& srcPts, int max_iters, int partition_num, int core_num = 1, - int minimum_inlier_ratio_in_validity_check = 0.1) + double minimum_inlier_ratio_in_validity_check = 0.1, + double normalizing_multiplier = 1e-3) { magsac::utils::DefaultEssentialMatrixEstimator estimator(Eigen::Map(intrinsics_src.data()), Eigen::Map(intrinsics_dst.data()), - minimum_inlier_ratio_in_validity_check); // The robust homography estimator class containing the + minimum_inlier_ratio_in_validity_check + ); // The robust homography estimator class containing the gcransac::EssentialMatrix model; // The estimated model MAGSAC magsac; @@ -101,6 +105,7 @@ int findEssentialMatrix_(std::vector& srcPts, magsac.setCoreNumber(core_num); // The number of cores used to speed up sigma-consensus magsac.setPartitionNumber(partition_num); // The number partitions used for speeding up sigma consensus. As the value grows, the algorithm become slower and, usually, more accurate. magsac.setIterationLimit(max_iters); + magsac.setReferenceThreshold(magsac.getReferenceThreshold() * normalizing_multiplier); //magsac.setTerminationCriterion(MAGSAC::TerminationCriterion::RansacCriterion, // sigma_th); // Use the standard RANSAC termination criterion since the MAGSAC one is too pessimistic and, thus, runs too long sometimes @@ -114,12 +119,14 @@ int findEssentialMatrix_(std::vector& srcPts, } gcransac::sampler::UniformSampler main_sampler(&points); + ModelScore score; bool success = magsac.run(points, // The data points conf, // The required confidence in the results estimator, // The used estimator main_sampler, // The sampler used for selecting minimal samples in each iteration model, // The estimated model - max_iters); // The number of iterations + max_iters, // The number of iterations + score); // The score of the estimated model inliers.resize(num_tents); if (!success) { for (auto pt_idx = 0; pt_idx < points.rows; ++pt_idx) { @@ -179,12 +186,14 @@ int findHomography_(std::vector& srcPts, } gcransac::sampler::UniformSampler main_sampler(&points); + ModelScore score; bool success = magsac.run(points, // The data points conf, // The required confidence in the results estimator, // The used estimator main_sampler, // The sampler used for selecting minimal samples in each iteration model, // The estimated model - max_iters); // The number of iterations + max_iters, // The number of iterations + score); // The score of the estimated model inliers.resize(num_tents); if (!success) { for (auto pt_idx = 0; pt_idx < points.rows; ++pt_idx) { From 95b0efab7a4df7027fde3351bda4ad28c1843051 Mon Sep 17 00:00:00 2001 From: sundw2014 Date: Sun, 30 Aug 2020 22:34:22 -0500 Subject: [PATCH 8/8] add new argument core_num to findFundamentalMatrix --- src/pymagsac/include/magsac_python.hpp | 3 ++- src/pymagsac/src/bindings.cpp | 9 ++++++--- src/pymagsac/src/magsac_python.cpp | 5 +++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/pymagsac/include/magsac_python.hpp b/src/pymagsac/include/magsac_python.hpp index 0a501c4..8033b3e 100644 --- a/src/pymagsac/include/magsac_python.hpp +++ b/src/pymagsac/include/magsac_python.hpp @@ -11,7 +11,8 @@ int findFundamentalMatrix_(std::vector& srcPts, double sigma_th = 3.0, double conf = 0.99, int max_iters = 10000, - int partition_num = 5); + int partition_num = 5, + int core_num = 1); int findEssentialMatrix_(std::vector& srcPts, std::vector& dstPts, diff --git a/src/pymagsac/src/bindings.cpp b/src/pymagsac/src/bindings.cpp index 4a3701b..a5956f1 100644 --- a/src/pymagsac/src/bindings.cpp +++ b/src/pymagsac/src/bindings.cpp @@ -13,7 +13,8 @@ py::tuple findFundamentalMatrix(py::array_t x1y1_, double sigma_th, double conf, int max_iters, - int partition_num) { + int partition_num, + int core_num) { py::buffer_info buf1 = x1y1_.request(); size_t NUM_TENTS = buf1.shape[0]; size_t DIM = buf1.shape[1]; @@ -52,7 +53,8 @@ py::tuple findFundamentalMatrix(py::array_t x1y1_, sigma_th, conf, max_iters, - partition_num); + partition_num, + core_num); py::array_t inliers_ = py::array_t(NUM_TENTS); py::buffer_info buf3 = inliers_.request(); @@ -248,7 +250,8 @@ PYBIND11_PLUGIN(pymagsac) { py::arg("sigma_th") = 1.0, py::arg("conf") = 0.99, py::arg("max_iters") = 10000, - py::arg("partition_num") = 2); + py::arg("partition_num") = 2, + py::arg("core_num") = 1); m.def("findEssentialMatrix", &findEssentialMatrix, R"doc(some doc)doc", py::arg("x1y1"), diff --git a/src/pymagsac/src/magsac_python.cpp b/src/pymagsac/src/magsac_python.cpp index f7b978c..d94226c 100644 --- a/src/pymagsac/src/magsac_python.cpp +++ b/src/pymagsac/src/magsac_python.cpp @@ -16,7 +16,8 @@ int findFundamentalMatrix_(std::vector& srcPts, double sigma_max, double conf, int max_iters, - int partition_num) + int partition_num, + int core_num = 1) { magsac::utils::DefaultFundamentalMatrixEstimator estimator(0.1); // The robust homography estimator class containing the @@ -25,7 +26,7 @@ int findFundamentalMatrix_(std::vector& srcPts, MAGSAC magsac; magsac.setMaximumThreshold(sigma_max); // The maximum noise scale sigma allowed //magsac.setInterruptingThreshold(sigma_th / 3.0f); // The threshold used for speeding up the procedure - magsac.setCoreNumber(1); // The number of cores used to speed up sigma-consensus + magsac.setCoreNumber(core_num); // The number of cores used to speed up sigma-consensus magsac.setPartitionNumber(partition_num); // The number partitions used for speeding up sigma consensus. As the value grows, the algorithm become slower and, usually, more accurate. magsac.setIterationLimit(max_iters); //magsac.setTerminationCriterion(MAGSAC::TerminationCriterion::RansacCriterion,