Skip to content

Commit

Permalink
trained pedestrian.m
Browse files Browse the repository at this point in the history
  • Loading branch information
liuliu committed Jun 29, 2012
1 parent 1884333 commit 79f9514
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 119 deletions.
4 changes: 2 additions & 2 deletions bin/bbfdraw.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
y = args[1].to_i
width = args[2].to_i
height = args[3].to_i
rect += sprintf("-draw \"rectangle %d,%d,%d,%d\" ", x, y, x + width, y + height)
rect += sprintf("-draw \"ellipse %d,%d %d,%d 0,360\" ", x + width / 2, y + height / 2, width / 2, height / 2)
end

%x[#{sprintf("convert %s -fill none -stroke red -strokewidth 1 %s%s", ARGV[0], rect, ARGV[1])}]
%x[#{sprintf("convert %s -fill none -stroke green -strokewidth 2 %s%s", ARGV[0], rect, ARGV[1])}]
2 changes: 1 addition & 1 deletion bin/dpmdetect.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ int main(int argc, char** argv)
ccv_dense_matrix_t* image = 0;
ccv_read(argv[1], &image, CCV_IO_ANY_FILE);
ccv_dpm_mixture_model_t* model = ccv_load_dpm_mixture_model(argv[2]);
ccv_dpm_param_t params = { .interval = 8, .min_neighbors = 1, .flags = 0, .threshold = 0.85 };
ccv_dpm_param_t params = { .interval = 8, .min_neighbors = 1, .flags = 0, .threshold = 0.8 };
if (image != 0)
{
unsigned int elapsed_time = get_current_time();
Expand Down
2 changes: 1 addition & 1 deletion bin/dpmdraw.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
y = args[2].to_i
width = args[3].to_i
height = args[4].to_i
rect += sprintf("-stroke blue -draw \"rectangle %d,%d,%d,%d\" ", x, y, x + width, y + height)
rect += sprintf("-stroke \"#0000ff80\" -draw \"rectangle %d,%d,%d,%d\" ", x, y, x + width, y + height)
else
x = args[0].to_i
y = args[1].to_i
Expand Down
36 changes: 24 additions & 12 deletions doc/dpm.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,32 @@ without multi-thread support.

Accuracy-wise:

There are two off-the-shelf implementations. One is the DPM in matlab from author,
the other is HOG detector from OpenCV. Fo the task to detect pedestrians in a
given image, we use INTRA 2008 dataset, and it provides both training and testing
data. With OpenCV stock peopledetect sample program, we get:
There are two off-the-shelf implementations. One is the DPM in Matlab from author,
the other is the HOG detector from OpenCV. For the task to detect pedestrians in a
given image, we use INRIA 2008 dataset, and it provides both training and testing
data. With OpenCV stock peopledetect sample program (scale factor to be 1.09 to
match our DPM setting (interval = 8)), we get:

65.7% (156)
47.37% (133)

The former one is the detection rate (how many objects have been detected), the
later is the number of false alarms (the detected region doesn't contain the
expected object)
The former one is the detection rate (how many objects have been successfully
detected), the later is the number of false alarms (the detected region doesn't
contain the expected object).

Our implementation?
The dpmvldtr.rb compares the ground truth bounding box with the detected bounding
box by OpenCV, if the overlap area is larger than 60% of the biggest bounding box
area among the two), it will be counted as a true positive. Otherwise, it will be
counted as a false positive (false alarm).

80.14% (74)
Another implementation is from the DPM inventor, it is a Matlab implementation,
and the author has a specially trained detector for INRIA 2008 dataset.

Looks pretty good!
75.21% (74)

The DPM implementation in ccv was trained for three days using the default parameters
with INRIA training data. The result is not bad:

76.4% (68)

Speed-wise:

Expand All @@ -53,4 +63,6 @@ Speed-wise:
How to train my own detector?
-----------------------------

Yes, this implementation comes with a tool to train your own detector too.
Yes, this implementation comes with a tool to train your own detector too. In this
chapter, I will go through how I trained the pedestrian.m detector that shipped
with ccv source code.
32 changes: 19 additions & 13 deletions lib/ccv_dpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,22 +159,28 @@ static ccv_dpm_mixture_model_t* _ccv_dpm_model_copy(ccv_dpm_mixture_model_t* _mo
return model;
}

static void _ccv_dpm_write_checkpoint(ccv_dpm_mixture_model_t* model, const char* dir)
static void _ccv_dpm_write_checkpoint(ccv_dpm_mixture_model_t* model, int done, const char* dir)
{
char swpfile[1024];
sprintf(swpfile, "%s.swp", dir);
FILE* w = fopen(swpfile, "w+");
if (!w)
return;
fprintf(w, ",\n");
if (done)
fprintf(w, ".\n");
else
fprintf(w, ",\n");
int i, j, x, y, ch, count = 0;
for (i = 0; i < model->count; i++)
{
if (model->root[i].root.w == 0)
break;
count++;
}
fprintf(w, "%d %d\n", model->count, count);
if (done)
fprintf(w, "%d\n", model->count);
else
fprintf(w, "%d %d\n", model->count, count);
for (i = 0; i < count; i++)
{
ccv_dpm_root_classifier_t* root_classifier = model->root + i;
Expand Down Expand Up @@ -1317,9 +1323,9 @@ static void _ccv_dpm_check_params(ccv_dpm_new_param_t params)
assert(params.symmetric == 0 || params.symmetric == 1);
assert(params.min_area > 100);
assert(params.max_area > params.min_area);
assert(params.iterations > 0);
assert(params.data_minings > 0);
assert(params.relabels > 0);
assert(params.iterations >= 0);
assert(params.data_minings >= 0);
assert(params.relabels >= 0);
assert(params.negative_cache_size > 0);
assert(params.include_overlap > 0.1);
assert(params.alpha > 0 && params.alpha < 1);
Expand Down Expand Up @@ -1447,7 +1453,7 @@ void ccv_dpm_mixture_model_new(char** posfiles, ccv_rect_t* bboxes, int posnum,
root_classifier->root.w = ccv_dense_matrix_new(rows[i], cols[i], CCV_32F | 31, 0, 0);
printf("initializing root mixture model for model %d(%d)\n", i + 1, params.components);
_ccv_dpm_initialize_root_classifier(rng, root_classifier, i, mnum[i], labels, posfiles, bboxes, posnum, bgfiles, bgnum, negnum, params.C, params.symmetric, params.grayscale);
_ccv_dpm_write_checkpoint(model, checkpoint);
_ccv_dpm_write_checkpoint(model, 0, checkpoint);
}
ccfree(fn);
ccfree(labels);
Expand Down Expand Up @@ -1475,11 +1481,11 @@ void ccv_dpm_mixture_model_new(char** posfiles, ccv_rect_t* bboxes, int posnum,
} else {
printf(" - initializing part filters for model %d(%d)\n", i + 1, params.components);
_ccv_dpm_initialize_part_classifiers(model->root + i, params.parts, params.symmetric);
_ccv_dpm_write_checkpoint(model, checkpoint);
_ccv_dpm_write_checkpoint(model, initcheckpoint);
_ccv_dpm_write_checkpoint(model, 0, checkpoint);
_ccv_dpm_write_checkpoint(model, 0, initcheckpoint);
}
}
_ccv_dpm_write_checkpoint(model, checkpoint);
_ccv_dpm_write_checkpoint(model, 0, checkpoint);
/* optimize both root filter and part filters with stochastic gradient descent */
printf("optimizing root filter & part filters with stochastic gradient descent\n");
char gradient_progress_checkpoint[512];
Expand Down Expand Up @@ -1638,7 +1644,7 @@ void ccv_dpm_mixture_model_new(char** posfiles, ccv_rect_t* bboxes, int posnum,
previous_negative_loss = negative_loss;
alpha *= params.alpha_ratio; // it will decrease with each iteration
}
_ccv_dpm_write_checkpoint(model, checkpoint);
_ccv_dpm_write_checkpoint(model, 0, checkpoint);
printf("\n - data mining %d takes %.2lf seconds at loss %.5lf, %d more to go (%d of %d)\n", d + 1, (double)(_ccv_dpm_time_measure() - elapsed_time) / 1000000.0, loss, params.data_minings - d - 1, c + 1, params.relabels);
j = 0;
double* scores = (double*)ccmalloc(posnum * sizeof(double));
Expand All @@ -1657,7 +1663,7 @@ void ccv_dpm_mixture_model_new(char** posfiles, ccv_rect_t* bboxes, int posnum,
printf("\n");
char persist[512];
sprintf(persist, "%s/model.%d.%d", dir, c, d);
_ccv_dpm_write_checkpoint(model, persist);
_ccv_dpm_write_checkpoint(model, 0, persist);
}
d = 0;
// if abort, means that we cannot find enough negative examples, try to adjust constant
Expand All @@ -1680,7 +1686,7 @@ void ccv_dpm_mixture_model_new(char** posfiles, ccv_rect_t* bboxes, int posnum,
ccfree(posv);
printf("root rectangle prediction with linear regression\n");
_ccv_dpm_initialize_root_rectangle_estimator(model, posfiles, bboxes, posnum, params);
_ccv_dpm_write_checkpoint(model, checkpoint);
_ccv_dpm_write_checkpoint(model, 1, checkpoint);
printf("done\n");
remove(gradient_progress_checkpoint);
_ccv_dpm_mixture_model_cleanup(model);
Expand Down
Loading

0 comments on commit 79f9514

Please sign in to comment.