* Compile the source code entirely
* Generate the "pool file" containing the uncompressed images
- converted to gray levels, labeled with the ground truth.
+ converted to gray levels, labelled with the ground truth.
* Run 20 rounds of training / test (ten rounds for each of HB and
H+B detectors with different random seeds)
/*
This class is an implementation of the Classifier with a boosting of
- tree. It works with samples from R^n and has no concept of the
+ trees. It works with samples from R^n and has no concept of the
pi-features.
*/
/*
- This class is mostly able to learn a classifier from a SampleSet and
- to provide a scalar response on any test sample. Additional methods
- are required for persistence and select the possibly very few used
- features.
+ This class is almost purely virtual. It represents a classifier that
+ can be trained from a SampleSet and able to provide a scalar
+ response on any test sample. Additional methods are required for
+ persistence and select the possibly very few used features.
*/
case CLASSIFIER_BOOSTED:
result = new BoostedClassifier();
break;
-// case CLASSIFIER_BAYESIAN:
-// result = new BayesianClassifier();
-// break;
default:
cerr << "Unknown classifier ID " << id << endl;
exit(1);
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ Function to read classifiers, so that we can deal with different
+ type of classifiers.
+
+ */
+
#ifndef CLASSIFIER_READER_H
#define CLASSIFIER_READER_H
#include "classifier.h"
-enum { CLASSIFIER_BOOSTED, CLASSIFIER_BAYESIAN };
+enum { CLASSIFIER_BOOSTED };
Classifier *read_classifier(istream *is);
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ An implementation of the classifier with a decision tree. Each node
+ simply thresholds one of the component, and is chosen for maximum
+ loss reduction locally during training. The leaves are labelled with
+ the classifier response, which is chosen again for maximum loss
+ reduction.
+
+ */
+
#ifndef DECISION_TREE_H
#define DECISION_TREE_H
/*
- This is the main class, a folded hierarchy of classifiers.
+ This is the main class, a detector as a folded hierarchy of
+ classifiers.
*/
<< "INFO TOTAL_SURFACE " << total_surface << endl;
;
}
-
-void parse_scene(Detector *detector, const char *image_name) {
- RGBImage tmp;
- tmp.read_jpg(image_name);
- RichImage image(tmp.width(), tmp.height());
-
- for(int y = 0; y < tmp.height(); y++) {
- for(int x = 0; x < tmp.width(); x++) {
- image.set_value(x, y, int(scalar_t(tmp.pixel(x, y, 0)) * 0.2989 +
- scalar_t(tmp.pixel(x, y, 1)) * 0.5870 +
- scalar_t(tmp.pixel(x, y, 2)) * 0.1140));
- }
- }
-
- image.compute_rich_structure();
-
- PoseCellScoredSet cell_set;
- detector->parse(&image, &cell_set);
- cell_set.decimate_hit(detector->nb_levels() - 1);
-
- cout << "RESULT " << image_name << endl;
- for(int c = 0; c < cell_set.nb_cells(); c++) {
- cout << "ALARM " << c << endl;
- Pose alarm;
- cell_set.get_cell(c)->get_centroid(&alarm);
- alarm.print(&cout);
- }
- cout << "END_RESULT" << endl;
-}
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ Two functions to compute a detector error rate on a pool of scenes.
+
+ */
+
#ifndef ERROR_RATES_H
#define ERROR_RATES_H
void print_decimated_error_rate(int level, LabelledImagePool *pool, Detector *detector);
-void parse_scene(Detector *detector, const char *image_name);
-
#endif
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ My very own implementation of the fusion sort.
+
+ */
+
#ifndef FUSION_SORT_H
#define FUSION_SORT_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ A simple representation of a Gaussian distribution.
+
+ */
+
#ifndef GAUSSIAN_H
#define GAUSSIAN_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ We stuff all the global values in there.
+
+ */
+
#ifndef GLOBAL_H
#define GLOBAL_H
#include "progress_bar.h"
enum { LOSS_EXPONENTIAL,
- LOSS_EV_REGULARIZED,
LOSS_HINGE,
LOSS_LOGISTIC };
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ An implementation of a gray-scale image with a minimum set of
+ methods.
+
+ */
+
#ifndef IMAGE_H
#define IMAGE_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ An interval class.
+
+ */
+
#ifndef INTERVAL_H
#define INTERVAL_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ A LabelledImage is a RichImage labelled with the ground truth,
+ i.e. the target poses.
+
+ */
+
#ifndef LABELLED_IMAGE_H
#define LABELLED_IMAGE_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ This is a LabelledImagePool that corresponds physically to a file.
+
+ */
+
#ifndef LABELLED_IMAGE_POOL_FILE_H
#define LABELLED_IMAGE_POOL_FILE_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ This is a LabelledImagePool which corresponds to a subset of another
+ pool. We use that to extract the training, validation and test pool
+ from the global pool. It is mainly necessary to have such a class to
+ avoid unnecessary memory usage.
+
+ */
+
#ifndef LABELLED_IMAGE_POOL_SUBSET_H
#define LABELLED_IMAGE_POOL_SUBSET_H
}
break;
- case LOSS_EV_REGULARIZED:
- {
- scalar_t sum_pos = 0, sum_sq_pos = 0, nb_pos = 0, m_pos, v_pos;
- scalar_t sum_neg = 0, sum_sq_neg = 0, nb_neg = 0, m_neg, v_neg;
-
- for(int n = 0; n < samples->nb_samples(); n++) {
- if(samples->label(n) > 0) {
- sum_pos += responses[n];
- sum_sq_pos += sq(responses[n]);
- nb_pos += 1.0;
- }
- else if(samples->label(n) < 0) {
- sum_neg += responses[n];
- sum_sq_neg += sq(responses[n]);
- nb_neg += 1.0;
- }
- }
-
- m_pos = sum_pos / nb_pos;
- v_pos = sum_sq_pos/(nb_pos - 1) - sq(sum_pos)/(nb_pos * (nb_pos - 1));
-
- scalar_t loss_pos = nb_pos * exp(v_pos/2 - m_pos);
-
- m_neg = sum_neg / nb_neg;
- v_neg = sum_sq_neg/(nb_neg - 1) - sq(sum_neg)/(nb_neg * (nb_neg - 1));
-
- scalar_t loss_neg = nb_neg * exp(v_neg/2 + m_neg);
-
- for(int n = 0; n < samples->nb_samples(); n++) {
- if(samples->label(n) > 0) {
- derivatives[n] =
- ( - 1/nb_pos + (responses[n] - m_pos)/(nb_pos - 1)) * loss_pos;
- } else if(samples->label(n) < 0) {
- derivatives[n] =
- ( 1/nb_neg + (responses[n] - m_neg)/(nb_neg - 1)) * loss_neg;
- }
- }
- }
-
- break;
-
case LOSS_HINGE:
{
for(int n = 0; n < samples->nb_samples(); n++) {
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ A LossMachine provides all the methods necessary to do boosting with
+ a certain loss. Note that only the LOSS_EXPONENTIAL has been really
+ tested. Using the others may result in unexpected effects.
+
+ */
+
#ifndef LOSS_MACHINE_H
#define LOSS_MACHINE_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ Functions to produce the figures for the paper.
+
+ */
+
#ifndef MATERIALS_H
#define MATERIALS_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ A bunch of useful little functions.
+
+ */
+
#ifndef MISC_H
#define MISC_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ A class to parse the arguments from the command line.
+
+ */
+
#ifndef PARAM_PARSER_H
#define PARAM_PARSER_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
-#ifndef PARSING_H
-#define PARSING_H
-
/*
A Parsing is associated to a LabelledImage and stores responses over
- cells.
+ cells. We use it during training to remember the responses over all
+ the negative samples.
*/
+#ifndef PARSING_H
+#define PARSING_H
+
#include "fusion_sort.h"
#include "pose_cell_hierarchy.h"
#include "classifier.h"
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
-#ifndef PARSING_POOL_H
-#define PARSING_POOL_H
-
/*
- A ParsingPool is a family of Parsing associated to all the images of
- a LabelledImagePool.
+ A ParsingPool is a family of Parsings associated to all the images
+ of a LabelledImagePool.
*/
+#ifndef PARSING_POOL_H
+#define PARSING_POOL_H
+
#include "parsing.h"
#include "pi_feature_family.h"
#include "classifier.h"
/*
- This class implement the notion of pi-feature, that is a feature
- which can be evaluated on a pair image / referential, where the
- referential is computed from a pose cell.
+ A PiFeatures is the central new idea of this approach. It is a
+ feature which can be evaluated on a pair image / referential, where
+ the referential is computed from a pose cell.
*/
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ A PiFeatureFamily is simply a set of pi-features, with a method to
+ extract a subfamily, so that we can forget all the features not used
+ by a classifier when the learning is over.
+
+ */
+
#ifndef PI_FEATURE_FAMILY_H
#define PI_FEATURE_FAMILY_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ This the pose of a target. In the case of cats, we have a bounding
+ box, the head location and scale, and the body location. All are
+ given in the image coordinate system.
+
+ */
+
#ifndef POSE_H
#define POSE_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ A PoseCell is a 5d rectangle in the pose space.
+
+ */
+
#ifndef POSE_CELL_H
#define POSE_CELL_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ A PoseCellHierarchy provides the necessary methods to visit a
+ recursive partitioning of the pose space. The two main methods can
+ give you an root partitioning, or compute a finer partitioning from
+ an existing one.
+
+ */
+
#ifndef POSE_CELL_HIERARCHY_H
#define POSE_CELL_HIERARCHY_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ A function to read a hierarchy. We have in mind to have different
+ kind of hierarchies later.
+
+ */
+
#ifndef POSE_CELL_HIERARCHY_READER_H
#define POSE_CELL_HIERARCHY_READER_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ A set of PoseCells each paired with a detector response. This is
+ what the parsing of a scene produces.
+
+ */
+
#ifndef POSE_CELL_SCORED_SET_H
#define POSE_CELL_SCORED_SET_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ A set of PoseCell.
+
+ */
+
#ifndef POSE_CELL_SET_H
#define POSE_CELL_SET_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
-// A simple color image class
+/*
+
+ A simple image class to either load color images, or produce
+ materials.
+
+ */
#ifndef RGB_IMAGE_H
#define RGB_IMAGE_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
-// A simple color image class
+/*
+
+ Same as RGBImage, but with sub-pixel resolution to produce nifty
+ smoothing in the drawings.
+
+ */
#ifndef RGB_IMAGE_SUBPIXEL_H
#define RGB_IMAGE_SUBPIXEL_H
/*
- This class implements the multi-scale basic edge features on the
- images. The heavy machinery and ugly coding style is motivated by
- performance.
+ A RichImage is an Image with all the necessary pre-computation to
+ compute the feature responses: Edge detection and local variance
+ thresholding at multiple scale, with integral images. The heavy
+ machinery and ugly coding style is motivated by performance.
*/
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ A SampleSet stands for a set of samples from R^d with their
+ labels. It abstracts the notion features and is what the machine
+ learning techniques of this software see.
+
+ */
+
#ifndef SAMPLE_SET_H
#define SAMPLE_SET_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
-// A tiny class to implement shared objects and lazy deletion
+/*
-// When you create a reference to such an object, call grab(), and
-// when you destroy that reference, call release() which will delete
-// it if no reference remains. Never delete it yourself!
+ A tiny class to implement shared objects and lazy deletion. When you
+ create a reference to such an object, call grab(), and when you
+ destroy that reference, call release() which will delete it if no
+ reference remains. Never delete it yourself!
+
+ */
#ifndef SHARED_H
#define SHARED_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ A SharedResponses object is used to avoid duplicating the data when
+ we create several LabelledImagePoolSubset which look at the same
+ LabelledImagePool.
+
+ */
+
#ifndef SHARED_RESPONSES_H
#define SHARED_RESPONSES_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ This class is only used to provide the read/write methods from a
+ char *, given that the class implements read/write from streams.
+
+ */
+
#ifndef STORABLE_H
#define STORABLE_H
// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
///////////////////////////////////////////////////////////////////////////
+/*
+
+ Two handy functions to sample in a very large weighted sample set,
+ and to generate a ROC curve given a very large sample set.
+
+ */
+
#ifndef TOOLS_H
#define TOOLS_H