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 4 using namespace Eigen;
5 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 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 16 MatrixXf Y(X.rows() - 1,X.cols() - 1);
82 17  
83 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 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 35 MatrixXf P(points.size(), isAffine ? 3 : 2);
101 36 for (int i = 0; i < points.size(); i++) {
102 37 P(i, 0) = points[i].x();
... ... @@ -107,7 +42,7 @@ MatrixXf pointsToMatrix(const QList&lt;QPointF&gt; points, bool isAffine) {
107 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 46 QList<QPointF> points;
112 47 for (int i = 0; i < P.rows(); i++)
113 48 points.append(QPointF(P(i, 0), P(i, 1)));
... ... @@ -115,7 +50,7 @@ QList&lt;QPointF&gt; matrixToPoints(const Eigen::MatrixXf P) {
115 50 }
116 51  
117 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 54 int n = vector.rows();
120 55 Eigen::MatrixXf matrix(n / 2, 2);
121 56 for (int i = 0; i < n / 2; i++) {
... ... @@ -126,7 +61,7 @@ Eigen::MatrixXf vectorToMatrix(const Eigen::MatrixXf vector) {
126 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 65 int n2 = matrix.rows();
131 66 Eigen::MatrixXf vector(n2 * 2, 1);
132 67 for (int i = 0; i < n2; i++) {
... ... @@ -136,12 +71,3 @@ Eigen::MatrixXf matrixToVector(const Eigen::MatrixXf matrix) {
136 71 }
137 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 18 #define EIGENUTILS_H
19 19  
20 20 #include <QDataStream>
  21 +#include <QDebug>
21 22 #include <Eigen/Core>
22 23 #include <assert.h>
23 24  
  25 +#include <opencv2/core/eigen.hpp>
24 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 90 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
49 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 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 128 #endif // EIGENUTILS_H
... ...
openbr/plugins/eigen3.cpp
... ... @@ -600,7 +600,7 @@ class SparseLDATransform : public Transform
600 600  
601 601 //Only works on binary class problems for now
602 602 assert(ldaOrig.projection.cols() == 1);
603   - float ldaStd = eigStd(ldaOrig.projection);
  603 + float ldaStd = EigenUtils::stddev(ldaOrig.projection);
604 604 for (int i = 0; i < ldaOrig.projection.rows(); i++)
605 605 if (abs(ldaOrig.projection(i)) > varThreshold * ldaStd)
606 606 selections.append(i);
... ...
openbr/plugins/stasm4.cpp
... ... @@ -180,7 +180,7 @@ private:
180 180 void project(const Template &src, Template &dst) const
181 181 {
182 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 184 Eigen::MatrixXf affine = Eigen::MatrixXf::Zero(3, 3);
185 185 for (int i = 0, cnt = 0; i < 2; i++)
186 186 for (int j = 0; j < 3; j++, cnt++)
... ... @@ -192,7 +192,7 @@ private:
192 192 points = affineInv * pointsT;
193 193 dst = src;
194 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  
... ...