Skip to content

Commit

Permalink
fix a bug that gives me a weaker classifier in ICF
Browse files Browse the repository at this point in the history
Previously, we use the fast precomputed result to compute weak
classifier, however, the computation doesn't take into account that for
some features (especially lower-order features), examples may share the
same value.

This diff fixed his problem by precompute skip flag as well. Also,
introduced USE_SANITY_ASSERTION flag, with this flag, I can put more
sanity assertions that requires substantial computation there, for,
yeah, sanity check (which, helps uncover this problem BTW).
  • Loading branch information
liuliu committed Aug 22, 2013
1 parent d925ab3 commit a3c8fec
Show file tree
Hide file tree
Showing 7 changed files with 2,322 additions and 2,057 deletions.
9 changes: 6 additions & 3 deletions bin/icfcreate.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,20 +141,23 @@ int main(int argc, char** argv)
}
fclose(r2);
free(file);
params.grayscale = 0;
params.grayscale = 1;
params.margin = ccv_margin(5, 5, 5, 5);
params.size = ccv_size(20, 60);
params.min_dimension = 2;
params.deform_shift = 1;
params.deform_angle = 0;
params.deform_scale = 0.075;
params.feature_size = 50000;
params.weak_classifier = 2000;
params.acceptance = acceptance;
params.bootstrap = 3;
params.bootstrap = 4;
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);
ccv_icf_write_classifier_cascade(classifier, working_dir);
char filename[1024];
snprintf(filename, 1024, "%s/final-cascade", working_dir);
ccv_icf_write_classifier_cascade(classifier, filename);
for (i = 0; i < posfiles->rnum; i++)
{
ccv_file_info_t* file_info = (ccv_file_info_t*)ccv_array_get(posfiles, i);
Expand Down
66 changes: 66 additions & 0 deletions bin/icfdetect.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "ccv.h"
#include <sys/time.h>
#include <ctype.h>

unsigned int get_current_time()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}

int main(int argc, char** argv)
{
assert(argc >= 3);
int i;
ccv_enable_default_cache();
ccv_dense_matrix_t* image = 0;
ccv_icf_classifier_cascade_t* cascade = ccv_icf_read_classifier_cascade(argv[2]);
ccv_read(argv[1], &image, CCV_IO_ANY_FILE | CCV_IO_RGB_COLOR);
if (image != 0)
{
unsigned int elapsed_time = get_current_time();
ccv_array_t* seq = ccv_icf_detect_objects(image, &cascade, 1, ccv_icf_default_params);
elapsed_time = get_current_time() - elapsed_time;
for (i = 0; i < seq->rnum; i++)
{
ccv_comp_t* comp = (ccv_comp_t*)ccv_array_get(seq, i);
printf("%d %d %d %d %f\n", comp->rect.x, comp->rect.y, comp->rect.width, comp->rect.height, comp->confidence);
}
printf("total : %d in time %dms\n", seq->rnum, elapsed_time);
ccv_array_free(seq);
ccv_matrix_free(image);
} else {
FILE* r = fopen(argv[1], "rt");
if (argc == 4)
chdir(argv[3]);
if(r)
{
size_t len = 1024;
char* file = (char*)malloc(len);
ssize_t read;
while((read = getline(&file, &len, r)) != -1)
{
while(read > 1 && isspace(file[read - 1]))
read--;
file[read] = 0;
image = 0;
ccv_read(file, &image, CCV_IO_ANY_FILE | CCV_IO_RGB_COLOR);
assert(image != 0);
ccv_array_t* seq = ccv_icf_detect_objects(image, &cascade, 1, ccv_icf_default_params);
for (i = 0; i < seq->rnum; i++)
{
ccv_comp_t* comp = (ccv_comp_t*)ccv_array_get(seq, i);
printf("%s %d %d %d %d %f\n", file, comp->rect.x, comp->rect.y, comp->rect.width, comp->rect.height, comp->confidence);
}
ccv_array_free(seq);
ccv_matrix_free(image);
}
free(file);
fclose(r);
}
}
ccv_icf_classifier_cascade_free(cascade);
ccv_disable_cache();
return 0;
}
101 changes: 101 additions & 0 deletions bin/icfoptimize.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include "ccv.h"
#include <ctype.h>
#include <getopt.h>

