Commit 8f957ce1d545c5c53a982ac38dc782510d0c2c66

Authored by Scott Klum
2 parents 0bcb4058 568379f5

Merge branch 'master' of https://github.com/biometrics/openbr

app/br/br.cpp
... ... @@ -146,6 +146,9 @@ public:
146 146 } else if (!strcmp(fun, "plotDetection")) {
147 147 check(parc >= 2, "Incorrect parameter count for 'plotDetection'.");
148 148 br_plot_detection(parc-1, parv, parv[parc-1], true);
  149 + } else if (!strcmp(fun, "plotLandmarking")) {
  150 + check(parc >= 2, "Incorrect parameter count for 'plotLandmarking'.");
  151 + br_plot_landmarking(parc-1, parv, parv[parc-1], true);
149 152 } else if (!strcmp(fun, "plotMetadata")) {
150 153 check(parc >= 2, "Incorrect parameter count for 'plotMetadata'.");
151 154 br_plot_metadata(parc-1, parv, parv[parc-1], true);
... ... @@ -224,6 +227,7 @@ private:
224 227 "-evalLandmarking <predicted_gallery> <truth_gallery> [{csv} [<normalization_index_a> <normalization_index_b>]]\n"
225 228 "-evalRegression <predicted_gallery> <truth_gallery> <predicted property name> <ground truth property name>\n"
226 229 "-plotDetection <file> ... <file> {destination}\n"
  230 + "-plotLandmarking <file> ... <file> {destination}\n"
227 231 "-plotMetadata <file> ... <file> <columns>\n"
228 232 "-getHeader <matrix>\n"
229 233 "-setHeader {<matrix>} <target_gallery> <query_gallery>\n"
... ...
openbr/core/plot.cpp
... ... @@ -302,7 +302,6 @@ bool filesHaveSinglePoint(const QStringList &amp;files) {
302 302 bool PlotDetection(const QStringList &files, const File &destination, bool show)
303 303 {
304 304 qDebug("Plotting %d detection file(s) to %s", files.size(), qPrintable(destination));
305   -
306 305 RPlot p(files, destination, false);
307 306  
308 307 p.file.write("# Split data into individual plots\n"
... ... @@ -345,6 +344,22 @@ bool PlotDetection(const QStringList &amp;files, const File &amp;destination, bool show)
345 344 return p.finalize(show);
346 345 }
347 346  
  347 +bool PlotLandmarking(const QStringList &files, const File &destination, bool show)
  348 +{
  349 + qDebug("Plotting %d landmarking file(s) to %s", files.size(), qPrintable(destination));
  350 + RPlot p(files, destination, false);
  351 +
  352 + p.file.write("# Split data into individual plots\n"
  353 + "plot_index = which(names(data)==\"Plot\")\n"
  354 + "Box <- data[grep(\"Box\",data$Plot),-c(1)]\n"
  355 + "rm(data)\n"
  356 + "\n");
  357 +
  358 + p.file.write("ggplot(Box, aes(factor(X),Y)) + geom_boxplot() + geom_jitter(size=1.33,alpha=0.66) + scale_x_discrete(\"Landmark\") + scale_y_log10(\"Normalized Error\", breaks=c(0.01,0.1,1,10)) + annotation_logticks(sides=\"l\")\n\n");
  359 +
  360 + return p.finalize(show);
  361 +}
  362 +
348 363 bool PlotMetadata(const QStringList &files, const QString &columns, bool show)
349 364 {
350 365 qDebug("Plotting %d metadata file(s) for columns %s", files.size(), qPrintable(columns));
... ...
openbr/core/plot.h
... ... @@ -26,6 +26,7 @@ namespace br
26 26 {
27 27 bool Plot(const QStringList &files, const File &destination, bool show = false);
28 28 bool PlotDetection(const QStringList &files, const File &destination, bool show = false);
  29 + bool PlotLandmarking(const QStringList &files, const File &destination, bool show = false);
29 30 bool PlotMetadata(const QStringList &files, const QString &destination, bool show = false);
30 31 }
31 32  
... ...
openbr/openbr.cpp
... ... @@ -182,6 +182,11 @@ bool br_plot_detection(int num_files, const char *files[], const char *destinati
182 182 return PlotDetection(QtUtils::toStringList(num_files, files), destination, show);
183 183 }
184 184  
  185 +bool br_plot_landmarking(int num_files, const char *files[], const char *destination, bool show)
  186 +{
  187 + return PlotLandmarking(QtUtils::toStringList(num_files, files), destination, show);
  188 +}
  189 +
185 190 bool br_plot_metadata(int num_files, const char *files[], const char *columns, bool show)
186 191 {
187 192 return PlotMetadata(QtUtils::toStringList(num_files, files), columns, show);
... ...
openbr/openbr.h
... ... @@ -295,6 +295,18 @@ BR_EXPORT bool br_plot(int num_files, const char *files[], const char *destinati
295 295 BR_EXPORT bool br_plot_detection(int num_files, const char *files[], const char *destination, bool show = false);
296 296  
297 297 /*!
  298 + * \brief Renders landmarking performance figures for a set of <tt>.csv</tt> files created by \ref br_eval_landmarking.
  299 + *
  300 + * In order of their output, the figures are:
  301 + * -# Normalized error box plots (Box)
  302 + *
  303 + * Landmarking error is normalized against the distance between two predifined points, usually inter-ocular distance (IOD).
  304 + *
  305 + * \see br_plot
  306 + */
  307 +BR_EXPORT bool br_plot_landmarking(int num_files, const char *files[], const char *destination, bool show = false);
  308 +
  309 +/*!
298 310 * \brief Renders metadata figures for a set of <tt>.csv</tt> files with specified columns.
299 311 *
300 312 * Several files will be created:
... ...
openbr/plugins/algorithms.cpp
... ... @@ -50,9 +50,9 @@ class AlgorithmsInitializer : public Initializer
50 50 Globals->abbreviations.insert("PerFrameDetection", "Stream(SaveMat(original)+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+RestoreMat(original)+Draw(inPlace=true)+Show(false,[FrameNumber])+Discard)");
51 51 Globals->abbreviations.insert("AgeGenderDemo", "Stream(SaveMat(original)+Cvt(Gray)+Cascade(FrontalFace)+Expand+<FaceClassificationRegistration>+<FaceClassificationExtraction>+<AgeRegressor>/<GenderClassifier>+Discard+RestoreMat(original)+Draw(inPlace=true)+DrawPropertiesPoint([Age,Gender],Affine_0,inPlace=true)+SaveMat(original)+Discard+Contract+RestoreMat(original)+FPSCalc+Show(false,[AvgFPS,Age,Gender])+Discard)");
52 52  
53   - Globals->abbreviations.insert("HOG", "Stream(DropFrames(5)+Cvt(Gray)+KeyPointDetector(SIFT)+ROI+Expand+Resize(32,32)+Gradient+RectRegions+Bin(0,360,8)+Hist(8)+Cat)+Contract+CatRows+KMeans(500)+Hist(500)+SVM");
54   - Globals->abbreviations.insert("HOF", "Stream(DropFrames(5)+KeyPointDetector(SIFT)+AggregateFrames(2)+OpticalFlow+ROI+Expand+Resize(32,32)+Gradient+RectRegions+Bin(0,360,8)+Hist(8)+Cat)+Contract+CatRows+KMeans(500)+Hist(500)");
55   - Globals->abbreviations.insert("HOGHOF", "Stream(DropFrames(5)+KeyPointDetector(SIFT)+AggregateFrames(2)+(OpticalFlow++ROI+Expand+Resize(32,32)+Gradient+RectRegions+Bin(0,360,8)+Hist(8)+Cat+Contract)/(First+Cvt(Gray)+ROI+Expand+Resize(32,32)+Gradient+RectRegions+Bin(0,360,8)+Hist(8)+Cat+Contract)+CatCols)+Contract+CatRows+KMeans(500)+Hist(500)+SVM");
  53 + Globals->abbreviations.insert("HOG", "Stream(DropFrames(5)+Cvt(Gray)+Grid(5,5)+ROIFromPts(32,24)+Expand+Resize(32,32)+Gradient+RectRegions+Bin(0,360,8)+Hist(8)+Cat)+Contract+CatRows+KMeans(500)+Hist(500)+SVM");
  54 + Globals->abbreviations.insert("HOF", "Stream(DropFrames(5)+Grid(5,5)+AggregateFrames(2)+OpticalFlow+ROIFromPts(32,24)+Expand+Resize(32,32)+Gradient+RectRegions+Bin(0,360,8)+Hist(8)+Cat)+Contract+CatRows+KMeans(500)+Hist(500)");
  55 + Globals->abbreviations.insert("HOGHOF", "Stream(DropFrames(5)+Grid(5,5)+AggregateFrames(2)+(OpticalFlow+ROIFromPts(32,24)+Expand+Resize(32,32)+Gradient+RectRegions+Bin(0,360,8)+Hist(8)+Cat+Contract)/(First+Cvt(Gray)+ROIFromPts(32,24)+Expand+Resize(32,32)+Gradient+RectRegions+Bin(0,360,8)+Hist(8)+Cat+Contract)+CatCols)+Contract+CatRows+KMeans(500)+Hist(500)+SVM");
56 56  
57 57 // Generic Image Processing
58 58 Globals->abbreviations.insert("SIFT", "Open+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)");
... ...
openbr/plugins/crop.cpp
... ... @@ -69,6 +69,31 @@ BR_REGISTER(Transform, ROITransform)
69 69  
70 70 /*!
71 71 * \ingroup transforms
  72 + * \brief Crops the rectangular regions of interest from given points and sizes.
  73 + * \author Austin Blanton \cite imaus10
  74 + */
  75 +class ROIFromPtsTransform : public UntrainableTransform
  76 +{
  77 + Q_OBJECT
  78 + Q_PROPERTY(int width READ get_width WRITE set_width RESET reset_width STORED false)
  79 + Q_PROPERTY(int height READ get_height WRITE set_height RESET reset_height STORED false)
  80 + BR_PROPERTY(int, width, 1)
  81 + BR_PROPERTY(int, height, 1)
  82 +
  83 + void project(const Template &src, Template &dst) const
  84 + {
  85 + foreach (const QPointF &pt, src.file.points()) {
  86 + int x = pt.x() - (width/2);
  87 + int y = pt.y() - (height/2);
  88 + dst += src.m()(Rect(x, y, width, height));
  89 + }
  90 + }
  91 +};
  92 +
  93 +BR_REGISTER(Transform, ROIFromPtsTransform)
  94 +
  95 +/*!
  96 + * \ingroup transforms
72 97 * \brief Resize the template
73 98 * \author Josh Klontz \cite jklontz
74 99 * \note Method: Area should be used for shrinking an image, Cubic for slow but accurate enlargment, Bilin for fast enlargement.
... ...
openbr/plugins/eigen3.cpp
... ... @@ -253,9 +253,7 @@ class DFFSTransform : public Transform
253 253 {
254 254 Q_OBJECT
255 255 Q_PROPERTY(float keep READ get_keep WRITE set_keep RESET reset_keep STORED false)
256   - Q_PROPERTY(br::Transform *transform READ get_transform WRITE set_transform STORED false)
257 256 BR_PROPERTY(float, keep, 0.95)
258   - BR_PROPERTY(br::Transform*, transform, NULL)
259 257  
260 258 PCATransform pca;
261 259 Transform *cvtFloat;
... ...
openbr/plugins/frames.cpp
... ... @@ -52,6 +52,11 @@ private:
52 52 {
53 53 (void) stream;
54 54 }
  55 +
  56 + void init()
  57 + {
  58 + TimeVaryingTransform::init();
  59 + }
55 60 };
56 61  
57 62 BR_REGISTER(Transform, AggregateFrames)
... ...
openbr/plugins/fst3.cmake deleted
1   -set(BR_WITH_FST3 OFF CACHE BOOL "Build with Feature Selection Toolbox 3")
2   -
3   -if(${BR_WITH_FST3})
4   - find_package(FST3 REQUIRED)
5   - set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} plugins/fst3.cpp ${FST3_SRC})
6   -
7   - find_package(Boost REQUIRED)
8   - include_directories(${Boost_INCLUDE_DIRS})
9   - set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} boost_thread)
10   -
11   - find_package(LibSVM REQUIRED)
12   - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} ${LibSVM_SRC})
13   -endif()
openbr/plugins/fst3.cpp deleted
1   -#include <QMap>
2   -#include <QString>
3   -#include <QStringList>
4   -#include <QTime>
5   -#include <opencv2/core/core.hpp>
6   -#include <opencv2/imgproc/imgproc.hpp>
7   -#include <mm_plugin.h>
8   -
9   -#include "model.h"
10   -#include "common/opencvutils.h"
11   -#include "common/qtutils.h"
12   -#include "plugins/meta.h"
13   -#include "plugins/regions.h"
14   -
15   -//#ifdef MM_SDK_TRAINABLE
16   -#include <boost/smart_ptr.hpp>
17   -#include <exception>
18   -#include <iostream>
19   -#include <cstdlib>
20   -#include <sstream>
21   -#include <string>
22   -#include <vector>
23   -
24   -#include <error.hpp>
25   -#include <global.hpp>
26   -#include <subset.hpp>
27   -#include <data_intervaller.hpp>
28   -#include <data_splitter.hpp>
29   -#include <data_splitter_5050.hpp>
30   -#include <data_splitter_cv.hpp>
31   -#include <data_splitter_resub.hpp>
32   -#include <data_scaler.hpp>
33   -#include <data_scaler_void.hpp>
34   -#include <data_accessor_splitting_mem.hpp>
35   -#include <criterion_wrapper.hpp>
36   -#include <distance_euclid.hpp>
37   -#include <classifier_knn.hpp>
38   -#include <seq_step_straight_threaded.hpp>
39   -#include <search_seq_dos.hpp>
40   -#include <search_seq_sfs.hpp>
41   -#include <search_seq_sffs.hpp>
42   -#include <search_monte_carlo_threaded.hpp>
43   -
44   -using namespace FST;
45   -//#endif // MM_SDK_TRAINABLE
46   -
47   -using namespace mm;
48   -
49   -enum DimensionStatus {
50   - On,
51   - Off,
52   - Ignore
53   -};
54   -
55   -//#ifdef MM_SDK_TRAINABLE
56   -template<typename DATATYPE, typename IDXTYPE, class INTERVALCONTAINER>
57   -class FST3Data_Accessor_Splitting_MemMM : public Data_Accessor_Splitting_Mem<DATATYPE,IDXTYPE,INTERVALCONTAINER>
58   -{
59   - QList<MatrixList> mll;
60   - QList<DimensionStatus> dsl;
61   - int features;
62   - QMap<int, int> labelCounts;
63   -
64   -public:
65   - typedef Data_Accessor_Splitting_Mem<DATATYPE,IDXTYPE,INTERVALCONTAINER> DASM;
66   - typedef boost::shared_ptr<Data_Scaler<DATATYPE> > PScaler;
67   - typedef typename DASM::PSplitters PSplitters;
68   -
69   - FST3Data_Accessor_Splitting_MemMM(const QList<MatrixList> &_mll, const QList<DimensionStatus> &_dsl, const PSplitters _dsp, const PScaler _dsc)
70   - : Data_Accessor_Splitting_Mem<DATATYPE,IDXTYPE,INTERVALCONTAINER>("MM", _dsp, _dsc), mll(_mll), dsl(_dsl)
71   - {
72   - features = 0;
73   - foreach (DimensionStatus ds, dsl)
74   - if (ds != Ignore) features++;
75   - labelCounts = mll.first().labelCounts();
76   - }
77   -
78   - FST3Data_Accessor_Splitting_MemMM(const MatrixList &_ml, const PSplitters _dsp, const PScaler _dsc)
79   - : Data_Accessor_Splitting_Mem<DATATYPE,IDXTYPE,INTERVALCONTAINER>("MM", _dsp, _dsc)
80   - {
81   - mll.append(_ml);
82   - features = _ml.first().total() * _ml.first().channels();
83   - for (int i=0; i<features; i++)
84   - dsl.append(Off);
85   - labelCounts = _ml.labelCounts();
86   - }
87   -
88   - FST3Data_Accessor_Splitting_MemMM* sharing_clone() const;
89   - virtual std::ostream& print(std::ostream& os) const;
90   -
91   -protected:
92   - FST3Data_Accessor_Splitting_MemMM(const Data_Accessor_Splitting_MemMM &damt, int x)
93   - : Data_Accessor_Splitting_Mem<DATATYPE,IDXTYPE,INTERVALCONTAINER>(damt, x)
94   - {} // weak (referencing) copy-constructor to be used in sharing_clone()
95   -
96   - virtual void initial_data_read(); //!< \note off-limits in shared_clone
97   - virtual void initial_file_prepare() {}
98   -
99   -public:
100   - virtual unsigned int file_getNoOfClasses() const { return labelCounts.size(); }
101   - virtual unsigned int file_getNoOfFeatures() const { return features; }
102   - virtual IDXTYPE file_getClassSize(unsigned int cls) const { return labelCounts[cls]; }
103   -};
104   -
105   -template<typename DATATYPE, typename IDXTYPE, class INTERVALCONTAINER>
106   -void FST3Data_Accessor_Splitting_MemMM<DATATYPE,IDXTYPE,INTERVALCONTAINER>::initial_data_read() //!< \note off-limits in shared_clone
107   -{
108   - if (Clonable::is_sharing_clone()) throw fst_error("Data_Accessor_Splitting_MemMM()::initial_data_read() called from shared_clone instance.");
109   - IDXTYPE idx=0;
110   -
111   - // TODO: Assert that ml data type is DATATYPE
112   - const QList<float> labels = mll.first().labels();
113   - foreach (int label, labelCounts.keys()) {
114   - for (int i=0; i<labels.size(); i++) {
115   - if (labels[i] == label) {
116   - int dslIndex = 0;
117   - foreach (const MatrixList &ml, mll) {
118   - const Matrix &m = ml[i];
119   - const int dims = m.total() * m.channels();
120   - for (int j=0; j<dims; j++)
121   - if (dsl[dslIndex++] != Ignore)
122   - this->data[idx++] = reinterpret_cast<float*>(m.data)[j];
123   - }
124   - }
125   - }
126   - }
127   -}
128   -
129   -/*template<typename DATATYPE, typename IDXTYPE, class INTERVALCONTAINER>
130   -Data_Accessor_Splitting_MemMM<DATATYPE,IDXTYPE,INTERVALCONTAINER>* Data_Accessor_Splitting_MemMM<DATATYPE,IDXTYPE,INTERVALCONTAINER>::sharing_clone() const
131   -{
132   - Data_Accessor_Splitting_MemMM<DATATYPE,IDXTYPE,INTERVALCONTAINER> *clone=new Data_Accessor_Splitting_MemMM<DATATYPE,IDXTYPE,INTERVALCONTAINER>(*this, (int)0);
133   - clone->set_sharing_cloned();
134   - return clone;
135   -}
136   -
137   -template<typename DATATYPE, typename IDXTYPE, class INTERVALCONTAINER>
138   -std::ostream& Data_Accessor_Splitting_MemMM<DATATYPE,IDXTYPE,INTERVALCONTAINER>::print(std::ostream& os) const
139   -{
140   - DASM::print(os);
141   - os << std::endl << "Data_Accessor_Splitting_MemMM()";
142   - return os;
143   -}*/
144   -
145   -//#endif // MM_SDK_TRAINABLE
146   -
147   -
148   -class FST3DOS : public Feature
149   -{
150   - friend class Maker<DOS,true>;
151   -
152   - int delta;
153   -
154   - mm::Remap remap;
155   -
156   - DOS(int delta = 1)
157   - {
158   - this->delta = delta;
159   - }
160   -
161   - static QString args()
162   - {
163   - return "delta = 1";
164   - }
165   -
166   - static DOS *make(const QString &args)
167   - {
168   - QStringList words = QtUtils::parse(args);
169   - if (words.size() > 1) qFatal("DOS::make invalid argument count.");
170   -
171   - int delta = 1;
172   -
173   - bool ok;
174   - switch (words.size()) {
175   - case 1:
176   - delta = words[0].toInt(&ok); if (!ok) qFatal("DOS::make expected integer delta.");
177   - }
178   -
179   - return new DOS(delta);
180   - }
181   -
182   - QSharedPointer<Feature> clone() const
183   - {
184   - return QSharedPointer<Feature>(new DOS(delta));
185   - }
186   -
187   - void train(const MatrixList &data, Matrix &metadata)
188   - {
189   - (void) metadata;
190   - //#ifdef MM_SDK_TRAINABLE
191   - try {
192   - typedef float RETURNTYPE; typedef float DATATYPE; typedef float REALTYPE;
193   - typedef unsigned int IDXTYPE; typedef unsigned int DIMTYPE; typedef int BINTYPE;
194   - typedef Subset<BINTYPE, DIMTYPE> SUBSET;
195   - typedef Data_Intervaller<std::vector<Data_Interval<IDXTYPE> >,IDXTYPE> INTERVALLER;
196   - typedef boost::shared_ptr<Data_Splitter<INTERVALLER,IDXTYPE> > PSPLITTER;
197   - typedef Data_Splitter_CV<INTERVALLER,IDXTYPE> SPLITTERCV;
198   - typedef Data_Splitter_5050<INTERVALLER,IDXTYPE> SPLITTER5050;
199   - typedef Data_Splitter_Resub<INTERVALLER,IDXTYPE> SPLITTERRESUB;
200   - typedef Data_Accessor_Splitting_MemMM<DATATYPE,IDXTYPE,INTERVALLER> DATAACCESSOR;
201   - typedef Distance_Euclid<DATATYPE,DIMTYPE,SUBSET> DISTANCE;
202   - typedef Classifier_kNN<RETURNTYPE,DATATYPE,IDXTYPE,DIMTYPE,SUBSET,DATAACCESSOR,DISTANCE> CLASSIFIERKNN;
203   - typedef Criterion_Wrapper<RETURNTYPE,SUBSET,CLASSIFIERKNN,DATAACCESSOR> WRAPPERKNN;
204   - typedef Sequential_Step_Straight_Threaded<RETURNTYPE,DIMTYPE,SUBSET,WRAPPERKNN,24> EVALUATOR;
205   -
206   - // Initialize dataset
207   - PSPLITTER dsp_outer(new SPLITTER5050()); // keep second half of data for independent testing of final classification performance
208   - PSPLITTER dsp_inner(new SPLITTERCV(3)); // in the course of search use the first half of data by 3-fold cross-validation in wrapper FS criterion evaluation
209   - boost::shared_ptr<Data_Scaler<DATATYPE> > dsc(new Data_Scaler_void<DATATYPE>()); // do not scale data
210   - boost::shared_ptr<std::vector<PSPLITTER> > splitters(new std::vector<PSPLITTER>); // set-up data access
211   - splitters->push_back(dsp_outer); //splitters->push_back(dsp_inner);
212   - boost::shared_ptr<DATAACCESSOR> da(new DATAACCESSOR(data, splitters, dsc));
213   - da->initialize();
214   - da->setSplittingDepth(0); if(!da->getFirstSplit()) throw fst_error("50/50 data split failed.");
215   - //da->setSplittingDepth(1); if(!da->getFirstSplit()) throw fst_error("3-fold cross-validation failure.");
216   - boost::shared_ptr<SUBSET> sub(new SUBSET(da->getNoOfFeatures())); // initiate the storage for subset to-be-selected
217   - //sub->select_all();
218   -
219   - // Run search
220   - boost::shared_ptr<CLASSIFIERKNN> cknn(new CLASSIFIERKNN); cknn->set_k(1);
221   - boost::shared_ptr<WRAPPERKNN> wknn(new WRAPPERKNN);
222   - wknn->initialize(cknn,da);
223   - boost::shared_ptr<EVALUATOR> eval(new EVALUATOR); // set-up the standard sequential search step object (option: hybrid, ensemble, etc.)
224   - //Search_DOS<RETURNTYPE,DIMTYPE,SUBSET,WRAPPERKNN,EVALUATOR> srch(eval); // set-up Sequential Forward Floating Selection search procedure
225   - //srch.set_delta(delta);
226   -
227   - //FST::Search_SFFS<RETURNTYPE,DIMTYPE,SUBSET,WRAPPERKNN,EVALUATOR> srch(eval);
228   - //srch.set_search_direction(FST::BACKWARD);
229   -
230   - //FST::Search_SFS<RETURNTYPE,DIMTYPE,SUBSET,WRAPPERKNN,EVALUATOR> srch(eval);
231   - //srch.set_search_direction(FST::FORWARD);
232   -
233   - FST::Search_Monte_Carlo_Threaded<RETURNTYPE,DIMTYPE,SUBSET,WRAPPERKNN,24> srch;
234   - srch.set_cardinality_randomization(0.5); // probability of inclusion of each particular feature (~implies also the expected subset size)
235   - srch.set_stopping_condition(0/*max trials*/,30/*seconds*/); // one or both values must have positive value
236   -
237   - RETURNTYPE critval_train;
238   - if(!srch.search(0,critval_train,sub,wknn,std::cout)) throw fst_error("Search not finished.");
239   -
240   - // Create map matrix
241   - const int dims = sub->get_d_raw();
242   - cv::Mat xMap(1, dims, CV_16SC1),
243   - yMap(1, dims, CV_16SC1);
244   - int index = 0;
245   - for (int i=0; i<dims; i++) {
246   - if (sub->selected_raw(i)) {
247   - xMap.at<short>(0, index) = i;
248   - yMap.at<short>(0, index) = 0;
249   - index++;
250   - }
251   - }
252   -
253   - remap = Remap(xMap, yMap, cv::INTER_NEAREST);
254   - }
255   - catch (fst_error &e) { qFatal("FST ERROR: %s, code=%d", e.what(), e.code()); }
256   - catch (std::exception &e) { qFatal("non-FST ERROR: %s", e.what()); }
257   - metadata >> remap;
258   - //#else // MM_SDK_TRAINABLE
259   - //qFatal("StreamwiseFS::train not supported.");
260   - //#endif // MM_SDK_TRAINABLE
261   - }
262   -
263   - void project(const Matrix &src, Matrix &dst) const
264   - {
265   - dst = src;
266   - dst >> remap;
267   - }
268   -
269   - void store(QDataStream &stream) const
270   - {
271   - stream << remap;
272   - }
273   -
274   - void load(QDataStream &stream)
275   - {
276   - stream >> remap;
277   - }
278   -};
279   -
280   -MM_REGISTER(Feature, FST3DOS, true)
281   -
282   -
283   -class FST3StreamwiseFS : public Feature
284   -{
285   - friend class Maker<StreamwiseFS,true>;
286   -
287   - QSharedPointer<Feature> weakLearnerTemplate;
288   - int time;
289   -
290   - mm::Dup dup;
291   - mm::Remap remap;
292   -
293   - StreamwiseFS(const QSharedPointer<Feature> &weakLearnerTemplate, int time)
294   - : dup(weakLearnerTemplate, 1)
295   - {
296   - this->weakLearnerTemplate = weakLearnerTemplate;
297   - this->time = time;
298   - }
299   -
300   - static QString args()
301   - {
302   - return "<feature> weakLearnerTemplate, int time";
303   - }
304   -
305   - static StreamwiseFS *make(const QString &args)
306   - {
307   - QStringList words = QtUtils::parse(args);
308   - if (words.size() != 2) qFatal("StreamwiseFS::make invalid argument count.");
309   -
310   - QSharedPointer<Feature> weakLearnerTemplate = Feature::make(words[0]);
311   - bool ok;
312   - int time = words[1].toInt(&ok); assert(ok);
313   -
314   - return new StreamwiseFS(weakLearnerTemplate, time);
315   - }
316   -
317   - QSharedPointer<Feature> clone() const
318   - {
319   - return QSharedPointer<Feature>(new StreamwiseFS(weakLearnerTemplate, time));
320   - }
321   -
322   - void train(const MatrixList &data, Matrix &metadata)
323   - {
324   - QList< QSharedPointer<Feature> > weakLearners;
325   - QList<MatrixList> projectedDataList;
326   - QList<int> weakLearnerDimsList;
327   - QList<DimensionStatus> dimStatusList;
328   -
329   - QTime timer; timer.start();
330   - while (timer.elapsed() / 1000 < time) {
331   - // Construct a new weak learner
332   - QSharedPointer<Feature> newWeakLearner = weakLearnerTemplate->clone();
333   - Matrix metadataCopy(metadata);
334   - newWeakLearner->train(data, metadataCopy);
335   - weakLearners.append(newWeakLearner);
336   -
337   - MatrixList projectedData = data;
338   - projectedData >> *newWeakLearner;
339   - projectedDataList.append(projectedData);
340   - weakLearnerDimsList.append(projectedData.first().total() * projectedData.first().channels());
341   - for (int i=0; i<weakLearnerDimsList.last(); i++) dimStatusList.append(Off);
342   -
343   - //#ifdef MM_SDK_TRAINABLE
344   - try
345   - {
346   - typedef float RETURNTYPE; typedef float DATATYPE; typedef float REALTYPE;
347   - typedef unsigned int IDXTYPE; typedef unsigned int DIMTYPE; typedef int BINTYPE;
348   - typedef Subset<BINTYPE, DIMTYPE> SUBSET;
349   - typedef Data_Intervaller<std::vector<Data_Interval<IDXTYPE> >,IDXTYPE> INTERVALLER;
350   - typedef boost::shared_ptr<Data_Splitter<INTERVALLER,IDXTYPE> > PSPLITTER;
351   - typedef Data_Splitter_CV<INTERVALLER,IDXTYPE> SPLITTERCV;
352   - typedef Data_Splitter_5050<INTERVALLER,IDXTYPE> SPLITTER5050;
353   - typedef Data_Accessor_Splitting_MemMM<DATATYPE,IDXTYPE,INTERVALLER> DATAACCESSOR;
354   - typedef Distance_Euclid<DATATYPE,DIMTYPE,SUBSET> DISTANCE;
355   - typedef Classifier_kNN<RETURNTYPE,DATATYPE,IDXTYPE,DIMTYPE,SUBSET,DATAACCESSOR,DISTANCE> CLASSIFIERKNN;
356   - typedef Criterion_Wrapper<RETURNTYPE,SUBSET,CLASSIFIERKNN,DATAACCESSOR> WRAPPERKNN;
357   - typedef Sequential_Step_Straight_Threaded<RETURNTYPE,DIMTYPE,SUBSET,WRAPPERKNN,24> EVALUATOR;
358   -
359   - // Initialize dataset
360   - PSPLITTER dsp_outer(new SPLITTER5050()); // keep second half of data for independent testing of final classification performance
361   - PSPLITTER dsp_inner(new SPLITTERCV(3)); // in the course of search use the first half of data by 3-fold cross-validation in wrapper FS criterion evaluation
362   - boost::shared_ptr<Data_Scaler<DATATYPE> > dsc(new Data_Scaler_void<DATATYPE>()); // do not scale data
363   - boost::shared_ptr<std::vector<PSPLITTER> > splitters(new std::vector<PSPLITTER>); // set-up data access
364   - splitters->push_back(dsp_outer); splitters->push_back(dsp_inner);
365   - boost::shared_ptr<DATAACCESSOR> da(new DATAACCESSOR(projectedDataList, dimStatusList, splitters, dsc));
366   - da->initialize();
367   - da->setSplittingDepth(0); if(!da->getFirstSplit()) throw fst_error("50/50 data split failed.");
368   - da->setSplittingDepth(1); if(!da->getFirstSplit()) throw fst_error("3-fold cross-validation failure.");
369   - boost::shared_ptr<SUBSET> sub(new SUBSET(da->getNoOfFeatures())); // initiate the storage for subset to-be-selected
370   -
371   - { // Initialize subset from previous iteration results
372   - sub->deselect_all();
373   - int index = 0;
374   - for (int i=0; i<dimStatusList.size(); i++) {
375   - if (dimStatusList[i] == On) sub->select(index);
376   - if (dimStatusList[i] != Ignore) index++;
377   - }
378   - }
379   -
380   - // Run search
381   - boost::shared_ptr<CLASSIFIERKNN> cknn(new CLASSIFIERKNN); cknn->set_k(3); // set-up 3-Nearest Neighbor classifier based on Euclidean distances
382   - boost::shared_ptr<WRAPPERKNN> wknn(new WRAPPERKNN); // wrap the 3-NN classifier to enable its usage as FS criterion (criterion value will be estimated by 3-fold cross-val.)
383   - wknn->initialize(cknn,da);
384   - boost::shared_ptr<EVALUATOR> eval(new EVALUATOR); // set-up the standard sequential search step object (option: hybrid, ensemble, etc.)
385   - Search_DOS<RETURNTYPE,DIMTYPE,SUBSET,WRAPPERKNN,EVALUATOR> srch(eval); // set-up Sequential Forward Floating Selection search procedure
386   - srch.set_delta(1);
387   - RETURNTYPE critval_train;
388   - if(!srch.search(0,critval_train,sub,wknn,std::cout)) throw fst_error("Search not finished.");
389   -
390   - { // Update results
391   - int dslIndex = dimStatusList.size() - 1;
392   - int subIndex = da->getNoOfFeatures() - 1;
393   - for (int wlIndex = weakLearnerDimsList.size()-1; wlIndex >= 0; wlIndex--) {
394   - const int weakLearnerDims = weakLearnerDimsList[wlIndex];
395   - int numSelectedDims = 0;
396   - for (int i=0; i<weakLearnerDims; i++) {
397   - if (dimStatusList[dslIndex] != Ignore)
398   - dimStatusList[dslIndex] = sub->selected_raw(subIndex--) ? numSelectedDims++, On : Ignore;
399   - dslIndex--;
400   - }
401   -
402   - if (numSelectedDims == 0) {
403   - for (int j=0; j<weakLearnerDims; j++)
404   - dimStatusList.removeAt(dslIndex+1);
405   - weakLearnerDimsList.removeAt(wlIndex);
406   - projectedDataList.removeAt(wlIndex);
407   - weakLearners.removeAt(wlIndex);
408   - }
409   - }
410   - }
411   - }
412   - catch (fst_error &e) { qFatal("FST ERROR: %s, code=%d", e.what(), e.code()); }
413   - catch (std::exception &e) { qFatal("non-FST ERROR: %s", e.what()); }
414   - //#else // MM_SDK_TRAINABLE
415   - //qFatal("StreamwiseFS::train not supported.");
416   - //#endif // MM_SDK_TRAINABLE
417   - }
418   -
419   - dup = Dup(weakLearners);
420   -
421   - // Create map matrix
422   - int dims = 0;
423   - foreach (DimensionStatus ds, dimStatusList) if (ds == On) dims++;
424   - cv::Mat xMap(1, dims, CV_16SC1),
425   - yMap(1, dims, CV_16SC1);
426   - int index = 0;
427   - for (int i=0; i<dimStatusList.size(); i++) {
428   - if (dimStatusList[i] == On) {
429   - xMap.at<short>(0, index) = i;
430   - yMap.at<short>(0, index) = 0;
431   - index++;
432   - }
433   - }
434   -
435   - remap = Remap(xMap, yMap, cv::INTER_NEAREST);
436   - }
437   -
438   - void project(const Matrix &src, Matrix &dst) const
439   - {
440   - dst = src;
441   - dst >> dup >> mm::Cat >> remap;
442   - }
443   -
444   - void store(QDataStream &stream) const
445   - {
446   - stream << dup << remap;
447   - }
448   -
449   - void load(QDataStream &stream)
450   - {
451   - stream >> dup >> remap;
452   - }
453   -};
454   -
455   -MM_REGISTER(Feature, FST3StreamwiseFS, true)
openbr/plugins/gui.cpp
... ... @@ -350,6 +350,8 @@ public:
350 350 if (!Globals->useGui)
351 351 return;
352 352  
  353 + TimeVaryingTransform::init();
  354 +
353 355 if (displayBuffer)
354 356 delete displayBuffer;
355 357 displayBuffer = new QPixmap();
... ... @@ -530,6 +532,7 @@ public:
530 532 target_wait = 1000.0 / targetFPS;
531 533 timer.start();
532 534 last_time = timer.elapsed();
  535 + TimeVaryingTransform::init();
533 536 }
534 537  
535 538 protected:
... ... @@ -583,6 +586,7 @@ public:
583 586 {
584 587 initialized = false;
585 588 framesSeen = 0;
  589 + TimeVaryingTransform::init();
586 590 }
587 591  
588 592 protected:
... ...
openbr/plugins/keypoint.cpp
... ... @@ -222,9 +222,9 @@ class GridTransform : public UntrainableTransform
222 222 QList<QPointF> landmarks;
223 223 const float row_step = 1.f * src.m().rows / rows;
224 224 const float column_step = 1.f * src.m().cols / columns;
225   - for (float i=row_step/2; i<src.m().rows; i+=row_step)
226   - for (float j=column_step/2; j<src.m().cols; j+=column_step)
227   - landmarks.append(QPointF(i,j));
  225 + for (float y=row_step/2; y<src.m().rows; y+=row_step)
  226 + for (float x=column_step/2; x<src.m().cols; x+=column_step)
  227 + landmarks.append(QPointF(x,y));
228 228 dst = src;
229 229 dst.file.setPoints(landmarks);
230 230 }
... ...
openbr/plugins/meta.cpp
... ... @@ -264,7 +264,6 @@ class ContractTransform : public UntrainableMetaTransform
264 264  
265 265 virtual void project(const TemplateList &src, TemplateList &dst) const
266 266 {
267   - //dst = Expanded(src);
268 267 if (src.empty()) return;
269 268 Template out;
270 269  
... ... @@ -682,8 +681,10 @@ public:
682 681  
683 682 void init()
684 683 {
685   - if (transform && transform->timeVarying())
686   - transform = new br::TimeInvariantWrapperTransform(transform);
  684 + if (!transform)
  685 + return;
  686 +
  687 + trainable = transform->trainable;
687 688 }
688 689  
689 690 };
... ...
openbr/plugins/openbr_internal.h
... ... @@ -24,81 +24,27 @@ private:
24 24 };
25 25  
26 26 /*!
27   - * \brief A br::MetaTransform that does not require training data.
  27 + * \brief A br::Transform expecting multiple matrices per template.
28 28 */
29   -class BR_EXPORT UntrainableMetaTransform : public UntrainableTransform
  29 +class BR_EXPORT MetaTransform : public Transform
30 30 {
31 31 Q_OBJECT
32 32  
33 33 protected:
34   - UntrainableMetaTransform() : UntrainableTransform(false) {}
35   -};
36   -
37   -/*!
38   - * \brief A br::Transform for which the results of project may change due to prior calls to project
39   - */
40   -class BR_EXPORT TimeVaryingTransform : public Transform
41   -{
42   - Q_OBJECT
43   -
44   -public:
45   - virtual bool timeVarying() const { return true; }
46   -
47   - virtual void project(const Template &src, Template &dst) const
48   - {
49   - qFatal("No const project defined for time-varying transform");
50   - (void) dst; (void) src;
51   - }
52   -
53   - virtual void project(const TemplateList &src, TemplateList &dst) const
54   - {
55   - qFatal("No const project defined for time-varying transform");
56   - (void) dst; (void) src;
57   - }
58   -
59   - // Get a compile failure if this isn't here to go along with the other
60   - // projectUpdate, no idea why
61   - virtual void projectUpdate(const Template & src, Template & dst)
62   - {
63   - (void) src; (void) dst;
64   - qFatal("do something useful");
65   - }
66   -
67   - virtual void projectUpdate(const TemplateList &src, TemplateList &dst)
68   - {
69   - foreach (const Template & src_part, src) {
70   - Template out;
71   - projectUpdate(src_part, out);
72   - dst.append(out);
73   - }
74   - }
75   -
76   - /*!
77   - *\brief For transforms that don't do any training, this default implementation
78   - * which creates a new copy of the Transform from its description string is sufficient.
79   - */
80   - virtual Transform * smartCopy()
81   - {
82   - return this->clone();
83   - }
84   -
85   -
86   -protected:
87   - TimeVaryingTransform(bool independent = true, bool trainable = true) : Transform(independent, trainable) {}
  34 + MetaTransform() : Transform(false) {}
88 35 };
89 36  
90 37 /*!
91   - * \brief A br::Transform expecting multiple matrices per template.
  38 + * \brief A br::MetaTransform that does not require training data.
92 39 */
93   -class BR_EXPORT MetaTransform : public Transform
  40 +class BR_EXPORT UntrainableMetaTransform : public UntrainableTransform
94 41 {
95 42 Q_OBJECT
96 43  
97 44 protected:
98   - MetaTransform() : Transform(false) {}
  45 + UntrainableMetaTransform() : UntrainableTransform(false) {}
99 46 };
100 47  
101   -
102 48 class TransformCopier : public ResourceMaker<Transform>
103 49 {
104 50 public:
... ... @@ -151,6 +97,71 @@ private:
151 97 Transform * baseTransform;
152 98 };
153 99  
  100 +/*!
  101 + * \brief A br::Transform for which the results of project may change due to prior calls to project
  102 + */
  103 +class BR_EXPORT TimeVaryingTransform : public Transform
  104 +{
  105 + Q_OBJECT
  106 +
  107 +public:
  108 +
  109 + virtual bool timeVarying() const { return true; }
  110 +
  111 + virtual void project(const Template &src, Template &dst) const
  112 + {
  113 + timeInvariantAlias->project(src,dst);
  114 + }
  115 +
  116 + virtual void project(const TemplateList &src, TemplateList &dst) const
  117 + {
  118 + timeInvariantAlias->project(src,dst);
  119 + }
  120 +
  121 + // Get a compile failure if this isn't here to go along with the other
  122 + // projectUpdate, no idea why
  123 + virtual void projectUpdate(const Template & src, Template & dst)
  124 + {
  125 + (void) src; (void) dst;
  126 + qFatal("do something useful");
  127 + }
  128 +
  129 + virtual void projectUpdate(const TemplateList &src, TemplateList &dst)
  130 + {
  131 + foreach (const Template & src_part, src) {
  132 + Template out;
  133 + projectUpdate(src_part, out);
  134 + dst.append(out);
  135 + }
  136 + }
  137 +
  138 + /*!
  139 + *\brief For transforms that don't do any training, this default implementation
  140 + * which creates a new copy of the Transform from its description string is sufficient.
  141 + */
  142 + virtual Transform * smartCopy()
  143 + {
  144 + return this->clone();
  145 + }
  146 +
  147 + void init()
  148 + {
  149 + delete timeInvariantAlias;
  150 + timeInvariantAlias = new TimeInvariantWrapperTransform(this);
  151 + }
  152 +
  153 +protected:
  154 + Transform * timeInvariantAlias;
  155 + TimeVaryingTransform(bool independent = true, bool trainable = true) : Transform(independent, trainable)
  156 + {
  157 + timeInvariantAlias = NULL;
  158 + }
  159 + ~TimeVaryingTransform()
  160 + {
  161 + delete timeInvariantAlias;
  162 + }
  163 +};
  164 +
154 165  
155 166 /*!
156 167 * \brief A MetaTransform that aggregates some sub-transforms
... ... @@ -165,15 +176,17 @@ public:
165 176  
166 177 virtual void project(const Template &src, Template &dst) const
167 178 {
168   - if (timeVarying()) qFatal("No const project defined for time-varying transform");
  179 + if (timeVarying()) {
  180 + timeInvariantAlias->project(src,dst);
  181 + return;
  182 + }
169 183 _project(src, dst);
170 184 }
171 185  
172 186 virtual void project(const TemplateList &src, TemplateList &dst) const
173 187 {
174 188 if (timeVarying()) {
175   - CompositeTransform * non_const = const_cast<CompositeTransform *>(this);
176   - non_const->projectUpdate(src,dst);
  189 + timeInvariantAlias->project(src,dst);
177 190 return;
178 191 }
179 192 _project(src, dst);
... ... @@ -190,6 +203,10 @@ public:
190 203 isTimeVarying = isTimeVarying || transform->timeVarying();
191 204 trainable = trainable || transform->trainable;
192 205 }
  206 +
  207 + // If we are time varying, set up timeInvariantAlias
  208 + if (this->timeVarying())
  209 + TimeVaryingTransform::init();
193 210 }
194 211  
195 212 /*!
... ...
openbr/plugins/phash.cmake deleted
1   -set(BR_WITH_PHASH OFF CACHE BOOL "Build with pHash")
2   -
3   -if(${BR_WITH_PHASH})
4   - find_package(pHash REQUIRED)
5   - find_package(CImg REQUIRED)
6   - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/phash.cpp ${PHASH_SRC})
7   -endif()
openbr/plugins/phash.cpp deleted
1   -#include <opencv2/core/core.hpp>
2   -#include <pHash.h>
3   -#include <mm_plugin.h>
4   -
5   -using namespace mm;
6   -
7   -/**** PHASH ****/
8   -class pHashEnroll : public UntrainableFeature
9   -{
10   - void project(const Matrix &src, Matrix &dst) const
11   - {
12   - CImg<uint8_t> cImg(src.data, src.cols, src.rows, 1, src.channels());
13   - cv::Mat m(1, sizeof(ulong64), CV_8UC1);
14   - ulong64 hash;
15   - if (ph_dct_imagehash(cImg, hash) == -1)
16   - qFatal("pHashEnroll::project ph_dct_imagehash failure for file %s.", qPrintable(src.metadata.fileName));
17   - memcpy(m.data, &hash, sizeof(ulong64));
18   - dst = Matrix(m, src.metadata);
19   - }
20   -
21   - /*** Taken from pHash, modified to take in a CImg instead of a file. ***/
22   - static CImg<float>* ph_dct_matrix(const int N){
23   - CImg<float> *ptr_matrix = new CImg<float>(N,N,1,1,1/sqrt((float)N));
24   - const float c1 = sqrt(2.0/N);
25   - for (int x=0;x<N;x++){
26   - for (int y=1;y<N;y++){
27   - *ptr_matrix->data(x,y) = c1*cos((cimg::PI/2/N)*y*(2*x+1));
28   - }
29   - }
30   - return ptr_matrix;
31   - }
32   -
33   - static int ph_dct_imagehash(CImg<uint8_t> src, ulong64 &hash)
34   - {
35   - CImg<float> meanfilter(7,7,1,1,1);
36   - CImg<float> img;
37   - if (src.spectrum() == 3){
38   - img = src.RGBtoYCbCr().channel(0).get_convolve(meanfilter);
39   - } else if (src.spectrum() == 4){
40   - int width = img.width();
41   - int height = img.height();
42   - int depth = img.depth();
43   - img = src.crop(0,0,0,0,width-1,height-1,depth-1,2).RGBtoYCbCr().channel(0).get_convolve(meanfilter);
44   - } else {
45   - img = src.channel(0).get_convolve(meanfilter);
46   - }
47   -
48   - img.resize(32,32);
49   - CImg<float> *C = ph_dct_matrix(32);
50   - CImg<float> Ctransp = C->get_transpose();
51   -
52   - CImg<float> dctImage = (*C)*img*Ctransp;
53   -
54   - CImg<float> subsec = dctImage.crop(1,1,8,8).unroll('x');;
55   -
56   - float median = subsec.median();
57   - ulong64 one = 0x0000000000000001;
58   - hash = 0x0000000000000000;
59   - for (int i=0;i< 64;i++){
60   - float current = subsec(i);
61   - if (current > median)
62   - hash |= one;
63   - one = one << 1;
64   - }
65   -
66   - delete C;
67   -
68   - return 0;
69   - }
70   -};
71   -
72   -MM_REGISTER(Feature, pHashEnroll, false)
73   -
74   -
75   -/**** PHASH_COMPARE ****/
76   -class pHashCompare : public ComparerBase
77   -{
78   - float compare(const cv::Mat &a, const cv::Mat &b) const
79   - {
80   - return 1.f - 1.f * ph_hamming_distance(*reinterpret_cast<ulong64*>(a.data), *reinterpret_cast<ulong64*>(b.data)) / 64;
81   - }
82   -};
83   -
84   -MM_REGISTER(Comparer, pHashCompare, false)
85   -
86   -
87   -/**** PHASH ****/
88   -class pHash : public Algorithm
89   -{
90   - QString algorithm() const
91   - {
92   - return "Open+pHashEnroll:Identity:pHashCompare";
93   - }
94   -};
95   -
96   -MM_REGISTER(Algorithm, pHash, false)
openbr/plugins/pp4.cmake deleted
1   -set(BR_WITH_PP4 OFF CACHE BOOL "Build with PittPatt 4")
2   -
3   -if(${BR_WITH_PP4})
4   - find_package(PP4 REQUIRED)
5   - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} plugins/pp4.cpp)
6   - set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${PP4_LIBS})
7   - install(DIRECTORY ${PP4_DIR}/lib/ DESTINATION lib)
8   - install(DIRECTORY ${PP4_DIR}/models/ DESTINATION models/pp4)
9   -endif()
openbr/plugins/pp4.cpp deleted
1   -#include <QThreadPool>
2   -#include <pittpatt_errors.h>
3   -#include <pittpatt_nc_sdk.h>
4   -#include <pittpatt_raw_image_io.h>
5   -#include <pittpatt_license.h>
6   -#include <mm_plugin.h>
7   -
8   -#define TRY(CC) \
9   -{ \
10   - if ((CC) != PPR_SUCCESS) qFatal("%d error (%s, %d): %s.", CC, __FILE__, __LINE__, ppr_error_message(CC)); \
11   -}
12   -
13   -#define TRY_VIDEO(CC) \
14   -{ \
15   - if ((CC) != PPR_VIDEO_IO_SUCCESS) qFatal("%d error (%s, %d): %s.", CC, __FILE__, __LINE__, ppr_video_io_error_message(CC)); \
16   -}
17   -
18   -#define TRY_RAW_IMAGE(CC) \
19   -{ \
20   - if ((CC) != PPR_RAW_IMAGE_SUCCESS) qFatal("%d error (%s, %d): %s.", CC, __FILE__, __LINE__, ppr_raw_image_error_message(CC)); \
21   -}
22   -
23   -using namespace mm;
24   -
25   -/*!
26   - * \brief PittPatt 4 context
27   - * \author Josh Klontz \cite jklontz
28   - * \warning Needs a maintainer.
29   - */
30   -struct PP4Context
31   -{
32   - static ppr_context_type context;
33   -
34   - static void createRawImage(const cv::Mat &src, ppr_raw_image_type &dst)
35   - {
36   - ppr_raw_image_create(&dst, src.cols, src.rows, PPR_RAW_IMAGE_BGR24);
37   - assert((src.type() == CV_8UC3) && src.isContinuous());
38   - memcpy(dst.data, src.data, 3*src.rows*src.cols);
39   - }
40   -
41   - static void createMat(const ppr_template_type &src, cv::Mat &dst)
42   - {
43   - ppr_flat_template_type flat_template;
44   - TRY(ppr_flatten_template(context,src,&flat_template))
45   - dst = cv::Mat(1, flat_template.num_bytes, CV_8UC1, flat_template.data).clone();
46   - ppr_free_flat_template(flat_template);
47   - }
48   -
49   - static void createTemplate(const cv::Mat &src, ppr_template_type *dst)
50   - {
51   - ppr_flat_template_type flat_template;
52   - flat_template.num_bytes = src.cols;
53   - flat_template.data = src.data;
54   - TRY(ppr_unflatten_template(context, flat_template, dst))
55   - }
56   -
57   - static QString toString(const ppr_landmark_category_type &category)
58   - {
59   - switch (category) {
60   - case PPR_LANDMARK_LEFT_EYE:
61   - return "Left_Eye";
62   - case PPR_LANDMARK_RIGHT_EYE:
63   - return "Right_Eye";
64   - case PPR_LANDMARK_NOSE_BASE:
65   - return "Nose_Base";
66   - case PPR_LANDMARK_NOSE_BRIDGE:
67   - return "Nose_Bridge";
68   - case PPR_LANDMARK_NOSE_TIP:
69   - return "Nose_Tip";
70   - case PPR_LANDMARK_NOSE_TOP:
71   - return "Nose_Top";
72   - case PPR_LANDMARK_EYE_NOSE:
73   - return "Eye_Nose";
74   - case PPR_LANDMARK_MOUTH:
75   - return "Mouth";
76   - }
77   -
78   - return "Unknown";
79   - }
80   -
81   - static File toMetadata(const ppr_object_type &object)
82   - {
83   - File metadata;
84   - metadata.insert("PP4_Object_X", object.position.x - object.dimensions.width/2);
85   - metadata.insert("PP4_Object_Y", object.position.y - object.dimensions.height/2);
86   - metadata.insert("PP4_Object_Width", object.dimensions.width);
87   - metadata.insert("PP4_Object_Height", object.dimensions.height);
88   - metadata.insert("PP4_Object_Confidence", object.confidence);
89   - metadata.insert("PP4_Object_Roll", object.rotation.roll);
90   - metadata.insert("PP4_Object_Pitch", object.rotation.pitch);
91   - metadata.insert("PP4_Object_Yaw", object.rotation.yaw);
92   - metadata.insert("PP4_Object_Precision", object.rotation.precision);
93   - metadata.insert("PP4_Object_ModelID", object.model_id);
94   - metadata.insert("PP4_Object_NumLandmarks", object.num_landmarks);
95   - metadata.insert("PP4_Object_Size", object.size);
96   -
97   - QList<ppr_landmark_category_type> categories;
98   - categories << PPR_LANDMARK_RIGHT_EYE
99   - << PPR_LANDMARK_LEFT_EYE
100   - << PPR_LANDMARK_NOSE_BASE
101   - << PPR_LANDMARK_NOSE_BRIDGE
102   - << PPR_LANDMARK_NOSE_TIP
103   - << PPR_LANDMARK_NOSE_TOP
104   - << PPR_LANDMARK_EYE_NOSE
105   - << PPR_LANDMARK_MOUTH;
106   -
107   - for (int i=0; i<categories.size(); i++) {
108   - ppr_landmark_category_type category = categories[i];
109   - QString metadataString = QString("PP4_Landmark%1_%2").arg(QString::number(i), toString(category));
110   -
111   - bool found = false;
112   - for (int j=0; j<object.num_landmarks; j++) {
113   - ppr_landmark_type &landmark = object.landmarks[j];
114   - if (landmark.category != category) continue;
115   -
116   - metadata.insert(metadataString+"_X", landmark.position.x);
117   - metadata.insert(metadataString+"_Y", landmark.position.y);
118   - metadata.insert(metadataString+"_Category", landmark.category);
119   - metadata.insert(metadataString+"_ModelID", landmark.model_id);
120   - metadata.insert(metadataString+"_Index", j);
121   - found = true;
122   - break;
123   - }
124   -
125   - if (!found) {
126   - metadata.insert(metadataString+"_X", -1);
127   - metadata.insert(metadataString+"_Y", -1);
128   - metadata.insert(metadataString+"_Category", -1);
129   - metadata.insert(metadataString+"_ModelID", -1);
130   - metadata.insert(metadataString+"_Index", -1);
131   - }
132   - }
133   -
134   - return metadata;
135   - }
136   -
137   - static ppr_object_type fromMetadata(const File &metadata)
138   - {
139   - ppr_object_type object;
140   -
141   - object.position.x = metadata.value("PP4_Object_X").toFloat() + metadata.value("PP4_Object_Width").toFloat()/2;
142   - object.position.y = metadata.value("PP4_Object_Y").toFloat() + metadata.value("PP4_Object_Height").toFloat()/2;
143   - object.dimensions.width = metadata.value("PP4_Object_Width").toFloat();
144   - object.dimensions.height = metadata.value("PP4_Object_Height").toFloat();
145   - object.confidence = metadata.value("PP4_Object_Confidence").toFloat();
146   - object.rotation.roll = metadata.value("PP4_Object_Roll").toFloat();
147   - object.rotation.pitch = metadata.value("PP4_Object_Pitch").toFloat();
148   - object.rotation.yaw = metadata.value("PP4_Object_Yaw").toFloat();
149   - object.rotation.precision = (ppr_precision_type) metadata.value("PP4_Object_Precision").toFloat();
150   - object.model_id = metadata.value("PP4_Object_ModelID").toInt();
151   - object.num_landmarks = metadata.value("PP4_Object_NumLandmarks").toInt();
152   - object.size = metadata.value("PP4_Object_Size").toFloat();
153   -
154   - QStringList landmarkNames = QStringList(metadata.keys()).filter(QRegExp("(.*)_Category")).replaceInStrings("_Category", "");
155   - object.landmarks = new ppr_landmark_type[object.num_landmarks];
156   - for (int j=0; j<landmarkNames.size(); j++) {
157   - int landmarkIndex = metadata.value(landmarkNames[j]+"_Index").toInt();
158   - if (landmarkIndex == -1) continue;
159   - object.landmarks[landmarkIndex].position.x = metadata.value(landmarkNames[j]+"_X").toFloat();
160   - object.landmarks[landmarkIndex].position.y = metadata.value(landmarkNames[j]+"_Y").toFloat();
161   - object.landmarks[landmarkIndex].category = (ppr_landmark_category_type)metadata.value(landmarkNames[j]+"_Category").toInt();
162   - object.landmarks[landmarkIndex].model_id = metadata.value(landmarkNames[j]+"_ModelID").toInt();
163   - landmarkIndex++;
164   - }
165   -
166   - return object;
167   - }
168   -
169   - static void freeObject(ppr_object_type &object)
170   - {
171   - delete[] object.landmarks;
172   - object.landmarks = NULL;
173   - object.num_landmarks = 0;
174   - }
175   -};
176   -
177   -ppr_context_type PP4Context::context;
178   -
179   -/*!
180   - * \ingroup initializers
181   - * \brief Initialize PittPatt 4
182   - * \author Josh Klontz \cite jklontz
183   - * \warning Needs a maintainer.
184   - */
185   -class PP4Initializer : public Initializer
186   - , public PP4Context
187   -{
188   - Q_OBJECT
189   -
190   - void initialize() const
191   - {
192   - context = ppr_get_context();
193   - TRY(ppr_enable_recognition(context))
194   - TRY(ppr_set_license(context, my_license_id, my_license_key))
195   - TRY(ppr_set_models_path(context, qPrintable(Globals->SDKPath + "/models/pp4")))
196   - TRY(ppr_set_num_recognition_threads(context, QThreadPool::globalInstance()->maxThreadCount()))
197   - TRY(ppr_set_num_detection_threads(context, 1))
198   - TRY(ppr_set_detection_precision(context, PPR_FINE_PRECISION))
199   - TRY(ppr_set_landmark_detector_type(context, PPR_DUAL_MULTI_POSE_LANDMARK_DETECTOR, PPR_AUTOMATIC_LANDMARKS))
200   - TRY(ppr_set_min_size(context, 4))
201   - TRY(ppr_set_frontal_yaw_constraint(context, PPR_FRONTAL_YAW_CONSTRAINT_PERMISSIVE))
202   - TRY(ppr_set_template_extraction_type(context, PPR_EXTRACT_DOUBLE))
203   - TRY(ppr_initialize_context(context))
204   - Globals->Abbreviations.insert("PP4", "Open+PP4Detect!PP4Enroll:PP4Compare");
205   - }
206   -
207   - void finalize() const
208   - {
209   - TRY(ppr_release_context(context))
210   - ppr_finalize_sdk();
211   - }
212   -};
213   -
214   -MM_REGISTER(Initializer, PP4Initializer, "")
215   -
216   -/*!
217   - * \ingroup transforms
218   - * \brief Detect a face in PittPatt 4
219   - * \author Josh Klontz \cite jklontz
220   - * \warning Needs a maintainer.
221   - */
222   -class PP4Detect : public UntrainableMetaFeature
223   - , public PP4Context
224   -{
225   - Q_OBJECT
226   -
227   - void project(const Template &src, Template &dst) const
228   - {
229   - dst.file = src.file;
230   -
231   - foreach (const cv::Mat &matrix, src) {
232   - ppr_raw_image_type raw_image;
233   - createRawImage(matrix, raw_image);
234   - ppr_image_type image;
235   - TRY(ppr_create_image(raw_image, &image))
236   - ppr_object_list_type object_list;
237   - TRY(ppr_detect_objects(context, image, &object_list))
238   -
239   - QList<ppr_object_type> objects;
240   - if (src.file.getBool("ForceEnrollment")) objects = getBestObject(object_list);
241   - else objects = getAllObjects(object_list);
242   -
243   - foreach (const ppr_object_type &object, objects) {
244   - dst.file.append(toMetadata(object));
245   - dst += matrix;
246   - }
247   -
248   - ppr_free_object_list(object_list);
249   - ppr_free_image(image);
250   - ppr_raw_image_free(raw_image);
251   - }
252   -
253   - if (src.file.getBool("ForceEnrollment") && dst.isEmpty()) dst += cv::Mat();
254   - }
255   -
256   -private:
257   - QList<ppr_object_type> getBestObject(ppr_object_list_type object_list) const
258   - {
259   - int best_index = -1;
260   - float best_confidence = 0;
261   - for (int i=0; i<object_list.num_objects; i++) {
262   - ppr_object_type object = object_list.objects[i];
263   - ppr_object_suitability_type suitability;
264   - TRY(ppr_is_object_suitable_for_recognition(context, object, &suitability))
265   - if (suitability != PPR_OBJECT_SUITABLE_FOR_RECOGNITION) continue;
266   - if ((object.confidence > best_confidence) ||
267   - (best_index == -1)) {
268   - best_confidence = object.confidence;
269   - best_index = i;
270   - }
271   - }
272   -
273   - QList<ppr_object_type> objects;
274   - if (best_index != -1) objects.append(object_list.objects[best_index]);
275   - return objects;
276   - }
277   -
278   - QList<ppr_object_type> getAllObjects(ppr_object_list_type object_list) const
279   - {
280   - QList<ppr_object_type> objects;
281   - for (int i=0; i<object_list.num_objects; i++)
282   - objects.append(object_list.objects[i]);
283   - return objects;
284   - }
285   -};
286   -
287   -MM_REGISTER(Feature, PP4Detect, "")
288   -
289   -/*!
290   - * \ingroup transforms
291   - * \brief Enroll face in PittPatt 4
292   - * \author Josh Klontz \cite jklontz
293   - * \warning Needs a maintainer.
294   - */
295   -class PP4Enroll : public UntrainableMetaFeature
296   - , public PP4Context
297   -{
298   - Q_OBJECT
299   -
300   - void project(const Template &src, Template &dst) const
301   - {
302   - if (!src.m().data) {
303   - dst += cv::Mat();
304   - return;
305   - }
306   -
307   - ppr_raw_image_type raw_image;
308   - createRawImage(src, raw_image);
309   - ppr_image_type image;
310   - TRY(ppr_create_image(raw_image, &image))
311   -
312   - ppr_object_type object = fromMetadata(src.file);
313   -
314   - ppr_template_type curr_template;
315   - TRY(ppr_extract_template_from_object(context, image, object, &curr_template))
316   -
317   - freeObject(object);
318   -
319   - cv::Mat m;
320   - createMat(curr_template, m);
321   - dst += m;
322   -
323   - ppr_free_template(curr_template);
324   - ppr_free_image(image);
325   - ppr_raw_image_free(raw_image);
326   - }
327   -};
328   -
329   -MM_REGISTER(Feature, PP4Enroll, "")
330   -
331   -
332   -class PP4Compare : public Comparer,
333   - public PP4Context
334   -{
335   - Q_OBJECT
336   -
337   - void compare(const TemplateList &target, const TemplateList &query, Output *output) const
338   - {
339   - ppr_gallery_type target_gallery, query_gallery;
340   - ppr_create_gallery(context, &target_gallery);
341   - ppr_create_gallery(context, &query_gallery);
342   - QList<int> target_template_ids, query_template_ids;
343   - enroll(target, &target_gallery, target_template_ids);
344   - enroll(query, &query_gallery, query_template_ids);
345   -
346   - ppr_similarity_matrix_type similarity_matrix;
347   - TRY(ppr_compare_galleries(context, query_gallery, target_gallery, &similarity_matrix))
348   -
349   - for (int i=0; i<query_template_ids.size(); i++) {
350   - int query_template_id = query_template_ids[i];
351   - for (int j=0; j<target_template_ids.size(); j++) {
352   - int target_template_id = target_template_ids[j];
353   - float score = -std::numeric_limits<float>::max();
354   - if ((query_template_id != -1) && (target_template_id != -1)) {
355   - TRY(ppr_get_similarity_matrix_element(context, similarity_matrix, query_template_id, target_template_id, &score))
356   - }
357   - output->setData(score, i, j);
358   - }
359   - }
360   -
361   - ppr_free_similarity_matrix(similarity_matrix);
362   - ppr_free_gallery(target_gallery);
363   - ppr_free_gallery(query_gallery);
364   - }
365   -
366   - void enroll(const TemplateList &templates, ppr_gallery_type *gallery, QList<int> &template_ids) const
367   - {
368   - foreach (const Template &t, templates) {
369   - if (t.m().data) {
370   - ppr_template_type u;
371   - createTemplate(t.m(), &u);
372   - int template_id;
373   - TRY(ppr_copy_template_to_gallery(context, gallery, u, &template_id))
374   - template_ids.append(template_id);
375   - ppr_free_template(u);
376   - } else {
377   - template_ids.append(-1);
378   - }
379   - }
380   - }
381   -};
382   -
383   -MM_REGISTER(Comparer, PP4Compare, "")
384   -
385   -#include "plugins/pp4.moc"
openbr/plugins/regions.cpp
... ... @@ -141,13 +141,15 @@ class CatColsTransform : public UntrainableMetaTransform
141 141  
142 142 void project(const Template &src, Template &dst) const
143 143 {
  144 + int half = src.size()/2;
  145 + for (int i=0; i<half; i++) {
  146 + Mat first = src[i];
  147 + Mat second = src[half+i];
  148 + Mat both;
  149 + hconcat(first, second, both);
  150 + dst.append(both);
  151 + }
144 152 dst.file = src.file;
145   - Mat m = OpenCVUtils::toMatByRow(src);
146   - // right now this just splits src in half and joins them horizontally
147   - // TODO: add partitions parameter for more than a single split
148   - Mat first = m.rowRange(Range(0, m.rows/2));
149   - Mat second = m.rowRange(Range(m.rows/2, m.rows));
150   - hconcat(first, second, dst);
151 153 }
152 154 };
153 155  
... ...
openbr/plugins/stream.cpp
... ... @@ -707,8 +707,7 @@ public:
707 707 if (input == NULL) {
708 708 qFatal("null input to multi-thread stage");
709 709 }
710   - // Project the input we got
711   - transform->projectUpdate(input->data);
  710 + input->data >> *transform;
