Skip to content

Commit 611cf8d

Browse files
woody.chowalalek
authored andcommitted
Use Eigen::SelfAdjointEigenSolver in cv::eigen
1 parent a3ec2ac commit 611cf8d

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

modules/core/src/lapack.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@
4343
#include "precomp.hpp"
4444
#include <limits>
4545

46+
#ifdef HAVE_EIGEN
47+
#include <Eigen/Core>
48+
#include <Eigen/Eigenvalues>
49+
#include "opencv2/core/eigen.hpp"
50+
#endif
51+
4652
#if defined _M_IX86 && defined _MSC_VER && _MSC_VER < 1700
4753
#pragma float_control(precise, on)
4854
#endif
@@ -1396,6 +1402,47 @@ bool cv::eigen( InputArray _src, OutputArray _evals, OutputArray _evects )
13961402
v = _evects.getMat();
13971403
}
13981404

1405+
#ifdef HAVE_EIGEN
1406+
const bool evecNeeded = _evects.needed();
1407+
const int esOptions = evecNeeded ? Eigen::ComputeEigenvectors : Eigen::EigenvaluesOnly;
1408+
_evals.create(n, 1, type);
1409+
cv::Mat evals = _evals.getMat();
1410+
if ( type == CV_64F )
1411+
{
1412+
Eigen::MatrixXd src_eig, zeros_eig;
1413+
cv::cv2eigen(src, src_eig);
1414+
1415+
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es;
1416+
es.compute(src_eig, esOptions);
1417+
if ( es.info() == Eigen::Success )
1418+
{
1419+
cv::eigen2cv(es.eigenvalues().reverse().eval(), evals);
1420+
if ( evecNeeded )
1421+
{
1422+
cv::Mat evects = _evects.getMat();
1423+
cv::eigen2cv(es.eigenvectors().rowwise().reverse().transpose().eval(), v);
1424+
}
1425+
return true;
1426+
}
1427+
} else { // CV_32F
1428+
Eigen::MatrixXf src_eig, zeros_eig;
1429+
cv::cv2eigen(src, src_eig);
1430+
1431+
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> es;
1432+
es.compute(src_eig, esOptions);
1433+
if ( es.info() == Eigen::Success )
1434+
{
1435+
cv::eigen2cv(es.eigenvalues().reverse().eval(), evals);
1436+
if ( evecNeeded )
1437+
{
1438+
cv::eigen2cv(es.eigenvectors().rowwise().reverse().transpose().eval(), v);
1439+
}
1440+
return true;
1441+
}
1442+
}
1443+
return false;
1444+
#else
1445+
13991446
size_t elemSize = src.elemSize(), astep = alignSize(n*elemSize, 16);
14001447
AutoBuffer<uchar> buf(n*astep + n*5*elemSize + 32);
14011448
uchar* ptr = alignPtr((uchar*)buf, 16);
@@ -1408,6 +1455,7 @@ bool cv::eigen( InputArray _src, OutputArray _evals, OutputArray _evects )
14081455

14091456
w.copyTo(_evals);
14101457
return ok;
1458+
#endif
14111459
}
14121460

14131461
namespace cv

modules/core/test/test_eigen.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ using namespace std;
5959
#define MESSAGE_ERROR_DIFF_1 "Accuracy of eigen values computing less than required."
6060
#define MESSAGE_ERROR_DIFF_2 "Accuracy of eigen vectors computing less than required."
6161
#define MESSAGE_ERROR_ORTHO "Matrix of eigen vectors is not orthogonal."
62-
#define MESSAGE_ERROR_ORDER "Eigen values are not sorted in ascending order."
62+
#define MESSAGE_ERROR_ORDER "Eigen values are not sorted in descending order."
6363

6464
const int COUNT_NORM_TYPES = 3;
6565
const int NORM_TYPE[COUNT_NORM_TYPES] = {cv::NORM_L1, cv::NORM_L2, cv::NORM_INF};
@@ -257,7 +257,7 @@ bool Core_EigenTest::check_pairs_order(const cv::Mat& eigen_values)
257257
if (!(eigen_values.at<float>(i, 0) > eigen_values.at<float>(i+1, 0)))
258258
{
259259
std::cout << endl; std::cout << "Checking order of eigen values vector " << eigen_values << "..." << endl;
260-
std::cout << "Pair of indexes with non ascending of eigen values: (" << i << ", " << i+1 << ")." << endl;
260+
std::cout << "Pair of indexes with non descending of eigen values: (" << i << ", " << i+1 << ")." << endl;
261261
std::cout << endl;
262262
CV_Error(CORE_EIGEN_ERROR_ORDER, MESSAGE_ERROR_ORDER);
263263
return false;
@@ -272,9 +272,9 @@ bool Core_EigenTest::check_pairs_order(const cv::Mat& eigen_values)
272272
if (!(eigen_values.at<double>(i, 0) > eigen_values.at<double>(i+1, 0)))
273273
{
274274
std::cout << endl; std::cout << "Checking order of eigen values vector " << eigen_values << "..." << endl;
275-
std::cout << "Pair of indexes with non ascending of eigen values: (" << i << ", " << i+1 << ")." << endl;
275+
std::cout << "Pair of indexes with non descending of eigen values: (" << i << ", " << i+1 << ")." << endl;
276276
std::cout << endl;
277-
CV_Error(CORE_EIGEN_ERROR_ORDER, "Eigen values are not sorted in ascending order.");
277+
CV_Error(CORE_EIGEN_ERROR_ORDER, "Eigen values are not sorted in descending order.");
278278
return false;
279279
}
280280

0 commit comments

Comments
 (0)