Commit 51bb9ca52775a3403399b2322d2200abd9fec1d9

Authored by Scott Klum
2 parents 3122cac3 82822bb2

Merge pull request #321 from biometrics/eigenutil_cleanup

Eigenutil cleanup
openbr/core/eigenutils.cpp
@@ -4,80 +4,15 @@ @@ -4,80 +4,15 @@
4 using namespace Eigen; 4 using namespace Eigen;
5 using namespace cv; 5 using namespace cv;
6 6
7 -//Helper function to quickly write eigen matrix to disk. Not efficient.  
8 -void writeEigen(MatrixXf X, QString filename) {  
9 - Mat m(X.rows(),X.cols(),CV_32FC1);  
10 - for (int i = 0; i < X.rows(); i++) {  
11 - for (int j = 0; j < X.cols(); j++) {  
12 - m.at<float>(i,j) = X(i,j);  
13 - }  
14 - }  
15 - QScopedPointer<br::Format> format(br::Factory<br::Format>::make(filename));  
16 - format->write(br::Template(m));  
17 -}  
18 -  
19 -void writeEigen(MatrixXd X, QString filename) {  
20 - Mat m(X.rows(),X.cols(),CV_32FC1);  
21 - for (int i = 0; i < X.rows(); i++) {  
22 - for (int j = 0; j < X.cols(); j++) {  
23 - m.at<float>(i,j) = (float)X(i,j);  
24 - }  
25 - }  
26 - QScopedPointer<br::Format> format(br::Factory<br::Format>::make(filename));  
27 - format->write(br::Template(m));  
28 -}  
29 -  
30 -void writeEigen(VectorXd X, QString filename) {  
31 - Mat m(X.size(),1,CV_32FC1);  
32 - for (int i = 0; i < X.rows(); i++) {  
33 - m.at<float>(i,0) = (float)X(i);  
34 - }  
35 - QScopedPointer<br::Format> format(br::Factory<br::Format>::make(filename));  
36 - format->write(br::Template(m));  
37 -}  
38 -  
39 -void writeEigen(VectorXf X, QString filename) {  
40 - Mat m(X.size(),1,CV_32FC1);  
41 - for (int i = 0; i < X.rows(); i++) {  
42 - m.at<float>(i,0) = X(i);  
43 - }  
44 - QScopedPointer<br::Format> format(br::Factory<br::Format>::make(filename));  
45 - format->write(br::Template(m));  
46 -}  
47 -  
48 -void printEigen(Eigen::MatrixXd X) {  
49 - for (int i = 0; i < X.rows(); i++) {  
50 - QString str;  
51 - for (int j = 0; j < X.cols(); j++) {  
52 - str.append(QString::number(X(i,j)) + " ");  
53 - }  
54 - qDebug() << str;  
55 - }  
56 -}  
57 -void printEigen(Eigen::MatrixXf X) {  
58 - for (int i = 0; i < X.rows(); i++) {  
59 - QString str;  
60 - for (int j = 0; j < X.cols(); j++) {  
61 - str.append(QString::number(X(i,j)) + " ");  
62 - }  
63 - qDebug() << str;  
64 - }  
65 -}  
66 -  
67 -void printSize(Eigen::MatrixXf X) { 7 +void EigenUtils::printSize(Eigen::MatrixXf X) {
68 qDebug() << "Rows=" << X.rows() << "\tCols=" << X.cols(); 8 qDebug() << "Rows=" << X.rows() << "\tCols=" << X.cols();
69 } 9 }
70 10
71 -float eigMean(const Eigen::MatrixXf& x) {  
72 - return x.array().sum() / (x.rows() * x.cols()); 11 +float EigenUtils::stddev(const Eigen::MatrixXf& x) {
  12 + return sqrt((x.array() - x.mean()).pow(2).sum() / (x.cols() * x.rows()));
73 } 13 }
74 14
75 -float eigStd(const Eigen::MatrixXf& x) {  
76 - float mean = eigMean(x);  
77 - return sqrt((x.array() - mean).pow(2).sum() / (x.cols() * x.rows()));  
78 -}  
79 -  
80 -MatrixXf removeRowCol(const MatrixXf X, int row, int col) { 15 +MatrixXf EigenUtils::removeRowCol(const MatrixXf X, int row, int col) {
81 MatrixXf Y(X.rows() - 1,X.cols() - 1); 16 MatrixXf Y(X.rows() - 1,X.cols() - 1);
82 17
83 for (int i1 = 0, i2 = 0; i1 < X.rows(); i1++) { 18 for (int i1 = 0, i2 = 0; i1 < X.rows(); i1++) {
@@ -96,7 +31,7 @@ MatrixXf removeRowCol(const MatrixXf X, int row, int col) { @@ -96,7 +31,7 @@ MatrixXf removeRowCol(const MatrixXf X, int row, int col) {
96 return Y; 31 return Y;
97 } 32 }
98 33
99 -MatrixXf pointsToMatrix(const QList<QPointF> points, bool isAffine) { 34 +MatrixXf EigenUtils::pointsToMatrix(const QList<QPointF> points, bool isAffine) {
100 MatrixXf P(points.size(), isAffine ? 3 : 2); 35 MatrixXf P(points.size(), isAffine ? 3 : 2);
101 for (int i = 0; i < points.size(); i++) { 36 for (int i = 0; i < points.size(); i++) {
102 P(i, 0) = points[i].x(); 37 P(i, 0) = points[i].x();
@@ -107,7 +42,7 @@ MatrixXf pointsToMatrix(const QList&lt;QPointF&gt; points, bool isAffine) { @@ -107,7 +42,7 @@ MatrixXf pointsToMatrix(const QList&lt;QPointF&gt; points, bool isAffine) {
107 return P; 42 return P;
108 } 43 }
109 44
110 -QList<QPointF> matrixToPoints(const Eigen::MatrixXf P) { 45 +QList<QPointF> EigenUtils::matrixToPoints(const Eigen::MatrixXf P) {
111 QList<QPointF> points; 46 QList<QPointF> points;
112 for (int i = 0; i < P.rows(); i++) 47 for (int i = 0; i < P.rows(); i++)
113 points.append(QPointF(P(i, 0), P(i, 1))); 48 points.append(QPointF(P(i, 0), P(i, 1)));
@@ -115,7 +50,7 @@ QList&lt;QPointF&gt; matrixToPoints(const Eigen::MatrixXf P) { @@ -115,7 +50,7 @@ QList&lt;QPointF&gt; matrixToPoints(const Eigen::MatrixXf P) {
115 } 50 }
116 51
117 //Converts x y points in a single vector to two column matrix 52 //Converts x y points in a single vector to two column matrix
118 -Eigen::MatrixXf vectorToMatrix(const Eigen::MatrixXf vector) { 53 +Eigen::MatrixXf EigenUtils::vectorToMatrix(const Eigen::MatrixXf vector) {
119 int n = vector.rows(); 54 int n = vector.rows();
120 Eigen::MatrixXf matrix(n / 2, 2); 55 Eigen::MatrixXf matrix(n / 2, 2);
121 for (int i = 0; i < n / 2; i++) { 56 for (int i = 0; i < n / 2; i++) {
@@ -126,7 +61,7 @@ Eigen::MatrixXf vectorToMatrix(const Eigen::MatrixXf vector) { @@ -126,7 +61,7 @@ Eigen::MatrixXf vectorToMatrix(const Eigen::MatrixXf vector) {
126 return matrix; 61 return matrix;
127 } 62 }
128 63
129 -Eigen::MatrixXf matrixToVector(const Eigen::MatrixXf matrix) { 64 +Eigen::MatrixXf EigenUtils::matrixToVector(const Eigen::MatrixXf matrix) {
130 int n2 = matrix.rows(); 65 int n2 = matrix.rows();
131 Eigen::MatrixXf vector(n2 * 2, 1); 66 Eigen::MatrixXf vector(n2 * 2, 1);
132 for (int i = 0; i < n2; i++) { 67 for (int i = 0; i < n2; i++) {
@@ -136,12 +71,3 @@ Eigen::MatrixXf matrixToVector(const Eigen::MatrixXf matrix) { @@ -136,12 +71,3 @@ Eigen::MatrixXf matrixToVector(const Eigen::MatrixXf matrix) {
136 } 71 }
137 return vector; 72 return vector;
138 } 73 }
139 -  
140 -Eigen::MatrixXf toEigen(const Mat m) {  
141 - if (m.type() != CV_32F)  
142 - qFatal("Mat to Eigen Converstation only supports CV_32F");  
143 -  
144 - Eigen::MatrixXf data(m.rows, m.cols);  
145 - return Eigen::Map<const Eigen::MatrixXf>(m.ptr<float>(), m.rows, m.cols);  
146 -}  
147 -  
openbr/core/eigenutils.h
@@ -18,32 +18,74 @@ @@ -18,32 +18,74 @@
18 #define EIGENUTILS_H 18 #define EIGENUTILS_H
19 19
20 #include <QDataStream> 20 #include <QDataStream>
  21 +#include <QDebug>
21 #include <Eigen/Core> 22 #include <Eigen/Core>
22 #include <assert.h> 23 #include <assert.h>
23 24
  25 +#include <opencv2/core/eigen.hpp>
24 #include <opencv2/core/core.hpp> 26 #include <opencv2/core/core.hpp>
25 27
26 -void writeEigen(Eigen::MatrixXf X, QString filename);  
27 -void writeEigen(Eigen::MatrixXd X, QString filename);  
28 -void writeEigen(Eigen::VectorXd X, QString filename);  
29 -void writeEigen(Eigen::VectorXf X, QString filename);  
30 -void printEigen(Eigen::MatrixXd X);  
31 -void printEigen(Eigen::MatrixXf X);  
32 -void printSize(Eigen::MatrixXf X); 28 +#include "openbr/core/qtutils.h"
33 29
34 -//Converts x y points in a single vector to two column matrix  
35 -Eigen::MatrixXf vectorToMatrix(const Eigen::MatrixXf vector);  
36 -Eigen::MatrixXf matrixToVector(const Eigen::MatrixXf matrix); 30 +namespace EigenUtils
  31 +{
  32 + template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
  33 + QString matrixToString(const Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > &mat)
  34 + {
  35 + QString result;
  36 + if (mat.rows() > 1) result += "{ ";
  37 + for (int r=0; r<mat.rows(); r++) {
  38 + if ((mat.rows() > 1) && (r > 0)) result += " ";
  39 + if (mat.cols() > 1) result += "[";
  40 + for (int c=0; c<mat.cols(); c++) {
  41 + result += QString::number(mat(r, c));
  42 + if (c < mat.cols() - 1) result += ", ";
  43 + }
  44 + if (mat.cols() > 1) result += "]";
  45 + if (r < mat.rows()-1) result += "\n";
  46 + }
  47 + if (mat.rows() > 1) result += " }";
  48 + return result;
  49 + }
  50 +
  51 + template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
  52 + void writeMatrix(const Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > &mat, const QString &filename)
  53 + {
  54 + int r = mat.rows();
  55 + int c = mat.cols();
  56 +
  57 + _Scalar *data = new _Scalar[r*c];
  58 + for (int i=0; i<r; i++)
  59 + for (int j=0; j<c; j++)
  60 + data[i*c+j] = mat(i, j);
  61 + int bytes = r*c*sizeof(_Scalar);
  62 + QByteArray byteArray((const char*)data,bytes);
  63 + QtUtils::writeFile(filename,byteArray);
  64 + }
  65 +
  66 + void printSize(Eigen::MatrixXf X);
37 67
38 -//Remove row and column from the matrix:  
39 -Eigen::MatrixXf removeRowCol(const Eigen::MatrixXf X, int row, int col); 68 + // Converts x y points in a single vector to two column matrix
  69 + Eigen::MatrixXf vectorToMatrix(const Eigen::MatrixXf vector);
  70 + Eigen::MatrixXf matrixToVector(const Eigen::MatrixXf matrix);
40 71
41 -//Convert a point list into a matrix:  
42 -Eigen::MatrixXf pointsToMatrix(const QList<QPointF> points, bool isAffine=false);  
43 -QList<QPointF> matrixToPoints(const Eigen::MatrixXf P); 72 + // Remove row and column from the matrix:
  73 + Eigen::MatrixXf removeRowCol(const Eigen::MatrixXf X, int row, int col);
44 74
45 -//Convert cv::Mat to Eigen  
46 -Eigen::MatrixXf toEigen(const cv::Mat m); 75 + // Convert a point list into a matrix:
  76 + Eigen::MatrixXf pointsToMatrix(const QList<QPointF> points, bool isAffine=false);
  77 + QList<QPointF> matrixToPoints(const Eigen::MatrixXf P);
  78 +
  79 + // Compute the element-wise standard deviation
  80 + float stddev(const Eigen::MatrixXf& x);
  81 +}
  82 +
  83 +template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
  84 +inline QDebug operator<<(QDebug dbg, const Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > &mat)
  85 +{
  86 + dbg.nospace() << EigenUtils::matrixToString(mat);
  87 + return dbg.space();
  88 +}
47 89
48 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> 90 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
49 inline QDataStream &operator<<(QDataStream &stream, const Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > &mat) 91 inline QDataStream &operator<<(QDataStream &stream, const Eigen::Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > &mat)
@@ -83,56 +125,4 @@ inline QDataStream &amp;operator&gt;&gt;(QDataStream &amp;stream, Eigen::Matrix&lt; _Scalar, _Row @@ -83,56 +125,4 @@ inline QDataStream &amp;operator&gt;&gt;(QDataStream &amp;stream, Eigen::Matrix&lt; _Scalar, _Row
83 return stream; 125 return stream;
84 } 126 }
85 127
86 -/*Compute the mean of the each column (dim == 1) or row (dim == 2)  
87 - of the matrix*/  
88 -template<typename T>  
89 -Eigen::MatrixBase<T> eigMean(const Eigen::MatrixBase<T>& x,int dim)  
90 -{  
91 - if (dim == 1) {  
92 - Eigen::MatrixBase<T> y(1,x.cols());  
93 - for (int i = 0; i < x.cols(); i++)  
94 - y(i) = x.col(i).sum() / x.rows();  
95 - return y;  
96 - } else if (dim == 2) {  
97 - Eigen::MatrixBase<T> y(x.rows(),1);  
98 - for (int i = 0; i < x.rows(); i++)  
99 - y(i) = x.row(i).sum() / x.cols();  
100 - return y;  
101 - }  
102 - qFatal("A matrix can only have two dimensions");  
103 -}  
104 -  
105 -/*Compute the element-wise mean*/  
106 -float eigMean(const Eigen::MatrixXf& x);  
107 -/*Compute the element-wise mean*/  
108 -float eigStd(const Eigen::MatrixXf& x);  
109 -  
110 -/*Compute the std dev of the each column (dim == 1) or row (dim == 2)  
111 - of the matrix*/  
112 -template<typename T>  
113 -Eigen::MatrixBase<T> eigStd(const Eigen::MatrixBase<T>& x,int dim)  
114 -{  
115 - Eigen::MatrixBase<T> mean = eigMean(x, dim);  
116 - if (dim == 1) {  
117 - Eigen::MatrixBase<T> y(1,x.cols());  
118 - for (int i = 0; i < x.cols(); i++) {  
119 - T value = 0;  
120 - for (int j = 0; j < x.rows(); j++)  
121 - value += pow(y(j, i) - mean(i), 2);  
122 - y(i) = sqrt(value / (x.rows() - 1));  
123 - }  
124 - return y;  
125 - } else if (dim == 2) {  
126 - Eigen::MatrixBase<T> y(x.rows(),1);  
127 - for (int i = 0; i < x.rows(); i++) {  
128 - T value = 0;  
129 - for (int j = 0; j < x.cols(); j++)  
130 - value += pow(y(i, j) - mean(j), 2);  
131 - y(i) = sqrt(value / (x.cols() - 1));  
132 - }  
133 - return y;  
134 - }  
135 - qFatal("A matrix can only have two dimensions");  
136 -}  
137 -  
138 #endif // EIGENUTILS_H 128 #endif // EIGENUTILS_H
openbr/plugins/eigen3.cpp
@@ -600,7 +600,7 @@ class SparseLDATransform : public Transform @@ -600,7 +600,7 @@ class SparseLDATransform : public Transform
600 600
601 //Only works on binary class problems for now 601 //Only works on binary class problems for now
602 assert(ldaOrig.projection.cols() == 1); 602 assert(ldaOrig.projection.cols() == 1);
603 - float ldaStd = eigStd(ldaOrig.projection); 603 + float ldaStd = EigenUtils::stddev(ldaOrig.projection);
604 for (int i = 0; i < ldaOrig.projection.rows(); i++) 604 for (int i = 0; i < ldaOrig.projection.rows(); i++)
605 if (abs(ldaOrig.projection(i)) > varThreshold * ldaStd) 605 if (abs(ldaOrig.projection(i)) > varThreshold * ldaStd)
606 selections.append(i); 606 selections.append(i);
openbr/plugins/stasm4.cpp
@@ -180,7 +180,7 @@ private: @@ -180,7 +180,7 @@ private:
180 void project(const Template &src, Template &dst) const 180 void project(const Template &src, Template &dst) const
181 { 181 {
182 QList<float> paramList = src.file.getList<float>("affineParameters"); 182 QList<float> paramList = src.file.getList<float>("affineParameters");
183 - Eigen::MatrixXf points = pointsToMatrix(src.file.points(), true); 183 + Eigen::MatrixXf points = EigenUtils::pointsToMatrix(src.file.points(), true);
184 Eigen::MatrixXf affine = Eigen::MatrixXf::Zero(3, 3); 184 Eigen::MatrixXf affine = Eigen::MatrixXf::Zero(3, 3);
185 for (int i = 0, cnt = 0; i < 2; i++) 185 for (int i = 0, cnt = 0; i < 2; i++)
186 for (int j = 0; j < 3; j++, cnt++) 186 for (int j = 0; j < 3; j++, cnt++)
@@ -192,7 +192,7 @@ private: @@ -192,7 +192,7 @@ private:
192 points = affineInv * pointsT; 192 points = affineInv * pointsT;
193 dst = src; 193 dst = src;
194 dst.file.clearPoints(); 194 dst.file.clearPoints();
195 - dst.file.setPoints(matrixToPoints(points.transpose())); 195 + dst.file.setPoints(EigenUtils::matrixToPoints(points.transpose()));
196 } 196 }
197 }; 197 };
198 198