712 711  
713 712 should_continue = nextStage->tryAcquireNextStage(input);
714 713  
... ... @@ -1300,6 +1299,12 @@ public:
1300 1299 {
1301 1300 if (!transform)
1302 1301 return;
  1302 +
  1303 + // Set up timeInvariantAlias
  1304 + // this is only safe because copies are actually made in project
  1305 + // calls, not during init.
  1306 + TimeVaryingTransform::init();
  1307 +
1303 1308 trainable = transform->trainable;
1304 1309  
1305 1310 basis.setParent(this->parent());
... ...
openbr/plugins/topsurf.cmake deleted
1   -set(BR_WITH_TOPSURF OFF CACHE BOOL "Build with TOP-SURF")
2   -
3   -if(${BR_WITH_TOPSURF})
4   - find_package(TopSurf REQUIRED)
5   - set(THIRDPARTY_SRC ${THIRDPARTY_SRC} plugins/topsurf.cpp ${TOPSURF_SRC} ${TOPSURF_FLANN_SRC})
6   - install(DIRECTORY ${TOPSURF_DIR}/dictionary_10000
7   - ${TOPSURF_DIR}/dictionary_20000
8   - ${TOPSURF_DIR}/dictionary_40000
9   - DESTINATION models/topsurf)
10   -endif()
openbr/plugins/topsurf.cpp deleted
1   -#include <topsurf/descriptor.h>
2   -#include <topsurf/topsurf.h>
3   -#include <mm_plugin.h>
4   -
5   -#include "common/opencvutils.h"
6   -#include "common/qtutils.h"
7   -#include "common/resource.h"
8   -
9   -using namespace cv;
10   -using namespace mm;
11   -using namespace std;
12   -
13   -class TopSurfInitializer : public Initializer
14   -{
15   - void initialize() const
16   - {
17   - Globals.Abbreviations.insert("TopSurf", "Open!TopSurfExtract(40000):TopSurfCompare");
18   - Globals.Abbreviations.insert("TopSurfM", "Open!TopSurfExtract(1000000):TopSurfCompare");
19   - Globals.Abbreviations.insert("TopSurfKNN", "Open!TopSurfExtract+TopSurfKNN");
20   - Globals.Abbreviations.insert("DocumentClassification", "TopSurfKNN");
21   - }
22   -
23   - void finalize() const {}
24   -};
25   -
26   -MM_REGISTER(Initializer, TopSurfInitializer, false)
27   -
28   -
29   -class TopSurfResourceMaker : public ResourceMaker<TopSurf>
30   -{
31   - QString file;
32   -
33   -public:
34   - TopSurfResourceMaker(const QString &dictionary)
35   - {
36   - file = Globals.SDKPath + "/models/topsurf/dictionary_" + dictionary;
37   - }
38   -
39   -private:
40   - TopSurf *make() const
41   - {
42   - TopSurf *topSurf = new TopSurf(256, 100);
43   - if (!topSurf->LoadDictionary(qPrintable(file)))
44   - qFatal("TopSurfResourceMaker::make failed to load dictionary.");
45   - return topSurf;
46   - }
47   -};
48   -
49   -
50   -/****
51   -TopSurfExtract
52   - Wrapper to TopSurf::ExtractDescriptor()
53   - B. Thomee, E.M. Bakker, and M.S. Lew, "TOP-SURF: a visual words toolkit",
54   - in Proceedings of the 18th ACM International Conference on Multimedia, pp. 1473-1476, Firenze, Italy, 2010.
55   -****/
56   -class TopSurfExtract : public UntrainableFeature
57   -{
58   - Q_OBJECT
59   - Q_PROPERTY(QString dictionary READ get_dictionary WRITE set_dictionary)
60   - MM_MEMBER(QString, dictionary)
61   -
62   - Resource<TopSurf> topSurfResource;
63   -
64   -public:
65   - TopSurfExtract() : topSurfResource(new TopSurfResourceMaker("10000")) {}
66   -
67   -private:
68   - void init()
69   - {
70   - topSurfResource.setResourceMaker(new TopSurfResourceMaker(dictionary));
71   - }
72   -
73   - void project(const Template &src, Template &dst) const
74   - {
75   - // Compute descriptor (not thread safe)
76   - TopSurf *topSurf = topSurfResource.acquire();
77   - TOPSURF_DESCRIPTOR descriptor;
78   - IplImage iplSrc = src.m();
79   - if (!topSurf->ExtractDescriptor(iplSrc, descriptor))
80   - qFatal("TopSurfExtract::project ExtractDescriptor failure.");
81   - topSurfResource.release(topSurf);
82   -
83   - // Copy descriptor and clean up
84   - unsigned char *data;
85   - int length;
86   - Descriptor2Array(descriptor, data, length);
87   - Mat m(1, length, CV_8UC1);
88   - memcpy(m.data, data, length);
89   - delete data;
90   - TopSurf::ReleaseDescriptor(descriptor);
91   - dst = m;
92   - }
93   -
94   -public:
95   - static QString args()
96   - {
97   - return "10000|20000|40000 dictionary = 10000";
98   - }
99   -
100   - static TopSurfExtract *make(const QStringList &args)
101   - {
102   - (void) args;
103   - return new TopSurfExtract();
104   - }
105   -};
106   -
107   -MM_REGISTER(Feature, TopSurfExtract, true)
108   -
109   -
110   -class TopSurfHist : public UntrainableFeature
111   -{
112   - Q_OBJECT
113   - Q_PROPERTY(int size READ get_size WRITE set_size)
114   - MM_MEMBER(int, size)
115   -
116   - void project(const Template &src, Template &dst) const
117   - {
118   - TOPSURF_DESCRIPTOR td;
119   - Array2Descriptor(src.m().data, td);
120   -
121   - Mat m(1, size, CV_32FC1);
122   - m.setTo(0);
123   - for (int i=0; i<td.count; i++)
124   - m.at<float>(0, td.visualword[i].identifier % size)++;
125   -
126   - TopSurf::ReleaseDescriptor(td);
127   - dst = m;
128   - }
129   -
130   -public:
131   - static QString args()
132   - {
133   - return "int size = 10000";
134   - }
135   -
136   - static TopSurfHist *make(const QStringList &args)
137   - {
138   - (void) args;
139   - return new TopSurfHist();
140   - }
141   -};
142   -
143   -MM_REGISTER(Feature, TopSurfHist, true)
144   -
145   -
146   -// Wrapper around TopSurf CompareDescriptors
147   -float TopSurfSimilarity(const Mat &a, const Mat &b, bool cosine)
148   -{
149   - TOPSURF_DESCRIPTOR tda, tdb;
150   - Array2Descriptor(a.data, tda);
151   - Array2Descriptor(b.data, tdb);
152   -
153   - float result;
154   - if (cosine) result = TopSurf::CompareDescriptorsCosine(tda, tdb);
155   - else result = TopSurf::CompareDescriptorsAbsolute(tda, tdb);
156   -
157   - TopSurf::ReleaseDescriptor(tda);
158   - TopSurf::ReleaseDescriptor(tdb);
159   - return result;
160   -}
161   -
162   -
163   -/****
164   -TopSurfCompare
165   - Wrapper to TopSurf_CompareDescriptors()
166   - B. Thomee, E.M. Bakker, and M.S. Lew, "TOP-SURF: a visual words toolkit",
167   - in Proceedings of the 18th ACM International Conference on Multimedia, pp. 1473-1476, Firenze, Italy, 2010.
168   -****/
169   -class TopSurfCompare : public ComparerBase
170   -{
171   - Q_OBJECT
172   - Q_PROPERTY(bool cosine READ get_cosine WRITE set_cosine)
173   - MM_MEMBER(bool, cosine)
174   -
175   - float compare(const Mat &a, const Mat &b) const
176   - {
177   - return TopSurfSimilarity(a, b, cosine);
178   - }
179   -
180   -public:
181   - static QString args()
182   - {
183   - return "bool cosine = 1";
184   - }
185   -
186   - static TopSurfCompare *make(const QStringList &args)
187   - {
188   - (void) args;
189   - return new TopSurfCompare();
190   - }
191   -};
192   -
193   -MM_REGISTER(Comparer, TopSurfCompare, true)
194   -
195   -
196   -/****
197   -TopSurfKNN
198   - KNN classifier for TopSurf features.
199   -****/
200   -class TopSurfKNN : public Feature
201   -{
202   - Q_OBJECT
203   - Q_PROPERTY(int k READ get_k WRITE set_k)
204   - Q_PROPERTY(bool cosine READ get_cosine WRITE set_cosine)
205   - MM_MEMBER(int, k)
206   - MM_MEMBER(bool, cosine)
207   -
208   - TemplateList data;
209   -
210   -private:
211   - void train(const TemplateList &data)
212   - {
213   - this->data = data;
214   - }
215   -
216   - void project(const Template &src, Template &dst) const
217   - {
218   - // Compute distance to each descriptor
219   - QList< QPair<float, int> > distances; // <distance, label>
220   - distances.reserve(data.size());
221   - foreach (const Template &t, data)
222   - distances.append(QPair<float, int>(TopSurfSimilarity(src, t, cosine), t.file.label()));
223   -
224   - // Find nearest neighbors
225   - qSort(distances);
226   - QHash<int, QPair<int, float> > counts; // <label, <count, cumulative distance>>
227   - for (int i=0; i<k; i++) {
228   - QPair<float,int> &distance = distances[i];
229   - QPair<int,float> &count = counts[distance.second];
230   - count.first++;
231   - count.second += distance.first;
232   - }
233   -
234   - // Find most occuring label
235   - int best_label = -1;
236   - int best_count = 0;
237   - float best_distance = numeric_limits<float>::max();
238   - foreach (int label, counts.keys()) {
239   - const QPair<int, float> &count = counts[label];
240   - if ((count.first > best_count) || ((count.first == best_count) && (count.second < best_distance))) {
241   - best_label = label;
242   - best_count = count.first;
243   - best_distance = count.second;
244   - }
245   - }
246   - assert(best_label != -1);
247   -
248   - // Measure confidence
249   - int rest_count = 0;
250   - float rest_distance = 0;
251   - foreach (int label, counts.keys()) {
252   - if (label != best_label) {
253   - const QPair<int, float> &count = counts[label];
254   - rest_count = count.first;
255   - rest_distance = count.second;
256   - }
257   - }
258   -
259   - dst = src;
260   - dst.file["Label"] = best_label;
261   - dst.file["Confidence"] = (float)best_count/(float)k;
262   - }
263   -
264   - void store(QDataStream &stream) const
265   - {
266   - stream << data;
267   - }
268   -
269   - void load(QDataStream &stream)
270   - {
271   - stream >> data;
272   - }
273   -
274   -public:
275   - static QString args()
276   - {
277   - return "int k, int cosine = 1";
278   - }
279   -
280   - static TopSurfKNN *make(const QStringList &args)
281   - {
282   - (void) args;
283   - return new TopSurfKNN();
284   - }
285   -};
286   -
287   -MM_REGISTER(Feature, TopSurfKNN, true)
288   -
289   -#include "topsurf.moc"
openbr/plugins/yubico.cmake deleted
1   -set(BR_WITH_YUBICO OFF CACHE BOOL "Build YubiKey authentication")
2   -
3   -if(${BR_WITH_YUBICO})
4   - find_package(YubiKey REQUIRED) # For decrypting YubiKeys
5   - find_package(YKPers REQUIRED) # For reading YubiKeys
6   -
7   - install(FILES ${YUBIKEY_LICENSE} RENAME YubiKey DESTINATION share/openbr/licenses)
8   - install(FILES ${YKPERS_LICENSE} RENAME YKPers DESTINATION share/openbr/licenses)
9   - install(FILES ${YKPERS_RULES} DESTINATION share/openbr)
10   -
11   - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} ${YUBIKEY_SRC} ${YKPERS_SRC} plugins/yubico.cpp)
12   - set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${YKPERS_LIBS})
13   -endif()
openbr/plugins/yubico.cpp deleted
1   -#include <mm_plugin.h>
2   -#include <yubikey.h>
3   -#include <ykdef.h>
4   -#include <ykpers.h>
5   -#include <stdlib.h>
6   -#include <time.h>
7   -
8   -/****
9   -YubiKey Challenge-Response Authentication
10   -
11   -To configure YubiKeys for mm usage:
12   -1) Download the cross platform personalization tool from http://yubico.com/personalization-tool.
13   -2) Insert YubiKey and launch the personalization tool (may require sudo access).
14   -3) Click "Challenge-Response Mode".
15   -4) Click "Yubico OTP".
16   -5) Select "Configuration Slot 2"
17   -6) In the Private Identity text box enter "21 92 78 11 55 8a".
18   -7) In the Secret Key text box enter "e7 32 df 49 f3 87 e6 89 04 d2 03 6a 59 ad b7 2f".
19   -8) Click "Write Configuration".
20   -9) Done!
21   -
22   -Unix implementation derived from "ykchalresp.c" in ykpers repository.
23   -Windows implementation derived from "MFCTestDlg.cpp" in Yubikey Client API installer.
24   -
25   -!!! Attention Linux Users !!!
26   -cp trunk/3rdparty/ykpers-1.6.3/70-yubikey.rules /etc/udev/rules.d
27   -
28   -!!! Attention Windows Users !!!
29   -Install Yubikey Client API.
30   -****/
31   -
32   -using namespace mm;
33   -
34   -static int challenge_response(YK_KEY *yk, int slot,
35   - unsigned char *challenge, unsigned int len,
36   - bool hmac, bool may_block, bool verbose, unsigned char output_buf[(SHA1_MAX_BLOCK_SIZE * 2) + 1])
37   -{
38   - unsigned char response[64];
39   - int yk_cmd;
40   - unsigned int flags = 0;
41   - unsigned int response_len = 0;
42   - unsigned int expect_bytes = 0;
43   -
44   - memset(response, 0, sizeof(response));
45   -
46   - if (may_block)
47   - flags |= YK_FLAG_MAYBLOCK;
48   -
49   - if (verbose) {
50   - fprintf(stderr, "Sending %i bytes %s challenge to slot %i\n", len, (hmac == true) ? "HMAC" : "Yubico", slot);
51   - //_yk_hexdump(challenge, len);
52   - }
53   -
54   - switch(slot) {
55   - case 1:
56   - yk_cmd = (hmac == true) ? SLOT_CHAL_HMAC1 : SLOT_CHAL_OTP1;
57   - break;
58   - case 2:
59   - yk_cmd = (hmac == true) ? SLOT_CHAL_HMAC2 : SLOT_CHAL_OTP2;
60   - break;
61   - }
62   -
63   - if (!yk_write_to_key(yk, yk_cmd, challenge, len))
64   - return 0;
65   -
66   - if (verbose) {
67   - fprintf(stderr, "Reading response...\n");
68   - }
69   -
70   - /* HMAC responses are 160 bits, Yubico 128 */
71   - expect_bytes = (hmac == true) ? 20 : 16;
72   -
73   - if (! yk_read_response_from_key(yk, slot, flags,
74   - &response, sizeof(response),
75   - expect_bytes,
76   - &response_len))
77   - return 0;
78   -
79   - if (hmac && response_len > 20)
80   - response_len = 20;
81   - if (! hmac && response_len > 16)
82   - response_len = 16;
83   -
84   - memset(output_buf, 0, SHA1_MAX_BLOCK_SIZE * 2 + 1);
85   - if (hmac) {
86   - yubikey_hex_encode((char *)output_buf, (char *)response, response_len);
87   - } else {
88   - yubikey_modhex_encode((char *)output_buf, (char *)response, response_len);
89   - }
90   - // printf("%s\n", output_buf);
91   -
92   - return 1;
93   -}
94   -
95   -/*!
96   - * \ingroup initializers
97   - * \brief Initialize yubikey
98   - * \author Josh Klontz \cite jklontz
99   - */
100   -class YubiKey : public Initializer
101   -{
102   - Q_OBJECT
103   -
104   - void initialize() const
105   - {
106   - // Read from device
107   - YK_KEY *yk = 0;
108   -
109   - if (!yk_init())
110   - qFatal("YubiKey::initialize yk_init failure.");
111   -
112   - if (!(yk = yk_open_first_key()))
113   - qFatal("Could not connect to license.");
114   -
115   - // Challenge value is arbitrary
116   - srand(time(NULL));
117   - uint8_t challenge[6] = {rand()%255, rand()%255, rand()%255, rand()%255, rand()%255, rand()%255};
118   - unsigned char output_buf[(SHA1_MAX_BLOCK_SIZE * 2) + 1];
119   - if (!challenge_response(yk, 2, challenge, 6, false, true, false, output_buf))
120   - qFatal("YubiKey::initialize challenge_response failure.");
121   -
122   - if (yk && !yk_close_key(yk))
123   - qFatal("YubiKey::initialize yk_close_key failure.");
124   -
125   - if (!yk_release())
126   - qFatal("YubiKey::initialize yk_release failure.");
127   -
128   - // Check response
129   - // Our Secret Key! Shhh...
130   - const uint8_t key[YUBIKEY_KEY_SIZE] = {0xe7, 0x32, 0xdf, 0x49, 0xf3, 0x87, 0xe6, 0x89, 0x04, 0xd2, 0x03, 0x6a, 0x59, 0xad, 0xb7, 0x2f};
131   - yubikey_token_st out;
132   - yubikey_parse(output_buf, key, &out);
133   -
134   - // Our Private Identity! Shhh...
135   - uint8_t uid[YUBIKEY_UID_SIZE] = {0x21, 0x92, 0x78, 0x11, 0x55, 0x8a};
136   - if ((uid[0] != (out.uid[0] ^ challenge[0])) ||
137   - (uid[1] != (out.uid[1] ^ challenge[1])) ||
138   - (uid[2] != (out.uid[2] ^ challenge[2])) ||
139   - (uid[3] != (out.uid[3] ^ challenge[3])) ||
140   - (uid[4] != (out.uid[4] ^ challenge[4])) ||
141   - (uid[5] != (out.uid[5] ^ challenge[5])))
142   - qFatal("Invalid license.");
143   - }
144   -
145   - void finalize() const
146   - {
147   - // Nothing to do
148   - }
149   -};
150   -
151   -MM_REGISTER(Initializer,YubiKey,"")
152   -
153   -#include "yubico.moc"
share/openbr/cmake/FindCT8.cmake deleted
1   -# ================================================================
2   -# The CT8 CMake configuration file
3   -#
4   -# Usage from an external project:
5   -# In your CMakeLists.txt, add these lines:
6   -#
7   -# find_package(CT8 REQUIRED)
8   -# target_link_libraries(MY_TARGET ${CT8_LIBS})
9   -# ================================================================
10   -
11   -set(CT8_DIR "CT8_DIR-NOTFOUND" CACHE PATH "Cognitec FaceVACS 8.x directory")
12   -
13   -
14   -if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
15   - set(ARCH_STRING x86_64)
16   -else("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
17   - set(ARCH_STRING x86_32)
18   -endif("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
19   -
20   -if(DEFINED MSVC80)
21   - set(COMP_DIR_EXT "msc_8.0-ipp_crtdll")
22   -elseif(DEFINED MSVC90)
23   - set(COMP_DIR_EXT "msc_9.0-ipp_crtdll")
24   -elseif(DEFINED MSVC10)
25   - set(COMP_DIR_EXT "msc_10.0-ipp_crtdll")
26   -elseif(CMAKE_HOST_APPLE)
27   - set(COMP_DIR_EXT "gcc-4.2-ipp")
28   -else()
29   - set(COMP_DIR_EXT "gcc-4.3-ipp")
30   -endif()
31   -
32   -set(CT8_DIR_LIB ${CT8_DIR}/lib/${ARCH_STRING}/${COMP_DIR_EXT} )
33   -set(CT8_LIBRARY_RELEASE libfrsdk-8.6.0)
34   -set(CT8_LIBRARY_DEBUG libfrsdk-8.6.0d)
35   -
36   -include_directories(${CT8_DIR}/include)
37   -link_directories(${CT8_DIR_LIB} ${CT8_DIR_LIB}_g)
share/openbr/cmake/FindFST3.cmake deleted
1   -find_path(FST3_DIR _src_criteria/classifier.hpp ${CMAKE_SOURCE_DIR}/3rdparty/*)
2   -mark_as_advanced(FST3_DIR)
3   -include_directories(${FST3_DIR}/_src_criteria ${FST3_DIR}/_src_dataio ${FST3_DIR}/_src_global ${FST3_DIR}/_src_search)
4   -set(FST3_SRC ${FST3_DIR}/_src_global/global.cpp)
share/openbr/cmake/FindPP4.cmake deleted
1   -# ================================================================
2   -# The PP4 CMake configuration file
3   -#
4   -# Usage from an external project:
5   -# In your CMakeLists.txt, add these lines:
6   -#
7   -# find_package(PP4 REQUIRED)
8   -# target_link_libraries(MY_TARGET ${PP4_LIBS})
9   -# ================================================================
10   -
11   -find_path(PP4_DIR include/pittpatt_nc_sdk.h ${CMAKE_SOURCE_DIR}/3rdparty/*)
12   -include_directories(${PP4_DIR}/include)
13   -link_directories(${PP4_DIR}/lib)
14   -set(PP4_LIBS pittpatt_nc_sdk
15   - pittpatt_raw_image
16   - pittpatt_raw_image_io
17   - pittpatt_recognition_core
18   - pittpatt_video_io)
share/openbr/cmake/FindTopSurf.cmake deleted
1   -find_path(TOPSURF_DIR topsurf/topsurf.h ${CMAKE_SOURCE_DIR}/3rdparty/*)
2   -mark_as_advanced(TOPSURF_DIR)
3   -include_directories(${TOPSURF_DIR})
4   -aux_source_directory(${TOPSURF_DIR}/topsurf TOPSURF_SRC)
5   -aux_source_directory(${TOPSURF_DIR}/topsurf/flann TOPSURF_FLANN_SRC)
share/openbr/cmake/FindYubiKey.cmake deleted
1   -find_path(YUBIKEY_DIR yubikey.h ${CMAKE_SOURCE_DIR}/3rdparty/*)
2   -mark_as_advanced(YUBIKEY_DIR)
3   -include_directories(${YUBIKEY_DIR})
4   -if(MSVC)
5   - include_directories(${YUBIKEY_DIR}/stdbool)
6   -endif()
7   -
8   -if(NOT TARGET yubikey)
9   - set(YUBIKEY_SRC ${YUBIKEY_DIR}/ykaes.c ${YUBIKEY_DIR}/ykcrc.c ${YUBIKEY_DIR}/ykhex.c ${YUBIKEY_DIR}/ykmodhex.c ${YUBIKEY_DIR}/yktoken.c)
10   - if(WIN32)
11   - set_source_files_properties(${YUBIKEY_SRC} PROPERTIES LANGUAGE CXX)
12   - endif()
13   -endif()
14   -
15   -set(YUBIKEY_LICENSE ${YUBIKEY_DIR}/COPYING)
share/openbr/cmake/FindpHash.cmake deleted
1   -find_path(PHASH_DIR src/pHash.h ${CMAKE_SOURCE_DIR}/3rdparty/*)
2   -mark_as_advanced(PHASH_DIR)
3   -include_directories(${PHASH_DIR} ${PHASH_DIR}/src)
4   -set(PHASH_SRC ${PHASH_DIR}/src/pHash.cpp ${PHASH_DIR}/src/ph_fft.c)
1   -Subproject commit dccddf4dd3a5239911807beeec39308f8890b1e4
  1 +Subproject commit a73d51013ea05f263e88a28539393159fff2183e
... ...