Commit 5d001f4dba69bccdeb5e3db905b69cdaf18235dd
1 parent
d24c2952
Unimplemented header files for adaboost
Showing
9 changed files
with
177 additions
and
1 deletions
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
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
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
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
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 |