void exit_with_help()
{
printf(
"\n \033[1mUSAGE\033[0m\n\n icfoptimize [OPTION...]\n\n"
);
exit(-1);
}

int main(int argc, char** argv)
{
static struct option icf_options[] = {
/* help */
{"help", 0, 0, 0},
/* required parameters */
{"positive-list", 1, 0, 0},
{"working-dir", 1, 0, 0},
{"acceptance", 1, 0, 0},
/* optional parameters */
{"base-dir", 1, 0, 0},
{0, 0, 0, 0}
};
char* positive_list = 0;
char* working_dir = 0;
char* base_dir = 0;
double acceptance = 0;
ccv_icf_param_t detector = { .min_neighbors = 0, .flags = 0, .threshold = 0.0 };
ccv_icf_new_param_t params = {
.detector = detector,
};
int i, k;
while (getopt_long_only(argc, argv, "", icf_options, &k) != -1)
{
switch (k)
{
case 0:
exit_with_help();
case 1:
positive_list = optarg;
break;
case 2:
working_dir = optarg;
break;
case 3:
acceptance = atof(optarg);
break;
case 4:
base_dir = optarg;
break;
}
}
assert(positive_list != 0);
assert(working_dir != 0);
ccv_enable_cache(512 * 1024 * 1024);
FILE* r0 = fopen(positive_list, "r");
assert(r0 && "positive-list doesn't exists");
char* file = (char*)malloc(1024);
ccv_decimal_pose_t pose;
ccv_array_t* posfiles = ccv_array_new(sizeof(ccv_file_info_t), 32, 0);
int dirlen = (base_dir != 0) ? strlen(base_dir) + 1 : 0;
// roll pitch yaw
while (fscanf(r0, "%s %f %f %f %f %f %f %f", file, &pose.x, &pose.y, &pose.a, &pose.b, &pose.roll, &pose.pitch, &pose.yaw) != EOF)
{
ccv_file_info_t file_info;
file_info.filename = (char*)ccmalloc(1024);
if (base_dir != 0)
{
strncpy(file_info.filename, base_dir, 1024);
file_info.filename[dirlen - 1] = '/';
}
strncpy(file_info.filename + dirlen, file, 1024 - dirlen);
// blow up pose a little bit for INRIA data (16px on four strides)
file_info.pose = pose;
ccv_array_push(posfiles, &file_info);
}
fclose(r0);
free(file);
params.grayscale = 0;
params.margin = ccv_margin(5, 5, 5, 5);
params.size = ccv_size(20, 60);
params.deform_shift = 0;
params.deform_angle = 0;
params.deform_scale = 0;
params.feature_size = 50000;
params.weak_classifier = 2000;
params.acceptance = acceptance;
ccv_icf_classifier_cascade_t* cascade = ccv_icf_read_classifier_cascade(working_dir);
ccv_icf_classifier_cascade_soft(cascade, posfiles, working_dir, params);
ccv_icf_write_classifier_cascade(cascade, working_dir);
for (i = 0; i < posfiles->rnum; i++)
{
ccv_file_info_t* file_info = (ccv_file_info_t*)ccv_array_get(posfiles, i);
free(file_info->filename);
}
ccv_array_free(posfiles);
ccv_disable_cache();
return 0;
}
1 change: 0 additions & 1 deletion lib/ccv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1014,7 +1014,6 @@ typedef struct {
int count;
int grayscale;
ccv_margin_t margin;
double a, b; // scale the result, with a * (confidence + b)
ccv_size_t size; // this is the size includes the margin
ccv_icf_decision_tree_t* weak_classifiers;
} ccv_icf_classifier_cascade_t; // Type A, scale image
Expand Down
Loading

0 comments on commit a3c8fec

Please sign in to comment.