Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2011-10-13 21:54:05 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2011-10-13 21:54:05 +0400
commit594e9e0689b773af852a17353010d26024485937 (patch)
tree3d45d862dc25d1ccf2b23457cbc027046036111f
parent1d27e1c849f5198b18984cfc1bdc9562ec2f9c33 (diff)
Camera tracking integration
=========================== Added option to choose which method to use for feature detector: FAST or Moravec Moravec was supposed to be more "stable", but it collected worse feedback. before returning back to FAST detector added option to easier toggle between different detector to compare it's result and find out if we can leave only FAST.
-rw-r--r--extern/libmv/libmv-capi.cpp61
-rw-r--r--extern/libmv/libmv-capi.h4
-rw-r--r--extern/libmv/libmv/simple_pipeline/detect.cc50
-rw-r--r--extern/libmv/libmv/simple_pipeline/detect.h43
-rw-r--r--extern/libmv/patches/detect.patch151
-rw-r--r--extern/libmv/patches/series1
-rw-r--r--source/blender/blenkernel/BKE_tracking.h2
-rw-r--r--source/blender/blenkernel/intern/tracking.c8
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c39
9 files changed, 330 insertions, 29 deletions
diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp
index 8bf27ac0656..863e16515df 100644
--- a/extern/libmv/libmv-capi.cpp
+++ b/extern/libmv/libmv-capi.cpp
@@ -502,11 +502,13 @@ void libmv_destroyReconstruction(libmv_Reconstruction *libmv_reconstruction)
/* ************ feature detector ************ */
-struct libmv_Features *libmv_detectFeatures(unsigned char *data, int width, int height, int stride,
- int margin, int count, int min_distance)
+struct libmv_Features *libmv_detectFeaturesFAST(unsigned char *data, int width, int height, int stride,
+ int margin, int min_trackness, int min_distance)
{
- libmv::Feature *features = new libmv::Feature[count];
- libmv_Features *libmv_features = new libmv_Features;
+ libmv::Feature *features = NULL;
+ std::vector<libmv::Feature> v;
+ libmv_Features *libmv_features = new libmv_Features();
+ int i= 0, count;
if(margin) {
data += margin*stride+margin;
@@ -514,13 +516,47 @@ struct libmv_Features *libmv_detectFeatures(unsigned char *data, int width, int
height -= 2*margin;
}
- libmv::Detect(data, stride, width, height, features, &count, min_distance, NULL);
+ v = libmv::DetectFAST(data, width, height, stride, min_trackness, min_distance);
+
+ count = v.size();
+
+ if(count) {
+ features= new libmv::Feature[count];
+
+ for(std::vector<libmv::Feature>::iterator it = v.begin(); it != v.end(); it++) {
+ features[i++]= *it;
+ }
+ }
- libmv_features->count= count;
- libmv_features->margin= margin;
- libmv_features->features= features;
+ libmv_features->features = features;
+ libmv_features->count = count;
+ libmv_features->margin = margin;
- return libmv_features ;
+ return (libmv_Features *)libmv_features;
+}
+
+struct libmv_Features *libmv_detectFeaturesMORAVEC(unsigned char *data, int width, int height, int stride,
+ int margin, int count, int min_distance)
+{
+ libmv::Feature *features = NULL;
+ libmv_Features *libmv_features = new libmv_Features;
+
+ if(count) {
+ if(margin) {
+ data += margin*stride+margin;
+ width -= 2*margin;
+ height -= 2*margin;
+ }
+
+ features = new libmv::Feature[count];
+ libmv::DetectMORAVEC(data, stride, width, height, features, &count, min_distance, NULL);
+ }
+
+ libmv_features->count = count;
+ libmv_features->margin = margin;
+ libmv_features->features = features;
+
+ return libmv_features;
}
int libmv_countFeatures(struct libmv_Features *libmv_features)
@@ -530,7 +566,7 @@ int libmv_countFeatures(struct libmv_Features *libmv_features)
void libmv_getFeature(struct libmv_Features *libmv_features, int number, double *x, double *y, double *score, double *size)
{
- libmv::Feature feature = libmv_features->features[number];
+ libmv::Feature feature= libmv_features->features[number];
*x = feature.x + libmv_features->margin;
*y = feature.y + libmv_features->margin;
@@ -540,7 +576,10 @@ void libmv_getFeature(struct libmv_Features *libmv_features, int number, double
void libmv_destroyFeatures(struct libmv_Features *libmv_features)
{
- delete (libmv::Feature *)libmv_features;
+ if(libmv_features->features)
+ delete [] libmv_features->features;
+
+ delete libmv_features;
}
/* ************ camera intrinsics ************ */
diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h
index 8f2a57748b2..d77e9ac62fa 100644
--- a/extern/libmv/libmv-capi.h
+++ b/extern/libmv/libmv-capi.h
@@ -72,7 +72,9 @@ double libmv_reprojectionError(struct libmv_Reconstruction *libmv_reconstruction
void libmv_destroyReconstruction(struct libmv_Reconstruction *libmv_reconstruction);
/* feature detector */
-struct libmv_Features *libmv_detectFeatures(unsigned char *data, int width, int height, int stride,
+struct libmv_Features *libmv_detectFeaturesFAST(unsigned char *data, int width, int height, int stride,
+ int margin, int min_trackness, int min_distance);
+struct libmv_Features *libmv_detectFeaturesMORAVEC(unsigned char *data, int width, int height, int stride,
int margin, int count, int min_distance);
int libmv_countFeatures(struct libmv_Features *libmv_features);
void libmv_getFeature(struct libmv_Features *libmv_features, int number, double *x, double *y, double *score, double *size);
diff --git a/extern/libmv/libmv/simple_pipeline/detect.cc b/extern/libmv/libmv/simple_pipeline/detect.cc
index 6fc0cdd120a..b316f427649 100644
--- a/extern/libmv/libmv/simple_pipeline/detect.cc
+++ b/extern/libmv/libmv/simple_pipeline/detect.cc
@@ -23,15 +23,59 @@
****************************************************************************/
#include "libmv/simple_pipeline/detect.h"
+#include <third_party/fast/fast.h>
#include <stdlib.h>
-#include <string.h>
+#include <memory.h>
+
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
namespace libmv {
typedef unsigned int uint;
+std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height, int stride,
+ int min_trackness, int min_distance) {
+ std::vector<Feature> features;
+ // TODO(MatthiasF): Support targetting a feature count (binary search trackness)
+ int num_features;
+ xy* all = fast9_detect(data, width, height,
+ stride, min_trackness, &num_features);
+ if(num_features == 0) {
+ free(all);
+ return features;
+ }
+ int* scores = fast9_score(data, stride, all, num_features, min_trackness);
+ // TODO: merge with close feature suppression
+ xy* nonmax = nonmax_suppression(all, scores, num_features, &num_features);
+ free(all);
+ // Remove too close features
+ // TODO(MatthiasF): A resolution independent parameter would be better than distance
+ // e.g. a coefficient going from 0 (no minimal distance) to 1 (optimal circle packing)
+ // FIXME(MatthiasF): this method will not necessarily give all maximum markers
+ if(num_features) features.reserve(num_features);
+ for(int i = 0; i < num_features; ++i) {
+ xy xy = nonmax[i];
+ Feature a = { xy.x, xy.y, scores[i], 7 };
+ // compare each feature against filtered set
+ for(int j = 0; j < features.size(); j++) {
+ Feature& b = features[j];
+ if ( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) < min_distance*min_distance ) {
+ // already a nearby feature
+ goto skip;
+ }
+ }
+ // otherwise add the new feature
+ features.push_back(a);
+ skip: ;
+ }
+ free(scores);
+ free(nonmax);
+ return features;
+}
+
#ifdef __SSE2__
-#include <emmintrin.h>
static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strideB) {
__m128i a = _mm_setzero_si128();
for(int i = 0; i < 16; i++) {
@@ -52,7 +96,7 @@ static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strid
}
#endif
-void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) {
+void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) {
unsigned short histogram[256];
memset(histogram,0,sizeof(histogram));
ubyte* scores = new ubyte[width*height];
diff --git a/extern/libmv/libmv/simple_pipeline/detect.h b/extern/libmv/libmv/simple_pipeline/detect.h
index 23b239b81d6..bbe7aed784c 100644
--- a/extern/libmv/libmv/simple_pipeline/detect.h
+++ b/extern/libmv/libmv/simple_pipeline/detect.h
@@ -25,27 +25,52 @@
#ifndef LIBMV_SIMPLE_PIPELINE_DETECT_H_
#define LIBMV_SIMPLE_PIPELINE_DETECT_H_
-#ifdef __cplusplus
+#include <vector>
+
namespace libmv {
-#endif
typedef unsigned char ubyte;
/*!
- \a Feature is the 2D location of a detected feature in an image.
+ A Feature is the 2D location of a detected feature in an image.
- \a x, \a y is the position of the center in pixels (from image top-left).
- \a score is an estimate of how well the pattern will be tracked.
- \a size can be used as an initial size to track the pattern.
+ \a x, \a y is the position of the feature in pixels from the top left corner.
+ \a score is an estimate of how well the feature will be tracked.
+ \a size can be used as an initial pattern size to track the feature.
\sa Detect
*/
struct Feature {
+ /// Position in pixels (from top-left corner)
+ /// \note libmv might eventually support subpixel precision.
float x, y;
+ /// Trackness of the feature
float score;
+ /// Size of the feature in pixels
float size;
};
- //radius for non maximal suppression
+
+/*!
+ Detect features in an image.
+
+ You need to input a single channel 8-bit image using pointer to image \a data,
+ \a width, \a height and \a stride (i.e bytes per line).
+
+ You can tweak the count of detected features using \a min_trackness, which is
+ the minimum score to add a feature, and \a min_distance which is the minimal
+ distance accepted between two featuress.
+
+ \note You can binary search over \a min_trackness to get a given feature count.
+
+ \note a way to get an uniform distribution of a given feature count is:
+ \a min_distance = \a width * \a height / desired_feature_count ^ 2
+
+ \return All detected feartures matching given parameters
+*/
+std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height,
+ int stride, int min_trackness = 128,
+ int min_distance = 120);
+
/*!
Detect features in an image.
@@ -63,10 +88,8 @@ struct Feature {
\note \a You can crop the image (to avoid detecting markers near the borders) without copying:
image += marginY*stride+marginX, width -= 2*marginX, height -= 2*marginY;
*/
-void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/);
+void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/);
-#ifdef __cplusplus
}
-#endif
#endif
diff --git a/extern/libmv/patches/detect.patch b/extern/libmv/patches/detect.patch
new file mode 100644
index 00000000000..0d9b88faa96
--- /dev/null
+++ b/extern/libmv/patches/detect.patch
@@ -0,0 +1,151 @@
+diff --git a/src/libmv/simple_pipeline/detect.cc b/src/libmv/simple_pipeline/detect.cc
+index 6fc0cdd..b316f42 100644
+--- a/src/libmv/simple_pipeline/detect.cc
++++ b/src/libmv/simple_pipeline/detect.cc
+@@ -23,15 +23,59 @@
+ ****************************************************************************/
+
+ #include "libmv/simple_pipeline/detect.h"
++#include <third_party/fast/fast.h>
+ #include <stdlib.h>
+-#include <string.h>
++#include <memory.h>
++
++#ifdef __SSE2__
++#include <emmintrin.h>
++#endif
+
+ namespace libmv {
+
+ typedef unsigned int uint;
+
++std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height, int stride,
++ int min_trackness, int min_distance) {
++ std::vector<Feature> features;
++ // TODO(MatthiasF): Support targetting a feature count (binary search trackness)
++ int num_features;
++ xy* all = fast9_detect(data, width, height,
++ stride, min_trackness, &num_features);
++ if(num_features == 0) {
++ free(all);
++ return features;
++ }
++ int* scores = fast9_score(data, stride, all, num_features, min_trackness);
++ // TODO: merge with close feature suppression
++ xy* nonmax = nonmax_suppression(all, scores, num_features, &num_features);
++ free(all);
++ // Remove too close features
++ // TODO(MatthiasF): A resolution independent parameter would be better than distance
++ // e.g. a coefficient going from 0 (no minimal distance) to 1 (optimal circle packing)
++ // FIXME(MatthiasF): this method will not necessarily give all maximum markers
++ if(num_features) features.reserve(num_features);
++ for(int i = 0; i < num_features; ++i) {
++ xy xy = nonmax[i];
++ Feature a = { xy.x, xy.y, scores[i], 7 };
++ // compare each feature against filtered set
++ for(int j = 0; j < features.size(); j++) {
++ Feature& b = features[j];
++ if ( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) < min_distance*min_distance ) {
++ // already a nearby feature
++ goto skip;
++ }
++ }
++ // otherwise add the new feature
++ features.push_back(a);
++ skip: ;
++ }
++ free(scores);
++ free(nonmax);
++ return features;
++}
++
+ #ifdef __SSE2__
+-#include <emmintrin.h>
+ static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strideB) {
+ __m128i a = _mm_setzero_si128();
+ for(int i = 0; i < 16; i++) {
+@@ -52,7 +96,7 @@ static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strid
+ }
+ #endif
+
+-void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) {
++void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) {
+ unsigned short histogram[256];
+ memset(histogram,0,sizeof(histogram));
+ ubyte* scores = new ubyte[width*height];
+diff --git a/src/libmv/simple_pipeline/detect.h b/src/libmv/simple_pipeline/detect.h
+index 23b239b..bbe7aed 100644
+--- a/src/libmv/simple_pipeline/detect.h
++++ b/src/libmv/simple_pipeline/detect.h
+@@ -25,27 +25,52 @@
+ #ifndef LIBMV_SIMPLE_PIPELINE_DETECT_H_
+ #define LIBMV_SIMPLE_PIPELINE_DETECT_H_
+
+-#ifdef __cplusplus
++#include <vector>
++
+ namespace libmv {
+-#endif
+
+ typedef unsigned char ubyte;
+
+ /*!
+- \a Feature is the 2D location of a detected feature in an image.
++ A Feature is the 2D location of a detected feature in an image.
+
+- \a x, \a y is the position of the center in pixels (from image top-left).
+- \a score is an estimate of how well the pattern will be tracked.
+- \a size can be used as an initial size to track the pattern.
++ \a x, \a y is the position of the feature in pixels from the top left corner.
++ \a score is an estimate of how well the feature will be tracked.
++ \a size can be used as an initial pattern size to track the feature.
+
+ \sa Detect
+ */
+ struct Feature {
++ /// Position in pixels (from top-left corner)
++ /// \note libmv might eventually support subpixel precision.
+ float x, y;
++ /// Trackness of the feature
+ float score;
++ /// Size of the feature in pixels
+ float size;
+ };
+- //radius for non maximal suppression
++
++/*!
++ Detect features in an image.
++
++ You need to input a single channel 8-bit image using pointer to image \a data,
++ \a width, \a height and \a stride (i.e bytes per line).
++
++ You can tweak the count of detected features using \a min_trackness, which is
++ the minimum score to add a feature, and \a min_distance which is the minimal
++ distance accepted between two featuress.
++
++ \note You can binary search over \a min_trackness to get a given feature count.
++
++ \note a way to get an uniform distribution of a given feature count is:
++ \a min_distance = \a width * \a height / desired_feature_count ^ 2
++
++ \return All detected feartures matching given parameters
++*/
++std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height,
++ int stride, int min_trackness = 128,
++ int min_distance = 120);
++
+ /*!
+ Detect features in an image.
+
+@@ -63,10 +88,8 @@ struct Feature {
+ \note \a You can crop the image (to avoid detecting markers near the borders) without copying:
+ image += marginY*stride+marginX, width -= 2*marginX, height -= 2*marginY;
+ */
+-void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/);
++void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/);
+
+-#ifdef __cplusplus
+ }
+-#endif
+
+ #endif
diff --git a/extern/libmv/patches/series b/extern/libmv/patches/series
index 410a14ca135..00a52c1cfaa 100644
--- a/extern/libmv/patches/series
+++ b/extern/libmv/patches/series
@@ -10,3 +10,4 @@ mingw.patch
msvc2010.patch
scaled_distortion.patch
overscan.patch
+detect.patch
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index 84e2acfb147..0e29bb44181 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -87,7 +87,7 @@ void BKE_tracking_projection_matrix(struct MovieTracking *tracking, int framenr,
void BKE_tracking_apply_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]);
void BKE_tracking_invert_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]);
-void BKE_tracking_detect(struct MovieTracking *tracking, struct ImBuf *imbuf, int framenr, int margin, int count, int min_distance);
+void BKE_tracking_detect(struct MovieTracking *tracking, struct ImBuf *imbuf, int framenr, int margin, int min_trackness, int count, int min_distance, int fast);
struct MovieTrackingTrack *BKE_tracking_indexed_bundle(struct MovieTracking *tracking, int bundlenr);
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 9ad7b963447..9f5478df0b1 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -1526,14 +1526,18 @@ static unsigned char *acquire_ucharbuf(ImBuf *ibuf)
}
#endif
-void BKE_tracking_detect(MovieTracking *tracking, ImBuf *ibuf, int framenr, int margin, int count, int min_distance)
+void BKE_tracking_detect(MovieTracking *tracking, ImBuf *ibuf, int framenr, int margin, int min_trackness, int count, int min_distance, int fast)
{
#ifdef WITH_LIBMV
struct libmv_Features *features;
unsigned char *pixels= acquire_ucharbuf(ibuf);
int a;
- features= libmv_detectFeatures(pixels, ibuf->x, ibuf->y, ibuf->x, margin, count, min_distance);
+ if(fast)
+ features= libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x, margin, min_trackness, min_distance);
+ else
+ features= libmv_detectFeaturesMORAVEC(pixels, ibuf->x, ibuf->y, ibuf->x, margin, count, min_distance);
+
MEM_freeN(pixels);
a= libmv_countFeatures(features);
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 1651d4cea7e..3a559bbf935 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -2214,7 +2214,9 @@ static int detect_features_exec(bContext *C, wmOperator *op)
MovieClip *clip= ED_space_clip(sc);
ImBuf *ibuf= BKE_movieclip_acquire_ibuf_flag(clip, &sc->user, 0);
MovieTrackingTrack *track= clip->tracking.tracks.first;
+ int detector= RNA_enum_get(op->ptr, "detector");
int margin= RNA_int_get(op->ptr, "margin");
+ int min_trackness= RNA_int_get(op->ptr, "min_trackness");
int count= RNA_int_get(op->ptr, "count");
int min_distance= RNA_int_get(op->ptr, "min_distance");
@@ -2227,7 +2229,7 @@ static int detect_features_exec(bContext *C, wmOperator *op)
track= track->next;
}
- BKE_tracking_detect(&clip->tracking, ibuf, sc->user.framenr, margin, count, min_distance);
+ BKE_tracking_detect(&clip->tracking, ibuf, sc->user.framenr, margin, min_trackness, count, min_distance, detector==0);
IMB_freeImBuf(ibuf);
@@ -2236,8 +2238,40 @@ static int detect_features_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static void detect_features_draw(bContext *C, wmOperator *op)
+{
+ uiLayout *layout = op->layout;
+ wmWindowManager *wm= CTX_wm_manager(C);
+ PointerRNA ptr;
+ int detector= RNA_enum_get(op->ptr, "detector");
+ PropertyRNA *prop_min_trackness;
+ PropertyRNA *prop_count;
+
+ prop_min_trackness= RNA_struct_find_property(op->ptr, "min_trackness");
+ prop_count= RNA_struct_find_property(op->ptr, "count");
+
+ if(detector==0) {
+ RNA_def_property_clear_flag(prop_min_trackness, PROP_HIDDEN);
+ RNA_def_property_flag(prop_count, PROP_HIDDEN);
+ } else {
+ RNA_def_property_flag(prop_min_trackness, PROP_HIDDEN);
+ RNA_def_property_clear_flag(prop_count, PROP_HIDDEN);
+ }
+
+ RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
+
+ /* main draw call */
+ uiDefAutoButsRNA(layout, &ptr, NULL, 'V');
+}
+
void CLIP_OT_detect_features(wmOperatorType *ot)
{
+ static EnumPropertyItem detector_items[] = {
+ {0, "FAST", 0, "FAST", "FAST corner detector"},
+ {1, "MORAVEC", 0, "Moravec", "Moravec corner detector"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
/* identifiers */
ot->name= "Detect Features";
ot->description= "Automatically detect features to track";
@@ -2246,12 +2280,15 @@ void CLIP_OT_detect_features(wmOperatorType *ot)
/* api callbacks */
ot->exec= detect_features_exec;
ot->poll= space_clip_frame_poll;
+ ot->ui= detect_features_draw;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
+ RNA_def_enum(ot->srna, "detector", detector_items, 0, "Detector", "Detector using for detecting features");
RNA_def_int(ot->srna, "margin", 16, 0, INT_MAX, "Margin", "Only corners further than margin pixels from the image edges are considered", 0, 300);
+ RNA_def_int(ot->srna, "min_trackness", 16, 0, INT_MAX, "Trackness", "Minimum score to add a corner", 0, 300);
RNA_def_int(ot->srna, "count", 50, 1, INT_MAX, "Count", "Count of corners to detect", 0, 300);
RNA_def_int(ot->srna, "min_distance", 120, 0, INT_MAX, "Distance", "Minimal distance accepted between two corners", 0, 300);
}