diff --git a/conf/modules/cv_opticflow.xml b/conf/modules/cv_opticflow.xml index 5113ee0d89..a2cd0b37ae 100644 --- a/conf/modules/cv_opticflow.xml +++ b/conf/modules/cv_opticflow.xml @@ -13,18 +13,31 @@
- - - - - - + + + + + + +
+ +
+ + + + + + + + + +
- + - - + + @@ -32,6 +45,18 @@ + + + + + + + + + + + + diff --git a/sw/airborne/modules/computer_vision/opticflow/opticflow_calculator.c b/sw/airborne/modules/computer_vision/opticflow/opticflow_calculator.c index e4ff24095d..8e037fcee8 100644 --- a/sw/airborne/modules/computer_vision/opticflow/opticflow_calculator.c +++ b/sw/airborne/modules/computer_vision/opticflow/opticflow_calculator.c @@ -46,6 +46,47 @@ #define Fx_ARdrone 343.1211 #define Fy_ARdrone 348.5053 +/* Set the default values */ +#ifndef OPTICFLOW_MAX_TRACK_CORNERS +#define OPTICFLOW_MAX_TRACK_CORNERS 25 +#endif +PRINT_CONFIG_VAR(OPTICFLOW_MAX_TRACK_CORNERS); + +#ifndef OPTICFLOW_WINDOW_SIZE +#define OPTICFLOW_WINDOW_SIZE 10 +#endif +PRINT_CONFIG_VAR(OPTICFLOW_WINDOW_SIZE); + +#ifndef OPTICFLOW_SUBPIXEL_FACTOR +#define OPTICFLOW_SUBPIXEL_FACTOR 10 +#endif +PRINT_CONFIG_VAR(OPTICFLOW_SUBPIXEL_FACTOR); + +#ifndef OPTICFLOW_MAX_ITERATIONS +#define OPTICFLOW_MAX_ITERATIONS 10 +#endif +PRINT_CONFIG_VAR(OPTICFLOW_MAX_ITERATIONS); + +#ifndef OPTICFLOW_THRESHOLD_VEC +#define OPTICFLOW_THRESHOLD_VEC 2 +#endif +PRINT_CONFIG_VAR(OPTICFLOW_THRESHOLD_VEC); + +#ifndef OPTICFLOW_FAST9_ADAPTIVE +#define OPTICFLOW_FAST9_ADAPTIVE TRUE +#endif +PRINT_CONFIG_VAR(OPTICFLOW_FAST9_ADAPTIVE); + +#ifndef OPTICFLOW_FAST9_THRESHOLD +#define OPTICFLOW_FAST9_THRESHOLD 20 +#endif +PRINT_CONFIG_VAR(OPTICFLOW_FAST9_THRESHOLD); + +#ifndef OPTICFLOW_FAST9_MIN_DISTANCE +#define OPTICFLOW_FAST9_MIN_DISTANCE 10 +#endif +PRINT_CONFIG_VAR(OPTICFLOW_FAST9_MIN_DISTANCE); + /* Functions only used here */ static uint32_t timeval_diff(struct timeval *starttime, struct timeval *finishtime); static int cmp_flow(const void *a, const void *b); @@ -66,6 +107,17 @@ void opticflow_calc_init(struct opticflow_t *opticflow, uint16_t w, uint16_t h) opticflow->got_first_img = FALSE; opticflow->prev_phi = 0.0; opticflow->prev_theta = 0.0; + + /* Set the default values */ + opticflow->max_track_corners = OPTICFLOW_MAX_TRACK_CORNERS; + opticflow->window_size = OPTICFLOW_WINDOW_SIZE; + opticflow->subpixel_factor = OPTICFLOW_SUBPIXEL_FACTOR; + opticflow->max_iterations = OPTICFLOW_MAX_ITERATIONS; + opticflow->threshold_vec = OPTICFLOW_THRESHOLD_VEC; + + opticflow->fast9_adaptive = OPTICFLOW_FAST9_ADAPTIVE; + opticflow->fast9_threshold = OPTICFLOW_FAST9_THRESHOLD; + opticflow->fast9_min_distance = OPTICFLOW_FAST9_MIN_DISTANCE; } /** @@ -95,14 +147,18 @@ void opticflow_calc_frame(struct opticflow_t *opticflow, struct opticflow_state_ // ************************************************************************************* // FAST corner detection (TODO: non fixed threashold) - static uint8_t threshold = 20; - struct point_t *corners = fast9_detect(img, threshold, 10, 20, 20, &result->corner_cnt); + struct point_t *corners = fast9_detect(img, opticflow->fast9_threshold, opticflow->fast9_min_distance, + 20, 20, &result->corner_cnt); // Adaptive threshold - if(result->corner_cnt < 40 && threshold > 5) - threshold--; - else if(result->corner_cnt > 50 && threshold < 60) - threshold++; + if(opticflow->fast9_adaptive) { + + // Decrease and increase the threshold based on previous values + if(result->corner_cnt < 40 && opticflow->fast9_threshold > 5) + opticflow->fast9_threshold--; + else if(result->corner_cnt > 50 && opticflow->fast9_threshold < 60) + opticflow->fast9_threshold++; + } #if OPTICFLOW_DEBUG && OPTICFLOW_SHOW_CORNERS image_show_points(img, corners, result->corner_cnt); @@ -119,18 +175,14 @@ void opticflow_calc_frame(struct opticflow_t *opticflow, struct opticflow_state_ // Corner Tracking // ************************************************************************************* -#define MAX_TRACK_CORNERS 25 -#define HALF_WINDOW_SIZE 5 -#define SUBPIXEL_FACTOR 10 -#define MAX_ITERATIONS 10 -#define THRESHOLD_VEC 2 // Execute a Lucas Kanade optical flow result->tracked_cnt = result->corner_cnt; struct flow_t *vectors = opticFlowLK(&opticflow->img_gray, &opticflow->prev_img_gray, corners, &result->tracked_cnt, - HALF_WINDOW_SIZE, SUBPIXEL_FACTOR, MAX_ITERATIONS, THRESHOLD_VEC, MAX_TRACK_CORNERS); + opticflow->window_size/2, opticflow->subpixel_factor, opticflow->max_iterations, + opticflow->threshold_vec, opticflow->max_track_corners); #if OPTICFLOW_DEBUG && OPTICFLOW_SHOW_FLOW - image_show_flow(img, vectors, result->tracked_cnt, SUBPIXEL_FACTOR); + image_show_flow(img, vectors, result->tracked_cnt, opticflow->subpixel_factor); #endif // Get the median flow @@ -158,14 +210,14 @@ void opticflow_calc_frame(struct opticflow_t *opticflow, struct opticflow_state_ // Flow Derotation float diff_flow_x = (state->phi - opticflow->prev_phi) * img->w / FOV_W; float diff_flow_y = (state->theta - opticflow->prev_theta) * img->h / FOV_H; - result->flow_der_x = result->flow_x - diff_flow_x * SUBPIXEL_FACTOR; - result->flow_der_y = result->flow_y - diff_flow_y * SUBPIXEL_FACTOR; + result->flow_der_x = result->flow_x - diff_flow_x * opticflow->subpixel_factor; + result->flow_der_y = result->flow_y - diff_flow_y * opticflow->subpixel_factor; opticflow->prev_phi = state->phi; opticflow->prev_theta = state->theta; // Velocity calculation - result->vel_x = -result->flow_der_x * result->fps / SUBPIXEL_FACTOR * img->w / Fx_ARdrone; - result->vel_y = result->flow_der_y * result->fps / SUBPIXEL_FACTOR * img->h / Fy_ARdrone; + result->vel_x = -result->flow_der_x * result->fps / opticflow->subpixel_factor * img->w / Fx_ARdrone; + result->vel_y = result->flow_der_y * result->fps / opticflow->subpixel_factor * img->h / Fy_ARdrone; // ************************************************************************************* // Next Loop Preparation diff --git a/sw/airborne/modules/computer_vision/opticflow/opticflow_calculator.h b/sw/airborne/modules/computer_vision/opticflow/opticflow_calculator.h index f010fc8284..f30c0dc566 100644 --- a/sw/airborne/modules/computer_vision/opticflow/opticflow_calculator.h +++ b/sw/airborne/modules/computer_vision/opticflow/opticflow_calculator.h @@ -42,6 +42,16 @@ struct opticflow_t struct image_t img_gray; //< Current gray image frame struct image_t prev_img_gray; //< Previous gray image frame struct timeval prev_timestamp; //< Timestamp of the previous frame, used for FPS calculation + + uint8_t max_track_corners; //< Maximum amount of corners Lucas Kanade should track + uint16_t window_size; //< Window size of the Lucas Kanade calculation (needs to be even) + uint8_t subpixel_factor; //< The amount of subpixels per pixel + uint8_t max_iterations; //< The maximum amount of iterations the Lucas Kanade algorithm should do + uint8_t threshold_vec; //< The threshold in x, y subpixels which the algorithm should stop + + bool_t fast9_adaptive; //< Whether the FAST9 threshold should be adaptive + uint8_t fast9_threshold; //< FAST9 corner detection threshold + uint16_t fast9_min_distance; //< Minimum distance in pixels between corners }; diff --git a/sw/airborne/modules/computer_vision/opticflow_module.c b/sw/airborne/modules/computer_vision/opticflow_module.c index 92312b985f..b1071a5167 100644 --- a/sw/airborne/modules/computer_vision/opticflow_module.c +++ b/sw/airborne/modules/computer_vision/opticflow_module.c @@ -64,7 +64,7 @@ PRINT_CONFIG_MSG("OPTICFLOW_DEVICE_SIZE = " _SIZE_HELPER(OPTICFLOW_DEVICE_SIZE)) PRINT_CONFIG_VAR(VIEWVIDEO_DEVICE_BUFFERS); /* The main opticflow variables */ -static struct opticflow_t opticflow; //< Opticflow calculations +struct opticflow_t opticflow; //< Opticflow calculations static struct opticflow_result_t opticflow_result; //< The opticflow result static struct opticflow_state_t opticflow_state; //< State of the drone to communicate with the opticflow static struct v4l2_device *opticflow_dev; //< The opticflow camera V4L2 device diff --git a/sw/airborne/modules/computer_vision/opticflow_module.h b/sw/airborne/modules/computer_vision/opticflow_module.h index 5e583ce5a6..eb158cc83c 100644 --- a/sw/airborne/modules/computer_vision/opticflow_module.h +++ b/sw/airborne/modules/computer_vision/opticflow_module.h @@ -32,6 +32,9 @@ #include "opticflow/opticflow_calculator.h" #include "opticflow/stabilization_opticflow.h" +// Needed for settings +extern struct opticflow_t opticflow; + // Module functions extern void opticflow_module_init(void); extern void opticflow_module_run(void);