Paparazzi UAS  v5.8.2_stable-0-g6260b7c
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 #define NO_DIV 0.0
36 
44 float get_size_divergence(struct flow_t *vectors, int count, int n_samples)
45 {
46  float distance_1;
47  float distance_2;
48  float *divs;
49  unsigned int sample;
50  float dx;
51  float dy;
52  float mean_divergence;
53  int n_elements;
54  unsigned int i, j;
55 
56  if (count < 2) {
57  return NO_DIV;
58  }
59 
60  if (n_samples == 0) {
61  // divs will contain the individual divergence estimates:
62  n_elements = (count * count - count) / 2;
63  divs = (float *) malloc(sizeof(float) * n_elements);
64 
65  // go through all possible lines:
66  sample = 0;
67  for (i = 0; i < count; i++) {
68  for (j = i + 1; j < count; j++) {
69  // distance in previous image:
70  dx = vectors[i].pos.x - vectors[j].pos.x;
71  dy = vectors[i].pos.y - vectors[j].pos.y;
72  distance_1 = sqrt(dx * dx + dy * dy);
73 
74  // distance in current image:
75  dx = vectors[i].pos.x + vectors[i].flow_x - vectors[j].pos.x - vectors[j].flow_x;
76  dy = vectors[i].pos.y + vectors[i].flow_y - vectors[j].pos.y - vectors[j].flow_y;
77  distance_2 = sqrt(dx * dx + dy * dy);
78 
79  // calculate divergence for this sample:
80  divs[sample] = (distance_2 - distance_1) / distance_1;
81  sample++;
82  }
83  }
84 
85  // calculate the mean divergence:
86  mean_divergence = get_mean(divs, n_elements);
87 
88  // free the memory of divs:
89  free(divs);
90  } else {
91  // vector that will contain individual divergence estimates:
92  divs = (float *) malloc(sizeof(float) * n_samples);
93 
94  // take random samples:
95  for (sample = 0; sample < n_samples; sample++) {
96  // take two random indices:
97  i = rand() % count;
98  j = rand() % count;
99  // ensure it is not the same index:
100  while (i == j) {
101  j = rand() % count;
102  }
103 
104  // distance in previous image:
105  dx = vectors[i].pos.x - vectors[j].pos.x;
106  dy = vectors[i].pos.y - vectors[j].pos.y;
107  distance_1 = sqrt(dx * dx + dy * dy);
108 
109  // distance in current image:
110  dx = vectors[i].pos.x + vectors[i].flow_x - vectors[j].pos.x - vectors[j].flow_x;
111  dy = vectors[i].pos.y + vectors[i].flow_y - vectors[j].pos.y - vectors[j].flow_y;
112  distance_2 = sqrt(dx * dx + dy * dy);
113 
114  // calculate divergence for this sample:
115  divs[sample] = (distance_2 - distance_1) / distance_1;
116  }
117 
118  // calculate the mean divergence:
119  mean_divergence = get_mean(divs, n_samples);
120 
121  // free the memory of divs:
122  free(divs);
123  }
124 
125  // return the calculated divergence:
126  return mean_divergence;
127 }
128 
135 float get_mean(float *numbers, int n_elements)
136 {
137  int i = 0;
138  float mean = 0;
139  for (i = 0; i < n_elements; i++) {
140  mean += numbers[i];
141  }
142  mean /= n_elements;
143  return mean;
144 }
145 
146 
float get_mean(float *numbers, int n_elements)
Get the sample mean of a vector of floats.
uint16_t x
The x coordinate of the point.
Definition: image.h:55
Definition: image.h:60
Calculate divergence from flow vectors by looking at line sizes beteween the points.
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.
int16_t flow_x
The x direction flow in subpixels.
Definition: image.h:62
struct point_t pos
The original position the flow comes from.
Definition: image.h:61
#define NO_DIV
uint16_t y
The y coordinate of the point.
Definition: image.h:56
int16_t flow_y
The y direction flow in subpixels.
Definition: image.h:63