Paparazzi UAS  v5.14.0_stable-0-g3f680d1
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
act_fast.c
Go to the documentation of this file.
1 /*
2 Copyright (c) 2017, Guido de Croon, TU Delft
3 All rights reserved.
4 */
5 
6 
26 #include "fast_rosten.h"
27 #include "act_fast.h"
28 #include "math.h"
29 #include "image.h"
30 
31 
32 #define MAX_AGENTS 1000
34 
48 void act_fast(struct image_t *img, uint8_t fast_threshold, uint16_t *num_corners, struct point_t **ret_corners,
49  uint16_t n_agents, uint16_t n_time_steps, float long_step, float short_step, int min_gradient, int gradient_method)
50 {
51 
52  /*
53  * Procedure:
54  * 1) initialize agent positions
55  * 2) loop over the agents, moving and checking for corners
56  */
57 
58  // ensure that n_agents is never bigger than MAX_AGENTS
59  n_agents = (n_agents < MAX_AGENTS) ? n_agents : MAX_AGENTS;
60 
61  int border = 4;
62 
63  // ***********************************
64  // 1) initialize the agents' positions
65  // ***********************************
66 
67  // grid sampling with a border:
68  int init_border = 10;
69  float GRID_ROWS = (int) ceil(sqrtf((float) n_agents));
70  float step_size_x = (img->w - 2 * init_border) / (GRID_ROWS - 1);
71  float step_size_y = (img->h - 2 * init_border) / (GRID_ROWS - 1);
72 
73  int a = 0;
74  float px, py, pnorm;
75  for (int c = 0; c < GRID_ROWS; c++) {
76  for (int r = 0; r < GRID_ROWS; r++) {
77  // px, py represent the preferred direction of the agent when there is no texture
78  // here we initialize it differently for each agent:
79  // TODO: don't we have a randf function in Paparazzi?
80  px = ((float)(rand() % 10000)) / 10000.0f;
81  py = ((float)(rand() % 10000)) / 10000.0f;
82  pnorm = sqrtf(px * px + py * py);
83  struct agent_t ag = { (border + c * step_size_x), (border + r * step_size_y), 1, px / pnorm, py / pnorm};
84  agents[a] = ag;
85  a++;
86  if (a == n_agents) { break; }
87  }
88 
89  // only initialize a maximum of n_agents agents.
90  if (a == n_agents) { break; }
91  }
92 
93  /* ********************************************************
94  * 2) loop over the agents, moving and checking for corners
95  * ********************************************************/
96 
97  // gradient
98  int dx, dy;
99 
100  // loop over all time steps:
101  for (int t = 0; t < n_time_steps; t++) {
102  // loop over the agents
103  for (a = 0; a < n_agents; a++) {
104  // only do something if the agent is active:
105  if (agents[a].active) {
106  // check if this position is a corner:
107  uint16_t x = (uint16_t) agents[a].x;
108  uint16_t y = (uint16_t) agents[a].y;
109  if (fast9_detect_pixel(img, fast_threshold, x, y)) {
110  // we arrived at a corner, yeah!!!
111  agents[a].active = 0;
112  break;
113  } else {
114  // make a step:
115  struct point_t loc = { .x = agents[a].x, .y = agents[a].y};
116  image_gradient_pixel(img, &loc, gradient_method, &dx, &dy);
117  int gradient = (abs(dx) + abs(dy)) / 2;
118  if (abs(gradient) >= min_gradient) {
119  // determine the angle and make a step in that direction:
120  float norm_factor = sqrtf((float)(dx * dx + dy * dy));
121  agents[a].x += (dy / norm_factor) * short_step;
122  agents[a].y += (dx / norm_factor) * short_step;
123  } else {
124  // make a step in the preferred direction:
125  agents[a].x += agents[a].preferred_dir_x * long_step;
126  agents[a].y += agents[a].preferred_dir_y * long_step;
127  }
128  }
129 
130  // let the agent move over the image in a toroid world:
131  if (agents[a].x > img->w - border) {
132  agents[a].x = border;
133  } else if (agents[a].x < border) {
134  agents[a].x = img->w - border;
135  }
136  if (agents[a].y > img->h - border) {
137  agents[a].y = border;
138  } else if (agents[a].y < border) {
139  agents[a].y = img->h - border;
140  }
141  }
142  }
143  }
144 
145  // Transform agents to corners:
146  (*num_corners) = 0;
147  for (a = 0; a < n_agents; a++) {
148 
149  // for active agents do a last check on the new position:
150  if (agents[a].active) {
151  // check if the last step brought the agent to a corner:
152  uint16_t x = (uint16_t) agents[a].x;
153  uint16_t y = (uint16_t) agents[a].y;
154  if (fast9_detect_pixel(img, fast_threshold, x, y)) {
155  // we arrived at a corner, yeah!!!
156  agents[a].active = 0;
157  }
158  }
159 
160  // if inactive, the agent is a corner:
161  if (!agents[a].active) {
162  (*ret_corners)[(*num_corners)].x = (uint32_t) agents[a].x;
163  (*ret_corners)[(*num_corners)].y = (uint32_t) agents[a].y;
164  (*num_corners)++;
165  }
166  }
167 }
168 
unsigned short uint16_t
Definition: types.h:16
uint16_t n_agents
Definition: image.h:43
uint16_t n_time_steps
int active
Definition: act_fast.h:31
uint32_t x
The x coordinate of the point.
Definition: image.h:58
Finds corners in an image by actively scanning the image.
int fast9_detect_pixel(struct image_t *img, uint8_t threshold, uint16_t x, uint16_t y)
Do a FAST9 corner detection for a single pixel.
Definition: fast_rosten.c:3709
float x
Definition: act_fast.h:29
Image helper functions like resizing, color filter, converters...
void image_gradient_pixel(struct image_t *img, struct point_t *loc, int method, int *dx, int *dy)
Get the gradient at a pixel location.
Definition: image.c:736
uint16_t w
Image width.
Definition: image.h:45
unsigned long uint32_t
Definition: types.h:18
uint16_t h
Image height.
Definition: image.h:46
float preferred_dir_y
Definition: act_fast.h:33
void act_fast(struct image_t *img, uint8_t fast_threshold, uint16_t *num_corners, struct point_t **ret_corners, uint16_t n_agents, uint16_t n_time_steps, float long_step, float short_step, int min_gradient, int gradient_method)
Do an ACT-FAST corner detection.
Definition: act_fast.c:48
uint32_t y
The y coordinate of the point.
Definition: image.h:59
Definition: image.h:57
struct agent_t agents[MAX_AGENTS]
Definition: act_fast.c:33
float preferred_dir_x
Definition: act_fast.h:32
unsigned char uint8_t
Definition: types.h:14
float y
Definition: act_fast.h:30
#define MAX_AGENTS
Definition: act_fast.c:32