Commit 5d001f4dba69bccdeb5e3db905b69cdaf18235dd

Authored by JordanCheney
1 parent d24c2952

Unimplemented header files for adaboost

openbr/CMakeLists.txt
@@ -11,6 +11,7 @@ add_definitions(-DJANUS_LIBRARY) @@ -11,6 +11,7 @@ add_definitions(-DJANUS_LIBRARY)
11 # Collect source files 11 # Collect source files
12 aux_source_directory(. SRC) 12 aux_source_directory(. SRC)
13 aux_source_directory(core BR_CORE) 13 aux_source_directory(core BR_CORE)
  14 +aux_source_directory(learning BR_LEARNING)
14 include(plugins/plugins.cmake) 15 include(plugins/plugins.cmake)
15 16
16 # Optional GUI module 17 # Optional GUI module
@@ -21,7 +22,7 @@ if(NOT ${BR_EMBEDDED}) @@ -21,7 +22,7 @@ if(NOT ${BR_EMBEDDED})
21 install(FILES ${HEADERS} DESTINATION include/openbr/gui) 22 install(FILES ${HEADERS} DESTINATION include/openbr/gui)
22 endif() 23 endif()
23 24
24 -add_library(openbr SHARED ${SRC} ${BR_CORE} ${BR_JANUS} ${BR_GUI} ${BR_ICONS} ${BR_THIRDPARTY_SRC} ${BR_RESOURCES} ${NATURALSTRINGCOMPARE_SRC}) 25 +add_library(openbr SHARED ${SRC} ${BR_CORE} ${BR_LEARNING} ${BR_JANUS} ${BR_GUI} ${BR_ICONS} ${BR_THIRDPARTY_SRC} ${BR_RESOURCES} ${NATURALSTRINGCOMPARE_SRC})
25 qt5_use_modules(openbr ${QT_DEPENDENCIES}) 26 qt5_use_modules(openbr ${QT_DEPENDENCIES})
26 set_target_properties(openbr PROPERTIES 27 set_target_properties(openbr PROPERTIES
27 DEFINE_SYMBOL BR_LIBRARY 28 DEFINE_SYMBOL BR_LIBRARY
openbr/learning/adaboost.cpp 0 → 100644
  1 +#include "adaboost.h"
  2 +
  3 +AdaBoost::AdaBoost()
  4 +{
  5 +}
openbr/learning/adaboost.h 0 → 100644
  1 +#ifndef ADABOOST_H
  2 +#define ADABOOST_H
  3 +
  4 +#include "trainingdata.h"
  5 +#include <openbr/openbr_plugin.h>
  6 +
  7 +namespace br
  8 +{
  9 +
  10 +struct Node
  11 +{
  12 + Node(int feature_idx, float threshold, int polarity, float weight) : feature_idx(feature_idx), threshold(threshold), polarity(polarity), weight(weight) {}
  13 + int predict(float feature_response) const { return (polarity * (feature_response - threshold)) > 0 ? 1 : -1; }
  14 +
  15 + int feature_idx; // index of the feature corresponding to this weak classifier
  16 + float threshold; // threshold at which classifier predicts yes or no
  17 + int polarity; // 1 or -1. 1 if high responses correspond to positives, -1 if low values do.
  18 + float weight; // weight of this classifier. Higher weight = more accurate classifier
  19 +};
  20 +
  21 +struct DecisionTree
  22 +{
  23 + DecisionTree() {}
  24 + void append(Node node); // add a node to the tree
  25 + float predict(QList<float> responses) const; // progress down the tree. Return value should be the
  26 + // sum of the weights of the correct nodes.
  27 +
  28 + QList<Node> tree; // List of the weak classifiers
  29 +};
  30 +
  31 +class AdaBoost
  32 +{
  33 +public:
  34 + AdaBoost();
  35 + DecisionTree train(int num_classifiers); // mostly a wrapper to call selectBestNode() and updateWeights() num_classifiers times.
  36 +
  37 +private:
  38 + Node selectBestNode(); // search through all possible features to find one that improves performance the most
  39 + void updateWeights(); // successful classification lowers weights, unsuccesful raises weights. After changes weights are normalized between 0 and 1
  40 +
  41 + TrainingData td; // training data to train on
  42 + DecisionTree classifier; // classifier to be trained
  43 +};
  44 +
  45 +}
  46 +#endif // ADABOOST_H
openbr/learning/cascade.cpp 0 → 100644
  1 +#include "cascade.h"
  2 +
  3 +Cascade::Cascade()
  4 +{
  5 +}
openbr/learning/cascade.h 0 → 100644
  1 +#ifndef CASCADE_H
  2 +#define CASCADE_H
  3 +
  4 +#include "feature.h"
  5 +#include "adaboost.h"
  6 +#include <openbr/openbr_plugin.h>
  7 +
  8 +namespace br
  9 +{
  10 +
  11 +// I'm not sure if this class can be made general enough (i.e not just for face detection) to live here.
  12 +// Ideally, it should handle model i/o, and probably detection as well. Perhaps it is better in plugins/cascade.cpp
  13 +class Cascade
  14 +{
  15 +public:
  16 + Cascade(const DecisionTree &classifier, const FeatureEvaluator &evaluator) : classifier(classifier), evaluator(evaluator) {}
  17 + void detect(const cv::Mat &img, QList<QRectF> &detections, QList<float> &confidences);
  18 +
  19 + void write(QString path);
  20 + static Cascade read(QString path);
  21 +
  22 +private:
  23 + DecisionTree classifier;
  24 + FeatureEvaluator evaluator;
  25 +};
  26 +
  27 +}
  28 +
  29 +#endif // CASCADE_H
openbr/learning/feature.cpp 0 → 100644
  1 +#include "feature.h"
  2 +
  3 +Feature::Feature()
  4 +{
  5 +}
openbr/learning/feature.h 0 → 100644
  1 +#ifndef FEATURE_H
  2 +#define FEATURE_H
  3 +
  4 +#include <openbr/openbr_plugin.h>
  5 +
  6 +// These two classes should be subclassed to handle any type of feature. In a perfect world I would like to subclass
  7 +// only Feature, and have FeatureEvaluator just call randomize and evaluate (and thus not have to be subclassed) as
  8 +// that would be simpler.
  9 +namespace br
  10 +{
  11 +
  12 +class Feature
  13 +{
  14 +public:
  15 + Feature();
  16 + QList<int> get_definition() { return definition; }
  17 +
  18 + virtual void randomize(int height, int width, int channels) = 0; // Initialize the feature within these dimensions
  19 + virtual float evaluate(const QList<cv::Mat> &img, const cv::Size &pos) const = 0; // img is a list of mats to support multiple channels
  20 + // if the image is larger than the feature model (i.e
  21 + // a real image instead of a training image) pos determines
  22 + // the top left corner of the feature.
  23 +
  24 +protected:
  25 + QList<int> definition; // The definition of the feature (usually these are coords)
  26 +};
  27 +
  28 +class FeatureEvaluator
  29 +{
  30 +public:
  31 + FeatureEvaluator(int num_features_) : num_features(num_features_) {}
  32 + int get_num_features() const { return num_features; }
  33 + QList<Feature> get_features() const { return features; }
  34 +
  35 + virtual void generateRandomFeatures(int height, int width, int channels) = 0; // initialize num_features random features within these dimensions.
  36 + // will call Feature->randomize()
  37 + virtual QList<float> evaluate(const QList<cv::Mat> &img, cv::Size pos) const = 0; // return the response of all features on the given image
  38 + // will call Feature->evaluate()
  39 +
  40 +private:
  41 + int num_features;
  42 + QList<Feature> features;
  43 +};
  44 +
  45 +}
  46 +
  47 +#endif // FEATURE_H
openbr/learning/trainingdata.cpp 0 → 100644
  1 +#include "trainingdata.h"
  2 +
  3 +TrainingData::TrainingData()
  4 +{
  5 +}
openbr/learning/trainingdata.h 0 → 100644
  1 +#ifndef TRAININGDATA_H
  2 +#define TRAININGDATA_H
  3 +
  4 +#include "feature.h"
  5 +#include <openbr/openbr_plugin.h>
  6 +
  7 +namespace br
  8 +{
  9 +
  10 +struct FeatureResponse // Feature vectors need to be sorted to do boosting. This keeps the weights and labels properly associated with the response without headaches.
  11 +{
  12 + FeatureResponse(float response, int label, float weight) : response(response), label(label), weight(weight) {}
  13 +
  14 + float response;
  15 + int label;
  16 + float weight;
  17 +};
  18 +
  19 +typedef QList<FeatureResponse> FeatureVector;
  20 +
  21 +class TrainingData
  22 +{
  23 +public:
  24 + TrainingData();
  25 + // This can have getters and setters to make manipulating feature vectors easier
  26 +
  27 +private:
  28 + QList<FeatureVector> data;
  29 + QList<bool> visited_features;
  30 +};
  31 +
  32 +}
  33 +#endif // TRAININGDATA_H