Commit 8c27a29e authored by Davis King's avatar Davis King

Just renamed variables and simplified a few things. No real changes.

parent 63eb621a
......@@ -15,11 +15,11 @@ namespace dlib
template <
typename track_association_function,
typename detection_type,
typename detection_id_type
typename label_type
>
void test_track_association_function (
const track_association_function& assoc,
const std::vector<std::vector<std::pair<detection_type,detection_id_type> > >& samples,
const std::vector<std::vector<labeled_detection<detection_type,label_type> > >& samples,
unsigned long& total_dets,
unsigned long& correctly_associated_dets
)
......@@ -30,7 +30,7 @@ namespace dlib
using namespace impl;
std::vector<track_type> tracks;
std::map<detection_id_type,unsigned long> track_idx; // tracks[track_idx[id]] == track with ID id.
std::map<label_type,unsigned long> track_idx; // tracks[track_idx[id]] == track with ID id.
for (unsigned long j = 0; j < samples.size(); ++j)
{
......@@ -38,32 +38,32 @@ namespace dlib
std::vector<long> assignments = f(get_unlabeled_dets(samples[j]), tracks);
std::vector<bool> updated_track(tracks.size(), false);
// now update all the tracks with the detections that associated to them.
const std::vector<std::pair<detection_type,detection_id_type> >& dets = samples[j];
const std::vector<labeled_detection<detection_type,label_type> >& dets = samples[j];
for (unsigned long k = 0; k < assignments.size(); ++k)
{
// If the detection is associated to tracks[assignments[k]]
if (assignments[k] != -1)
{
tracks[assignments[k]].update_track(dets[k].first);
tracks[assignments[k]].update_track(dets[k].det);
updated_track[assignments[k]] = true;
// if this detection was supposed to go to this track
if (track_idx.count(dets[k].second) && track_idx[dets[k].second]==assignments[k])
if (track_idx.count(dets[k].label) && track_idx[dets[k].label]==assignments[k])
++correctly_associated_dets;
track_idx[dets[k].second] = assignments[k];
track_idx[dets[k].label] = assignments[k];
}
else
{
track_type new_track;
new_track.update_track(dets[k].first);
new_track.update_track(dets[k].det);
tracks.push_back(new_track);
// if this detection was supposed to go to a new track
if (track_idx.count(dets[k].second) == 0)
if (track_idx.count(dets[k].label) == 0)
++correctly_associated_dets;
track_idx[dets[k].second] = tracks.size()-1;
track_idx[dets[k].label] = tracks.size()-1;
}
}
......@@ -82,11 +82,11 @@ namespace dlib
template <
typename track_association_function,
typename detection_type,
typename detection_id_type
typename label_type
>
double test_track_association_function (
const track_association_function& assoc,
const std::vector<std::vector<std::vector<std::pair<detection_type,detection_id_type> > > >& samples
const std::vector<std::vector<std::vector<labeled_detection<detection_type,label_type> > > >& samples
)
{
unsigned long total_dets = 0;
......@@ -105,18 +105,18 @@ namespace dlib
template <
typename trainer_type,
typename detection_type,
typename detection_id_type
typename label_type
>
double cross_validate_track_association_trainer (
const trainer_type& trainer,
const std::vector<std::vector<std::vector<std::pair<detection_type,detection_id_type> > > >& samples,
const std::vector<std::vector<std::vector<labeled_detection<detection_type,label_type> > > >& samples,
const long folds
)
{
const long num_in_test = samples.size()/folds;
const long num_in_train = samples.size() - num_in_test;
std::vector<std::vector<std::vector<std::pair<detection_type,detection_id_type> > > > samples_train;
std::vector<std::vector<std::vector<labeled_detection<detection_type,label_type> > > > samples_train;
long next_test_idx = 0;
unsigned long total_dets = 0;
......
......@@ -14,11 +14,11 @@ namespace dlib
template <
typename track_association_function,
typename detection_type,
typename detection_id_type
typename label_type
>
double test_track_association_function (
const track_association_function& assoc,
const std::vector<std::vector<std::vector<std::pair<detection_type,detection_id_type> > > >& samples
const std::vector<std::vector<std::vector<labeled_detection<detection_type,label_type> > > >& samples
);
/*!
requires
......@@ -38,11 +38,11 @@ namespace dlib
template <
typename trainer_type,
typename detection_type,
typename detection_id_type
typename label_type
>
double cross_validate_track_association_trainer (
const trainer_type& trainer,
const std::vector<std::vector<std::vector<std::pair<detection_type,detection_id_type> > > >& samples,
const std::vector<std::vector<std::vector<labeled_detection<detection_type,label_type> > > >& samples,
const long folds
);
/*!
......
......@@ -20,16 +20,16 @@ namespace dlib
{
template <
typename detection_type,
typename detection_id_type
typename label_type
>
std::vector<detection_type> get_unlabeled_dets (
const std::vector<std::pair<detection_type,detection_id_type> >& dets
const std::vector<labeled_detection<detection_type,label_type> >& dets
)
{
std::vector<detection_type> temp;
temp.reserve(dets.size());
for (unsigned long i = 0; i < dets.size(); ++i)
temp.push_back(dets[i].first);
temp.push_back(dets[i].det);
return temp;
}
......@@ -37,21 +37,9 @@ namespace dlib
// ----------------------------------------------------------------------------------------
template <
typename detection_type_,
typename detection_id_type_ = unsigned long
>
class structural_track_association_trainer
{
public:
typedef detection_type_ detection_type;
typedef typename detection_type::track_type track_type;
typedef detection_id_type_ detection_id_type;
typedef std::pair<detection_type, detection_id_type> labeled_detection;
typedef std::vector<labeled_detection> detections_at_single_time_step;
typedef std::vector<detections_at_single_time_step> track_history;
typedef track_association_function<detection_type> trained_function_type;
structural_track_association_trainer (
)
......@@ -159,8 +147,12 @@ namespace dlib
learn_nonnegative_weights = value;
}
template <
typename detection_type,
typename label_type
>
const track_association_function<detection_type> train (
const std::vector<track_history>& samples
const std::vector<std::vector<std::vector<labeled_detection<detection_type,label_type> > > >& samples
) const
{
// make sure requires clause is not broken
......@@ -170,6 +162,7 @@ namespace dlib
<< "\n\t is_track_association_problem(samples): " << is_track_association_problem(samples)
);
typedef typename detection_type::track_type track_type;
const unsigned long num_dims = find_num_dims(samples);
......@@ -195,21 +188,30 @@ namespace dlib
return track_association_function<detection_type>(trainer.train(assignment_samples, labels));
}
template <
typename detection_type,
typename label_type
>
const track_association_function<detection_type> train (
const track_history& sample
const std::vector<std::vector<labeled_detection<detection_type,label_type> > >& sample
) const
{
std::vector<track_history> samples;
std::vector<std::vector<std::vector<labeled_detection<detection_type,label_type> > > > samples;
samples.push_back(sample);
return train(samples);
}
private:
template <
typename detection_type,
typename label_type
>
static unsigned long find_num_dims (
const std::vector<track_history>& samples
const std::vector<std::vector<std::vector<labeled_detection<detection_type,label_type> > > >& samples
)
{
typedef typename detection_type::track_type track_type;
// find a detection_type object so we can call get_similarity_features() and
// find out how big the feature vectors are.
......@@ -222,9 +224,9 @@ namespace dlib
if (samples[i][j].size() > 0)
{
track_type new_track;
new_track.update_track(samples[i][j][0].first);
new_track.update_track(samples[i][j][0].det);
typename track_type::feature_vector_type feats;
new_track.get_similarity_features(samples[i][j][0].first, feats);
new_track.get_similarity_features(samples[i][j][0].det, feats);
return feats.size();
}
}
......@@ -234,6 +236,11 @@ namespace dlib
"No detection objects were given in the call to dlib::structural_track_association_trainer::train()");
}
template <
typename detections_at_single_time_step,
typename detection_type,
typename track_type
>
static void convert_dets_to_association_sets (
const std::vector<detections_at_single_time_step>& det_history,
std::vector<std::pair<std::vector<detection_type>, std::vector<track_type> > >& data,
......@@ -243,10 +250,11 @@ namespace dlib
if (det_history.size() < 1)
return;
typedef typename detections_at_single_time_step::value_type::label_type label_type;
std::vector<track_type> tracks;
// track_labels maps from detection labels to the index in tracks. So track
// with detection label X is at tracks[track_labels[X]].
std::map<detection_id_type,unsigned long> track_labels;
std::map<label_type,unsigned long> track_labels;
add_dets_to_tracks(tracks, track_labels, det_history[0]);
using namespace impl;
......@@ -258,17 +266,21 @@ namespace dlib
}
}
template <
typename labeled_detection,
typename label_type
>
static std::vector<long> get_association_labels(
const std::vector<labeled_detection>& dets,
const std::map<detection_id_type,unsigned long>& track_labels
const std::map<label_type,unsigned long>& track_labels
)
{
std::vector<long> assoc(dets.size(),-1);
// find out which detections associate to what tracks
for (unsigned long i = 0; i < dets.size(); ++i)
{
typename std::map<detection_id_type,unsigned long>::const_iterator j;
j = track_labels.find(dets[i].second);
typename std::map<label_type,unsigned long>::const_iterator j;
j = track_labels.find(dets[i].label);
// If this detection matches one of the tracks then record which track it
// matched with.
if (j != track_labels.end())
......@@ -277,9 +289,14 @@ namespace dlib
return assoc;
}
template <
typename track_type,
typename label_type,
typename labeled_detection
>
static void add_dets_to_tracks (
std::vector<track_type>& tracks,
std::map<detection_id_type,unsigned long>& track_labels,
std::map<label_type,unsigned long>& track_labels,
const std::vector<labeled_detection>& dets
)
{
......@@ -288,18 +305,18 @@ namespace dlib
// first assign the dets to the tracks
for (unsigned long i = 0; i < dets.size(); ++i)
{
const detection_id_type& label = dets[i].second;
const label_type& label = dets[i].label;
if (track_labels.count(label))
{
const unsigned long track_idx = track_labels[label];
tracks[track_idx].update_track(dets[i].first);
tracks[track_idx].update_track(dets[i].det);
updated_track[track_idx] = true;
}
else
{
// this detection creates a new track
track_type new_track;
new_track.update_track(dets[i].first);
new_track.update_track(dets[i].det);
tracks.push_back(new_track);
track_labels[label] = tracks.size()-1;
}
......
......@@ -11,45 +11,23 @@ namespace dlib
// ----------------------------------------------------------------------------------------
template <
typename detection_type_,
typename detection_id_type_ = unsigned long
>
class structural_track_association_trainer
{
/*!
REQUIREMENTS ON detection_type_
It must be an object that implements an interface compatible with the
example_detection defined in dlib/svm/track_association_function_abstract.h.
REQUIREMENTS ON detection_id_type_
This can be any type that can be used as the key in a std::map. e.g.
unsigned long, std::string, etc.
WHAT THIS OBJECT REPRESENTS
This object is a tool for learning to solve a track association problem. That
is, it takes in a set of training data and outputs a track_association_function
This object is a tool for learning to solve a track association problem. That
is, it takes in a set of training data and outputs a track_association_function
you can use to do detection to track association. The training data takes the
form of a set or sets of "track histories". Each track history is a
std::vector where each element contains all the detections from a single time
step. Moreover, each detection is labeled with a detection_id_type_ that
uniquely identifies which object (e.g. person or whatever) the detection really
corresponds to. That is, the detection_id_type_ values indicate the correct
detection to track associations. The goal of this object is then to produce a
track_association_function that can perform a correct detection to track
association at each time step.
step. Moreover, each detection has a label that uniquely identifies which
object (e.g. person or whatever) the detection really corresponds to. That is,
the labels indicate the correct detection to track associations. The goal of
this object is then to produce a track_association_function that can perform a
correct detection to track association at each time step.
!*/
public:
typedef detection_type_ detection_type;
typedef typename detection_type::track_type track_type;
typedef detection_id_type_ detection_id_type;
typedef std::pair<detection_type, detection_id_type> labeled_detection;
typedef std::vector<labeled_detection> detections_at_single_time_step;
typedef std::vector<detections_at_single_time_step> track_history;
typedef track_association_function<detection_type> trained_function_type;
structural_track_association_trainer (
);
......@@ -192,15 +170,21 @@ namespace dlib
- #learns_nonnegative_weights() == value
!*/
template <
typename detection_type,
typename label_type
>
const track_association_function<detection_type> train (
const track_history& sample
const std::vector<std::vector<labeled_detection<detection_type,label_type> > >& sample
) const;
/*!
requires
- is_track_association_problem(samples) == true
- is_track_association_problem(sample) == true
ensures
- This function attempts to learn to do track association from the given
training data.
training data. Note that we interpret sample as a single track history such
that sample[0] are all detections from the first time step, then sample[1]
are detections from the second time step, and so on.
- returns a function F such that:
- Executing F(tracks, detections) will try to correctly associate the
contents of detections to the contents of tracks and perform track
......@@ -209,8 +193,12 @@ namespace dlib
- min(F.get_assignment_function().get_weights()) >= 0
!*/
template <
typename detection_type,
typename label_type
>
const track_association_function<detection_type> train (
const std::vector<track_history>& samples
const std::vector<std::vector<std::vector<labeled_detection<detection_type,label_type> > > >& sample
) const;
/*!
requires
......
......@@ -307,14 +307,28 @@ namespace dlib
return false;
}
// ----------------------------------------------------------------------------------------
template <
typename detection_type_,
typename label_type_ = long
>
struct labeled_detection
{
typedef detection_type_ detection_type;
typedef label_type_ label_type;
detection_type det;
label_type label;
};
// ----------------------------------------------------------------------------------------
template <
typename detection_type,
typename detection_id_type
typename label_type
>
bool is_track_association_problem (
const std::vector<std::vector<std::pair<detection_type,detection_id_type> > >& samples
const std::vector<std::vector<labeled_detection<detection_type,label_type> > >& samples
)
{
if (samples.size() == 0)
......@@ -329,12 +343,12 @@ namespace dlib
if (num_nonzero_elements < 2)
return false;
// now make sure the detection_id_type values are unique within each time step.
// now make sure the label_type values are unique within each time step.
for (unsigned long i = 0; i < samples.size(); ++i)
{
std::set<detection_id_type> vals;
std::set<label_type> vals;
for (unsigned long j = 0; j < samples[i].size(); ++j)
vals.insert(samples[i][j].second);
vals.insert(samples[i][j].label);
if (vals.size() != samples[i].size())
return false;
}
......@@ -347,10 +361,10 @@ namespace dlib
template <
typename detection_type,
typename detection_id_type
typename label_type
>
bool is_track_association_problem (
const std::vector<std::vector<std::vector<std::pair<detection_type,detection_id_type> > > >& samples
const std::vector<std::vector<std::vector<labeled_detection<detection_type,label_type> > > >& samples
)
{
for (unsigned long i = 0; i < samples.size(); ++i)
......
......@@ -164,12 +164,36 @@ namespace dlib
// ----------------------------------------------------------------------------------------
template <
typename detection_type_,
typename label_type_ = long
>
struct labeled_detection
{
/*!
WHAT THIS OBJECT REPRESENTS
This is a simple object, like std::pair, it just holds two objects. It
serves the same purpose as std::pair except that it has informative names
describing its two members and is intended for use with track association
problems.
!*/
typedef detection_type_ detection_type;
typedef label_type_ label_type;
detection_type det;
label_type label;
};
// ----------------------------------------------------------------------------------------
template <
typename detection_type,
typename detection_id_type
typename label_type
>
bool is_track_association_problem (
const std::vector<std::vector<std::pair<detection_type,detection_id_type> > >& samples
const std::vector<std::vector<labeled_detection<detection_type,label_type> > >& samples
);
/*!
ensures
......@@ -185,8 +209,8 @@ namespace dlib
- samples[i] is a set of labeled detections from the i-th time step.
Each detection has been labeled with its "true object identity".
That is, all the detection throughout the history with the same
detection_id_type value are detections from the same object and
therefore should be associated to the same track.
label_type value are detections from the same object and therefore
should be associated to the same track.
Putting this all together, samples is a valid track association learning
problem if and only if the following are all true:
- samples.size() > 0
......@@ -198,18 +222,18 @@ namespace dlib
or it is impossible to learn anything.
- for all valid i:
- for all valid j and k where j!=k:
- samples[i][j].second != samples[i][k].second
(i.e. the detection_id_type values must be unique within each
time step. Or in other words, you can't have two detections on
the same object in a single time step.)
- samples[i][j].label != samples[i][k].label
(i.e. the label_type values must be unique within each time step.
Or in other words, you can't have two detections on the same
object in a single time step.)
!*/
template <
typename detection_type,
typename detection_id_type
typename label_type
>
bool is_track_association_problem (
const std::vector<std::vector<std::vector<std::pair<detection_type,detection_id_type> > > >& samples
const std::vector<std::vector<std::vector<labeled_detection<detection_type,label_type> > > >& samples
);
/*!
ensures
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment