Skip to content

Commit

Permalink
change the naming of several functions
Browse files Browse the repository at this point in the history
  • Loading branch information
liuliu committed Aug 26, 2013
1 parent a3c8fec commit 5df1de1
Show file tree
Hide file tree
Showing 14 changed files with 326 additions and 17 deletions.
2 changes: 1 addition & 1 deletion bin/bbfdetect.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ int main(int argc, char** argv)
int i;
ccv_enable_default_cache();
ccv_dense_matrix_t* image = 0;
ccv_bbf_classifier_cascade_t* cascade = ccv_load_bbf_classifier_cascade(argv[2]);
ccv_bbf_classifier_cascade_t* cascade = ccv_bbf_read_classifier_cascade(argv[2]);
ccv_read(argv[1], &image, CCV_IO_GRAY | CCV_IO_ANY_FILE);
if (image != 0)
{
Expand Down
4 changes: 2 additions & 2 deletions bin/bbffmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
void write_c(ccv_bbf_classifier_cascade_t* cascade)
{

printf("ccv_bbf_classifier_cascade_t* ccv_load_bbf_classifier_cascade()\n"
printf("ccv_bbf_classifier_cascade_t* ccv_bbf_read_classifier_cascade()\n"
"{\n"
" ccv_bbf_classifier_cascade_t* cascade = (ccv_bbf_classifier_cascade_t*)malloc(sizeof(ccv_bbf_classifier_cascade_t));\n"
" cascade->count = %d;\n"
Expand Down Expand Up @@ -98,7 +98,7 @@ void write_json(ccv_bbf_classifier_cascade_t* cascade)
int main(int argc, char** argv)
{
assert(argc >= 3);
ccv_bbf_classifier_cascade_t* cascade = ccv_load_bbf_classifier_cascade(argv[1]);
ccv_bbf_classifier_cascade_t* cascade = ccv_bbf_read_classifier_cascade(argv[1]);
if (strcmp(argv[2], "bin") == 0)
{
assert(argc >= 4);
Expand Down
2 changes: 1 addition & 1 deletion bin/dpmdetect.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ int main(int argc, char** argv)
ccv_enable_default_cache();
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_mixture_model_t* model = ccv_dpm_read_mixture_model(argv[2]);
if (image != 0)
{
unsigned int elapsed_time = get_current_time();
Expand Down
32 changes: 29 additions & 3 deletions bin/icfcreate.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,28 @@ void exit_with_help()
{
printf(
"\n \033[1mUSAGE\033[0m\n\n icfcreate [OPTION...]\n\n"
" \033[1mREQUIRED OPTIONS\033[0m\n\n"
" --positive-list : text file contains a list of positive files in format:\n"
" <file name> center-x center-y horizontal-axis-length vertical-axis-length object-roll object-pitch object-yaw \\newline\n"
" --positive-count : the number of positive examples we should collect from positive files with certain distortion\n"
" --validate-list : text file contains a list of positive files in following format but only used for soft cascading:\n"
" <file name> center-x center-y horizontal-axis-length vertical-axis-length object-roll object-pitch object-yaw \\newline\n"
" --acceptance : what percentage of validate examples that we should accept for soft cascading\n"
" --background-list : text file contains a list of image files that don't contain any target objects\n"
" --negative-count : the number of negative examples we should collect from background files for boosting\n"
" --size : size of object in pixel formatted as WxH\n"
" --margin : margin for object when extracting from given images, formatted as left,top,right,bottom\n"
" --feature-size : the number of features that we randomly generates and later pooling from\n"
" --weak-classifier-count : the number of weak classifiers in the boosted model\n"
" --working-dir : the directory to save progress and produce result model\n\n"
" \033[1mOTHER OPTIONS\033[0m\n\n"
" --base-dir : change the base directory so that the program can read images from there\n"
" --grayscale : 0 or 1, whether to exploit color in a given image [DEFAULT TO 0]\n"
" --deform-shift : [DEFAULT TO 1]\n"
" --deform-angle : [DEFAULT TO 0]\n"
" --deform-scale : [DEFAULT TO 0.075]\n"
" --min-dimension : [DEFAULT TO 2]\n"
" --bootstrap : [DEFAULT TO 3]\n\n"
);
exit(-1);
}
Expand All @@ -23,6 +45,10 @@ int main(int argc, char** argv)
{"negative-count", 1, 0, 0},
{"positive-count", 1, 0, 0},
{"acceptance", 1, 0, 0},
{"size", 1, 0, 0},
{"margin", 1, 0, 0},
{"feature-size", 1, 0, 0},
{"weak-classifier-count", 1, 0, 0},
/* optional parameters */
{"base-dir", 1, 0, 0},
{0, 0, 0, 0}
Expand Down Expand Up @@ -83,7 +109,7 @@ int main(int argc, char** argv)
FILE* r1 = fopen(background_list, "r");
assert(r1 && "background-list doesn't exists");
FILE* r2 = fopen(test_list, "r");
assert(r2 && "test-list doesn't exists");
assert(r2 && "validate-list doesn't exists");
char* file = (char*)malloc(1024);
ccv_decimal_pose_t pose;
int dirlen = (base_dir != 0) ? strlen(base_dir) + 1 : 0;
Expand Down Expand Up @@ -141,7 +167,7 @@ int main(int argc, char** argv)
}
fclose(r2);
free(file);
params.grayscale = 1;
params.grayscale = 0;
params.margin = ccv_margin(5, 5, 5, 5);
params.size = ccv_size(20, 60);
params.min_dimension = 2;
Expand All @@ -151,7 +177,7 @@ int main(int argc, char** argv)
params.feature_size = 50000;
params.weak_classifier = 2000;
params.acceptance = acceptance;
params.bootstrap = 4;
params.bootstrap = 3;
params.detector = ccv_icf_default_params;
params.detector.step_through = 4; // for faster negatives bootstrap time
ccv_icf_classifier_cascade_t* classifier = ccv_icf_classifier_cascade_new(posfiles, positive_count, bgfiles, negative_count, validatefiles, working_dir, params);
Expand Down
65 changes: 65 additions & 0 deletions doc/icf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
ICF: Integral Channel Features
==============================

What's ICF?
-----------

The original paper refers to:
Integral Channel Features, P. Dollar, Z. Tu, P. Perona, and S. Belongie, BMVC 2009

The improved version refers to:
Pedestrian Detection at 100 Frames per Second, R. Benenson, M. Mathias, R. Timofte, and L. Van Gool, CVPR 2012
Seeking the Strongest Rigid Detector, R. Benenson, M. Mathias, R. Timofte, and L. Van Gool, CVPR 2013

How it works?
-------------

This is a long story, you should read the original paper and the two follow ups to get
the idea why ICF is the strongest rigid detector, ccv does this though:

./icfdetect <Your Image contains Pedestrians> ../samples/pedestrian.icf | ./icfdraw.rb <Your Image contains Pedestrians> output.png

Checkout the output.png, all pedestrians should have a red box on them.

What about performance?
-----------------------

Speed-wise:

ICF has two modes, one is presented on the original paper, by resizing input into different
scales, and then run the same classifier again and again on these resized inputs. The
second is presented in the improved version, by running multiple classifiers that are
trained on different scales on the same input.

The second approach will be the faster alternative, unfortunately, I am unable to obtain
a reasonable recall / precision with the second approach.

Running in the first mode, on a computer with Core i7 3770K, with INRIA 2008 test set,
the figures are:

real 2m19.18s
user 2m16.30s
sys 0m2.79s

It is still slower than HOG, but faster than DPM implementation in libccv.

Accuracy-wise:

The pedestrian.icf model provided in ./samples are trained with INRIA 2008 training
dataset, but with additional 7542 negative samples collected from Flickr. The model is
trained at size 31x74, with 6px margins on each side.

The provided model is then tested with INRIA 2008 test dataset, if bounding boxes
overlap is greater than 0.5 of the bigger bounding boxes, it is a true positive.
The validation script is available at ./bin/icfvldtr.rb.

77.25% (66)

Which has slightly higher recall than DPM implementation provided in ccv, with higher
false alarms too.

How to train my own detector?
-----------------------------

ccv provides utilities to train your own object models. Specifically, for ICF, these
utilities are available at ./bin/icfcreate and ./bin/icfoptimize.
6 changes: 3 additions & 3 deletions lib/ccv.h
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ extern const ccv_dpm_param_t ccv_dpm_default_params;

void ccv_dpm_mixture_model_new(char** posfiles, ccv_rect_t* bboxes, int posnum, char** bgfiles, int bgnum, int negnum, const char* dir, ccv_dpm_new_param_t params);
ccv_array_t* __attribute__((warn_unused_result)) ccv_dpm_detect_objects(ccv_dense_matrix_t* a, ccv_dpm_mixture_model_t** model, int count, ccv_dpm_param_t params);
ccv_dpm_mixture_model_t* __attribute__((warn_unused_result)) ccv_load_dpm_mixture_model(const char* directory);
ccv_dpm_mixture_model_t* __attribute__((warn_unused_result)) ccv_dpm_read_mixture_model(const char* directory);
void ccv_dpm_mixture_model_free(ccv_dpm_mixture_model_t* model);

/* this is open source implementation of object detection algorithm: brightness binary feature
Expand Down Expand Up @@ -872,10 +872,10 @@ extern const ccv_bbf_param_t ccv_bbf_default_params;

void ccv_bbf_classifier_cascade_new(ccv_dense_matrix_t** posimg, int posnum, char** bgfiles, int bgnum, int negnum, ccv_size_t size, const char* dir, ccv_bbf_new_param_t params);
ccv_array_t* __attribute__((warn_unused_result)) ccv_bbf_detect_objects(ccv_dense_matrix_t* a, ccv_bbf_classifier_cascade_t** cascade, int count, ccv_bbf_param_t params);
ccv_bbf_classifier_cascade_t* __attribute__((warn_unused_result)) ccv_load_bbf_classifier_cascade(const char* directory);
ccv_bbf_classifier_cascade_t* __attribute__((warn_unused_result)) ccv_bbf_read_classifier_cascade(const char* directory);
void ccv_bbf_classifier_cascade_free(ccv_bbf_classifier_cascade_t* cascade);
ccv_bbf_classifier_cascade_t* __attribute__((warn_unused_result)) ccv_bbf_classifier_cascade_read_binary(char* s);
int ccv_bbf_classifier_cascade_write_binary(ccv_bbf_classifier_cascade_t* cascade, char* s, int slen);
void ccv_bbf_classifier_cascade_free(ccv_bbf_classifier_cascade_t* cascade);

/* Ferns classifier: this is a fern implementation that specifically used for TLD
* see: http://cvlab.epfl.ch/alumni/oezuysal/ferns.html for more about ferns */
Expand Down
2 changes: 1 addition & 1 deletion lib/ccv_bbf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1418,7 +1418,7 @@ ccv_array_t* ccv_bbf_detect_objects(ccv_dense_matrix_t* a, ccv_bbf_classifier_ca
return result_seq2;
}

ccv_bbf_classifier_cascade_t* ccv_load_bbf_classifier_cascade(const char* directory)
ccv_bbf_classifier_cascade_t* ccv_bbf_read_classifier_cascade(const char* directory)
{
char buf[1024];
sprintf(buf, "%s/cascade.txt", directory);
Expand Down
2 changes: 1 addition & 1 deletion lib/ccv_dpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2250,7 +2250,7 @@ ccv_array_t* ccv_dpm_detect_objects(ccv_dense_matrix_t* a, ccv_dpm_mixture_model
return result_seq2;
}

ccv_dpm_mixture_model_t* ccv_load_dpm_mixture_model(const char* directory)
ccv_dpm_mixture_model_t* ccv_dpm_read_mixture_model(const char* directory)
{
FILE* r = fopen(directory, "r");
if (r == 0)
Expand Down
2 changes: 1 addition & 1 deletion serve/bbf.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ void* uri_bbf_detect_objects_parse(const void* context, void* parsed, int resour
void* uri_bbf_detect_objects_init(void)
{
bbf_context_t* context = (bbf_context_t*)malloc(sizeof(bbf_context_t));
context->face = ccv_load_bbf_classifier_cascade("../samples/face");
context->face = ccv_bbf_read_classifier_cascade("../samples/face");
assert(context->face);
assert(param_parser_map_alphabet(param_map, sizeof(param_map) / sizeof(param_dispatch_t)) == 0);
context->desc = param_parser_map_http_body(param_map, sizeof(param_map) / sizeof(param_dispatch_t),
Expand Down
4 changes: 2 additions & 2 deletions serve/dpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ void* uri_dpm_detect_objects_parse(const void* context, void* parsed, int resour
void* uri_dpm_detect_objects_init(void)
{
dpm_context_t* context = (dpm_context_t*)malloc(sizeof(dpm_context_t));
context->pedestrian = ccv_load_dpm_mixture_model("../samples/pedestrian.m");
context->car = ccv_load_dpm_mixture_model("../samples/car.m");
context->pedestrian = ccv_dpm_read_mixture_model("../samples/pedestrian.m");
context->car = ccv_dpm_read_mixture_model("../samples/car.m");
assert(context->pedestrian && context->car);
assert(param_parser_map_alphabet(param_map, sizeof(param_map) / sizeof(param_dispatch_t)) == 0);
context->desc = param_parser_map_http_body(param_map, sizeof(param_map) / sizeof(param_dispatch_t),
Expand Down
Loading

0 comments on commit 5df1de1

Please sign in to comment.