From 3cfead3f969e94b4d487f6a0b329b66834e08d1f Mon Sep 17 00:00:00 2001 From: Liu Liu Date: Mon, 18 Jun 2012 01:18:54 -0400 Subject: [PATCH] continue tune some parameters for release --- .gitignore | 1 + bin/dpmcreate.c | 14 +++++++------- bin/dpmdetect.c | 2 +- bin/dpmvldtr.rb | 2 +- doc/bbf.md | 2 +- doc/dpm.md | 31 +++++++++++++++++++++++++++---- lib/ccv_dpm.c | 8 ++++---- 7 files changed, 42 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index cab434ee2..124ee6f6b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.swp tags gh-pages +site *.tests test/*_test test/*.jpg diff --git a/bin/dpmcreate.c b/bin/dpmcreate.c index 6d4dc60dd..c90796a88 100644 --- a/bin/dpmcreate.c +++ b/bin/dpmcreate.c @@ -17,12 +17,12 @@ void exit_with_help() "\t--symmetric : 0 or 1, whether to exploit symmetric property of the object\n\n" "\033[1mOTHER OPTIONS\033[0m\n" "\t--base-dir : change the base directory so that the program can read images from there\n" - "\t--iterations : how many iterations needed for stochastic gradient descent [DEFAULT TO 10]\n" + "\t--iterations : how many iterations needed for stochastic gradient descent [DEFAULT TO 15]\n" "\t--relabels : how many relabel procedure needed [DEFAULT TO 5]\n" "\t--alpha : the step size for stochastic gradient descent [DEFAULT TO 0.1]\n" - "\t--alpha-ratio : decrease the step size for each iteration [DEFAULT TO 0.85]\n" + "\t--alpha-ratio : decrease the step size for each iteration [DEFAULT TO 0.9]\n" "\t--margin-c : the famous C in SVM [DEFAULT TO 0.002]\n" - "\t--balance : to balance the weight of positive examples and negative examples [DEFAULT TO 1.75]\n" + "\t--balance : to balance the weight of positive examples and negative examples [DEFAULT TO 1.5]\n" "\t--negative-cache-size : the cache size for negative examples it should be smaller than negative-count and larger than 100 [DEFAULT TO 1000]\n" "\t--include-overlap : the percentage of overlap between expected bounding box and the bounding box from detection. Beyond this threshold, it is ensured to be the same object [DEFAULT TO 0.7]\n" "\t--exclude-overlap : the percentage of overlap between expected bounding box and the bounding box from detection. Below this threshold, it is ensured to not be the same object [DEFAULT TO 0.5]\n" @@ -73,9 +73,9 @@ int main(int argc, char** argv) .max_area = 5000, .symmetric = 1, .alpha = 0.1, - .balance = 1.75, - .alpha_ratio = 0.85, - .iterations = 10, + .balance = 1.5, + .alpha_ratio = 0.9, + .iterations = 15, .relabels = 5, .negative_cache_size = 1000, .C = 0.002, @@ -217,7 +217,7 @@ int main(int argc, char** argv) free(posfiles[i]); ccfree(posfiles); ccfree(bboxes); - for (i = 0; i < posnum; i++) + for (i = 0; i < bgnum; i++) free(bgfiles[i]); ccfree(bgfiles); ccv_disable_cache(); diff --git a/bin/dpmdetect.c b/bin/dpmdetect.c index 7b5124f81..76909ed8d 100644 --- a/bin/dpmdetect.c +++ b/bin/dpmdetect.c @@ -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.5 }; + ccv_dpm_param_t params = { .interval = 8, .min_neighbors = 1, .flags = 0, .threshold = -0.3 }; if (image != 0) { unsigned int elapsed_time = get_current_time(); diff --git a/bin/dpmvldtr.rb b/bin/dpmvldtr.rb index c78671ee8..bddd154ec 100755 --- a/bin/dpmvldtr.rb +++ b/bin/dpmvldtr.rb @@ -44,7 +44,7 @@ opx_max = [obj[:x] + obj[:width], x + width].min opy_max = [obj[:y] + obj[:height], y + height].min r0 = [opx_max - opx_min, 0].max * [opy_max - opy_min, 0].max - r1 = obj[:width] * obj[:height] * 0.5 + r1 = obj[:width] * obj[:height] * 0.6 if r0 > r1 outlier = false break diff --git a/doc/bbf.md b/doc/bbf.md index 1634091aa..2c4a77dd9 100644 --- a/doc/bbf.md +++ b/doc/bbf.md @@ -78,7 +78,7 @@ information, for me, it is: Suppose you have copied the ground truth to truth.txt file, run the validator: - ./validator.rb truth.txt result.txt + ./bbfvldr.rb truth.txt result.txt My result for bbfdetect is: diff --git a/doc/dpm.md b/doc/dpm.md index 4afb70e4e..688d5bafd 100644 --- a/doc/dpm.md +++ b/doc/dpm.md @@ -22,10 +22,33 @@ Checkout output.png, see what happens? What about performance? ----------------------- -DPM is not known for its speed. Its ability to identify difficult objects, that's -the winning point. However, this implementation tries to optimize for speed as -well. For a 640x480 photo, this mplementation will be done in about one seconds, -no multi-threading cheat. +DPM is not known for its speed. Its ability to identify difficult objects, is +the selling point. However, this implementation tries to optimize for speed as +well. For a 640x480 photo, this implementation will be done in about one second, +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: + + 65.7% (156) + +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) + +Our implementation? + + 80.14% (74) + +Looks pretty good! + +Speed-wise: + + How to train my own detector? ----------------------------- diff --git a/lib/ccv_dpm.c b/lib/ccv_dpm.c index 9631954d6..8ad6c161d 100644 --- a/lib/ccv_dpm.c +++ b/lib/ccv_dpm.c @@ -773,8 +773,8 @@ static ccv_dpm_feature_vector_t* _ccv_dpm_collect_best(ccv_dense_matrix_t* image for (j = next; j < scale_upto + next * 2; j++) { ccv_size_t size = ccv_size((int)(root_classifier->root.w->cols * CCV_DPM_WINDOW_SIZE * scale_x + 0.5), (int)(root_classifier->root.w->rows * CCV_DPM_WINDOW_SIZE * scale_y + 0.5)); - if ((double)(size.width * size.height) / (double)(bbox.width * bbox.height) < overlap || - (double)(bbox.width * bbox.height) / (double)(size.width * size.height) < overlap) + if (ccv_min((double)(size.width * size.height), (double)(bbox.width * bbox.height)) / + ccv_max((double)(bbox.width * bbox.height), (double)(size.width * size.height)) < overlap) { scale_x *= scale; scale_y *= scale; @@ -795,7 +795,7 @@ static ccv_dpm_feature_vector_t* _ccv_dpm_collect_best(ccv_dense_matrix_t* image ccv_rect_t rect = ccv_rect((int)((x - rww) * CCV_DPM_WINDOW_SIZE * scale_x + 0.5), (int)((y - rwh) * CCV_DPM_WINDOW_SIZE * scale_y + 0.5), (int)(root_classifier->root.w->cols * CCV_DPM_WINDOW_SIZE * scale_x + 0.5), (int)(root_classifier->root.w->rows * CCV_DPM_WINDOW_SIZE * scale_y + 0.5)); if ((double)(ccv_max(0, ccv_min(rect.x + rect.width, bbox.x + bbox.width) - ccv_max(rect.x, bbox.x)) * ccv_max(0, ccv_min(rect.y + rect.height, bbox.y + bbox.height) - ccv_max(rect.y, bbox.y))) / - (double)ccv_min(rect.width * rect.height, bbox.width * bbox.height) >= overlap && f_ptr[x] > best) + (double)ccv_max(rect.width * rect.height, bbox.width * bbox.height) >= overlap && f_ptr[x] > best) { // initialize v if (v == 0) @@ -870,7 +870,7 @@ static ccv_array_t* _ccv_dpm_collect_all(gsl_rng* rng, ccv_dense_matrix_t* image for (k = 0; k < bnum; k++) if ((double)(ccv_max(0, ccv_min(rect.x + rect.width, bboxes[k].x + bboxes[k].width) - ccv_max(rect.x, bboxes[k].x)) * ccv_max(0, ccv_min(rect.y + rect.height, bboxes[k].y + bboxes[k].height) - ccv_max(rect.y, bboxes[k].y))) / - (double)ccv_min(rect.width * rect.height, bboxes[k].width * bboxes[k].height) >= overlap) + (double)ccv_max(rect.width * rect.height, bboxes[k].width * bboxes[k].height) >= overlap) { flag = 1; break;