diff --git a/sdk/plugins/algorithms.cpp b/sdk/plugins/algorithms.cpp index f8ca61d..0f28273 100644 --- a/sdk/plugins/algorithms.cpp +++ b/sdk/plugins/algorithms.cpp @@ -50,7 +50,7 @@ class AlgorithmsInitializer : public Initializer Globals->abbreviations.insert("SmallSIFT", "Open+LimitSize(512)+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)"); Globals->abbreviations.insert("SmallSURF", "Open+LimitSize(512)+KeyPointDetector(SURF)+KeyPointDescriptor(SURF):KeyPointMatcher(BruteForce)"); Globals->abbreviations.insert("ColorHist", "Open+LimitSize(512)!EnsureChannels(3)+SplitChannels+Hist(256,0,8)+Cat+Normalize(L1):L2"); - Globals->abbreviations.insert("IHH", "Open+(RG+MAdd(0.5))/(Cvt(Gray)+Gradient+Bin(0,360,8,true))+Merge+Integral+IntegralSampler+CvtFloat:L2"); + Globals->abbreviations.insert("IHH", "Open+(RG+MAdd(0.5))/(Cvt(Gray)+Gradient+Bin(0,360,8,true))+Merge+Integral+IntegralSampler+CvtFloat+RowWisePCA(8)+RowWiseMeanCenter+Binarize:L2"); // Hash Globals->abbreviations.insert("FileName", "Name+Identity:Identical"); diff --git a/sdk/plugins/eigen3.cpp b/sdk/plugins/eigen3.cpp index 3026651..1368d25 100644 --- a/sdk/plugins/eigen3.cpp +++ b/sdk/plugins/eigen3.cpp @@ -32,6 +32,10 @@ namespace br class PCATransform : public Transform { Q_OBJECT + friend class DFFSTransform; + friend class LDATransform; + +protected: Q_PROPERTY(float keep READ get_keep WRITE set_keep RESET reset_keep STORED false) Q_PROPERTY(int drop READ get_drop WRITE set_drop RESET reset_drop STORED false) Q_PROPERTY(bool whiten READ get_whiten WRITE set_whiten RESET reset_whiten STORED false) @@ -42,12 +46,10 @@ class PCATransform : public Transform BR_PROPERTY(int, drop, 0) BR_PROPERTY(bool, whiten, false) - int originalRows; Eigen::VectorXf mean, eVals; Eigen::MatrixXf eVecs; - friend class DFFSTransform; - friend class LDATransform; + int originalRows; public: PCATransform() : keep(0.95), drop(0), whiten(false) {} @@ -118,6 +120,7 @@ private: stream >> keep >> drop >> whiten >> originalRows >> mean >> eVals >> eVecs; } +protected: void train(Eigen::MatrixXd data) { int dimsIn = data.rows(); @@ -200,6 +203,50 @@ BR_REGISTER(Transform, PCATransform) /*! * \ingroup transforms + * \brief PCA on each row. + * \author Josh Klontz \cite jklontz + */ +class RowWisePCATransform : public PCATransform +{ + Q_OBJECT + + void train(const TemplateList &trainingSet) + { + if (trainingSet.first().m().type() != CV_32FC1) + qFatal("Requires single channel 32-bit floating point matrices."); + + originalRows = trainingSet.first().m().rows; + const int dimsIn = trainingSet.first().m().cols; + int instances = 0; + foreach (const Template &t, trainingSet) + instances += t.m().rows; + + // Map into 64-bit Eigen matrix + Eigen::MatrixXd data(dimsIn, instances); + int index = 0; + foreach (const Template &t, trainingSet) + for (int i=0; i(t.m().ptr(i), dimsIn, 1).cast(); + + PCATransform::train(data); + } + + void project(const Template &src, Template &dst) const + { + dst = cv::Mat(src.m().rows, keep, CV_32FC1); + + for (int i=0; i inMap(src.m().ptr(i), src.m().cols, 1); + Eigen::Map outMap(dst.m().ptr(i), keep, 1); + outMap = eVecs.transpose() * (inMap - mean); + } + } +}; + +BR_REGISTER(Transform, RowWisePCATransform) + +/*! + * \ingroup transforms * \brief Computes Distance From Feature Space (DFFS) \cite moghaddam97. * \author Josh Klontz \cite jklontz */ diff --git a/sdk/plugins/integral.cpp b/sdk/plugins/integral.cpp index b403597..6b4eb2b 100644 --- a/sdk/plugins/integral.cpp +++ b/sdk/plugins/integral.cpp @@ -38,8 +38,8 @@ class IntegralSamplerTransform : public UntrainableTransform Q_PROPERTY(float scaleFactor READ get_scaleFactor WRITE set_scaleFactor RESET reset_scaleFactor STORED false) Q_PROPERTY(float stepFactor READ get_stepFactor WRITE set_stepFactor RESET reset_stepFactor STORED false) Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false) - BR_PROPERTY(int, scales, 3) - BR_PROPERTY(float, scaleFactor, 2) + BR_PROPERTY(int, scales, 4) + BR_PROPERTY(float, scaleFactor, 1.5) BR_PROPERTY(float, stepFactor, 0.25) BR_PROPERTY(int, minSize, 8) diff --git a/sdk/plugins/normalize.cpp b/sdk/plugins/normalize.cpp index 6e466d3..4300bf4 100644 --- a/sdk/plugins/normalize.cpp +++ b/sdk/plugins/normalize.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "core/common.h" @@ -184,6 +185,45 @@ private: BR_REGISTER(Transform, CenterTransform) +/*! + * \ingroup transforms + * \brief Remove the row-wise training set average. + * \author Josh Klontz \cite jklontz + */ +class RowWiseMeanCenterTransform : public Transform +{ + Q_OBJECT + Mat mean; + + void train(const TemplateList &data) + { + Mat m = OpenCVUtils::toMatByRow(data.data()); + mean = Mat(1, m.cols, m.type()); + for (int i=0; i> mean; + } +}; + +BR_REGISTER(Transform, RowWiseMeanCenterTransform) + } // namespace br #include "normalize.moc" diff --git a/sdk/plugins/quantize.cpp b/sdk/plugins/quantize.cpp index 02bd475..416289b 100644 --- a/sdk/plugins/quantize.cpp +++ b/sdk/plugins/quantize.cpp @@ -64,7 +64,8 @@ class BinarizeTransform : public UntrainableTransform void project(const Template &src, Template &dst) const { const Mat &m = src; - assert((m.cols % 8 == 0) && (m.type() == CV_32FC1)); + if ((m.cols % 8 != 0) || (m.type() != CV_32FC1)) + qFatal("Expected CV_32FC1 matrix with a multiple of 8 columns."); Mat n(m.rows, m.cols/8, CV_8UC1); for (int i=0; i