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
size_divergence.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Guido de Croon <guido.de.croon@gmail.com>
3  *
4  * From:
5  * Characterization of Flow Field Divergence for Vertical Landing Control of MAVs
6  * by H.W. Ho and G.C.H.E. de Croon (submitted)
7  *
8  * This file is part of Paparazzi.
9  *
10  * Paparazzi is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2, or (at your option)
13  * any later version.
14  *
15  * Paparazzi is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Paparazzi; see the file COPYING. If not, see
22  * <http://www.gnu.org/licenses/>.
23  */
24 
32 #include "size_divergence.h"
33 #include <stdlib.h>
34 
35 #include "math/pprz_stat.h"
36 
37 #define NO_DIV 0.0
38 
46 float get_size_divergence(struct flow_t *vectors, int count, int n_samples)
47 {
48  float distance_1, distance_2;
49  float *divs; // divs will contain the individual divergence estimates:
50  uint32_t used_samples = 0;
51  float dx, dy;
52  int32_t i, j;
53 
54  int32_t max_samples = (count * count - count) / 2;
55 
56  if (count < 2) {
57  return NO_DIV;
58  } else if (count >= max_samples) {
59  n_samples = 0;
60  }
61 
62  if (n_samples == 0) {
63  divs = (float *) malloc(sizeof(float) * max_samples);
64 
65  // go through all possible lines:
66  for (i = 0; i < count; i++) {
67  for (j = i + 1; j < count; j++) {
68  // distance in previous image:
69  dx = (float)vectors[i].pos.x - (float)vectors[j].pos.x;
70  dy = (float)vectors[i].pos.y - (float)vectors[j].pos.y;
71  distance_1 = sqrtf(dx * dx + dy * dy);
72 
73  // distance in current image:
74  dx = (float)vectors[i].pos.x + (float)vectors[i].flow_x - (float)vectors[j].pos.x - (float)vectors[j].flow_x;
75  dy = (float)vectors[i].pos.y + (float)vectors[i].flow_y - (float)vectors[j].pos.y - (float)vectors[j].flow_y;
76  distance_2 = sqrtf(dx * dx + dy * dy);
77 
78  // calculate divergence for this sample:
79  if (distance_1 > 1E-5) {
80  divs[used_samples] = (distance_2 - distance_1) / distance_1;
81  used_samples++;
82  }
83  }
84  }
85  } else {
86  divs = (float *) malloc(sizeof(float) * n_samples);
87 
88  // take random samples:
89  for (uint16_t sample = 0; sample < n_samples; sample++) {
90  // take two random indices:
91  i = rand() % count;
92  j = rand() % count;
93  // ensure it is not the same index:
94  while (i == j) {
95  j = rand() % count;
96  }
97 
98  // distance in previous image:
99  dx = (float)vectors[i].pos.x - (float)vectors[j].pos.x;
100  dy = (float)vectors[i].pos.y - (float)vectors[j].pos.y;
101  distance_1 = sqrt(dx * dx + dy * dy);
102 
103  // distance in current image:
104  dx = (float)vectors[i].pos.x + (float)vectors[i].flow_x - (float)vectors[j].pos.x - (float)vectors[j].flow_x;
105  dy = (float)vectors[i].pos.y + (float)vectors[i].flow_y - (float)vectors[j].pos.y - (float)vectors[j].flow_y;
106  distance_2 = sqrt(dx * dx + dy * dy);
107 
108 
109  // calculate divergence for this sample:
110  if (distance_1 > 1E-5) {
111  divs[used_samples] = (distance_2 - distance_1) / distance_1;
112  used_samples++;
113  }
114  }
115  }
116 
117  // calculate the mean divergence:
118  float mean_divergence = mean_f(divs, used_samples);
119 
120  // free the memory of divs:
121  free(divs);
122 
123  // return the calculated divergence:
124  return mean_divergence;
125 }
unsigned short uint16_t
Definition: types.h:16
Definition: image.h:66
Calculate divergence from flow vectors by looking at line sizes beteween the points.
uint32_t x
The x coordinate of the point.
Definition: image.h:58
int n_samples
Definition: detect_gate.c:85
float get_size_divergence(struct flow_t *vectors, int count, int n_samples)
Get divergence from optical flow vectors based on line sizes between corners.
float mean_f(float *array, uint32_t n_elements)
Compute the mean value of an array (float)
Definition: pprz_stat.c:122
int16_t flow_x
The x direction flow in subpixels.
Definition: image.h:68
unsigned long uint32_t
Definition: types.h:18
struct point_t pos
The original position the flow comes from.
Definition: image.h:67
uint32_t y
The y coordinate of the point.
Definition: image.h:59
signed long int32_t
Definition: types.h:19
#define NO_DIV
Statistics functions.
uint16_t count
Number of times the point has been tracked successfully.
Definition: image.h:60
#define E
int16_t flow_y
The y direction flow in subpixels.
Definition: image.h:69