Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
edge_flow.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016 Kimberly McGuire <k.n.mcguire@tudelft.nl
3 *
4 * This file is part of Paparazzi.
5 *
6 * Paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * Paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Paparazzi; see the file COPYING. If not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20
41{
42 // Adaptive Time Horizon:
43 // if the flow measured in previous frame is small,
44 // the algorithm will choose an frame further away back from the
45 // current frame to detect subpixel flow
46 if (MAX_HORIZON > 2) {
47
49 flow_mag_x = abs(result->flow_x);
50 flow_mag_y = abs(result->flow_y);
53
56
57 // IF statements which will decrement the previous frame offset
58 // if the measured flow of last loop is higher than max value (higher flow measured)
59 // and visa versa
62 }
65 }
68 }
71 }
72 }
73
74 //Wrap index previous frame offset from current frame nr.
79}
80
90{
91 uint8_t *img_buf = (uint8_t *)img->buf;
92
93 // TODO use arm_conv_q31()
95 int32_t Sobel[3] = { -1, 0, 1};
96
97 int32_t y = 0, x = 0;
98 int32_t c = 0;
99
100 uint32_t idx = 0;
101
105 if (img->type == IMAGE_GRAYSCALE) {
106 interlace = 1;
107 } else {
108 if (img->type == IMAGE_YUV422) {
109 interlace = 2;
110 } else
111 while (1); // hang to show user something isn't right
112 }
113
114
115 // compute edge histogram
116 if (direction == 'x') {
117 // set values that are not visited
119 for (x = 1; x < image_width - 1; x++) {
120 edge_histogram[x] = 0;
121 for (y = 0; y < image_height; y++) {
122 sobel_sum = 0;
123
124 for (c = -1; c <= 1; c += 2) {
125 idx = interlace * (image_width * y + (x + c));
126
127 sobel_sum += Sobel[c + 1] * (int32_t)img_buf[idx];
128 }
132 }
133 }
134 }
135 } else if (direction == 'y') {
136 // set values that are not visited
138 for (y = 1; y < image_height - 1; y++) {
139 edge_histogram[y] = 0;
140 for (x = 0; x < image_width; x++) {
141 sobel_sum = 0;
142
143 for (c = -1; c <= 1; c += 2) {
144 idx = interlace * (image_width * (y + c) + x);
145
146 sobel_sum += Sobel[c + 1] * (int32_t)img_buf[idx];
147 }
151 }
152 }
153 }
154 } else
155 while (1); // hang to show user something isn't right
156}
157
169 uint16_t size,
171{
172 int32_t c = 0, r = 0;
173 int32_t x = 0;
174 uint32_t SAD_temp[2 * DISP_RANGE_MAX + 1]; // size must be at least 2*D + 1
175
176 int32_t W = window;
178
179
181 memset(displacement, 0, sizeof(int32_t)*size);
182
183 int32_t border[2];
184
185 if (der_shift < 0) {
186 border[0] = W + D + der_shift;
187 border[1] = size - W - D;
188 } else if (der_shift > 0) {
189 border[0] = W + D;
190 border[1] = size - W - D - der_shift;
191 } else {
192 border[0] = W + D;
193 border[1] = size - W - D;
194 }
195
196 if (border[0] >= border[1] || abs(der_shift) >= 10) {
197 SHIFT_TOO_FAR = 1;
198 }
199 // TODO: replace with arm offset subtract
200 for (x = border[0]; x < border[1]; x++) {
201 if (!SHIFT_TOO_FAR) {
202 for (c = -D; c <= D; c++) {
203 SAD_temp[c + D] = 0;
204 for (r = -W; r <= W; r++) {
205 SAD_temp[c + D] += abs(edge_histogram[x + r] - edge_histogram_prev[x + r + c + der_shift]);
206 }
207 }
208 displacement[x] = (int32_t)getMinimum(SAD_temp, 2 * D + 1) - D;
209 } else {
210 }
211 }
212}
213
221{
222 uint32_t i;
223 uint32_t min_ind = 0;
226 for (i = 1; i < n; i++) {
227 if (a[i] <= min_err) {
228 min_ind = i;
229 min_err = a[i];
231 }
232 }
233 //*min_error = min_err_tot;
234 return min_ind;
235}
236
237
249{
250 int32_t x;
251
252 int32_t count = 0;
253 int32_t sumY = 0;
254 int32_t sumX = 0;
255 int32_t sumX2 = 0;
256 int32_t sumXY = 0;
257 int32_t xMean = 0;
258 int32_t yMean = 0;
261 int32_t size_int = (int32_t)size;
263
264 *divergence = 0;
265 *flow = 0;
266
267 // compute fixed sums
269 sumX = xend * (xend + 1) / 2 - border_int * (border_int + 1) / 2 + border_int;
270 sumX2 = xend * (xend + 1) * (2 * xend + 1) / 6 - border_int * (border_int + 1) * (2 * border_int + 1) / 6 + border_int * border_int;
271 xMean = (size_int - 1) / 2;
272 count = size_int - 2 * border_int;
273
274 for (x = border_int; x < size_int - border_int; x++) {
275 sumY += displacement[x];
276 sumXY += x * displacement[x];
277 }
278
279 yMean = RES * sumY / count;
280
281 divergence_int = (RES * sumXY - sumX * yMean) / (sumX2 - sumX * xMean); // compute slope of line ax + b
282 *divergence = divergence_int;
283 *flow = yMean - *divergence * xMean; // compute b (or y) intercept of line ax + b
284
285 for (x = border_int; x < size_int - border_int; x++) {
287 }
288}
289
299{
300 struct point_t point1;
301 struct point_t point2;
302 struct point_t point1_prev;
303 struct point_t point2_prev;
304 struct point_t point1_extra;
305 struct point_t point2_extra;
306 uint16_t i;
307
308 for (i = 1; i < img->w - 1; i++) {
309 point1.y = -(uint16_t)edge_hist_x[i] / 100 + img->h / 3;
310 point1.x = i;
311 point2.y = -(uint16_t)edge_hist_x[i + 1] / 100 + img->h / 3;
312 point2.x = i + 1;
313
314 point1_prev.y = -(uint16_t)edge_hist_x_prev[i] / 100 + img->h * 2 / 3;
315 point1_prev.x = i;
316 point2_prev.y = -(uint16_t)edge_hist_x_prev[i + 1] / 100 + img->h * 2 / 3;
317 point2_prev.x = i + 1;
318
321 }
322
323 point1_extra.y = (edgeflow.flow_x + edgeflow.div_x * img->w / 2) / 100 + img->h / 2;
324 point1_extra.x = 0;
325 point2_extra.y = (edgeflow.flow_x + edgeflow.div_x * img->w / 2) / 100 + img->h / 2;
326 point2_extra.x = img->w;
328}
329
338{
340 int32_t i = 0;
341
342 for (i = 1; i < size + 1; i ++) {
343 if (edgehist[i - 1] < edgehist[i] && edgehist[i] > edgehist[i + 1] && edgehist[i] > thres) {
344 amountPeaks ++;
345 }
346 }
347 return amountPeaks;
348}
#define RES
uint32_t getMinimum(uint32_t *a, uint32_t n)
Calculate minimum of an array.
Definition edge_flow.c:220
uint32_t getAmountPeaks(int32_t *edgehist, int32_t thres, int32_t size)
getAmountPeaks, calculates the amount of peaks in a edge histogram
Definition edge_flow.c:337
void calculate_edge_displacement(int32_t *edge_histogram, int32_t *edge_histogram_prev, int32_t *displacement, uint16_t size, uint8_t window, uint8_t disp_range, int32_t der_shift)
Calculate_displacement calculates the displacement between two histograms.
Definition edge_flow.c:168
void draw_edgeflow_img(struct image_t *img, struct edge_flow_t edgeflow, int32_t *edge_hist_x_prev, int32_t *edge_hist_x)
Draws edgehistogram, displacement and linefit directly on the image for debugging (only for edgeflow ...
Definition edge_flow.c:297
void calculate_edge_histogram(struct image_t *img, int32_t edge_histogram[], char direction, uint16_t edge_threshold)
Calculate a edge/gradient histogram for each dimension of the image.
Definition edge_flow.c:88
void line_fit(int32_t *displacement, int32_t *divergence, int32_t *flow, uint32_t size, uint32_t border, uint16_t RES)
Fits a linear model to an array with pixel displacements with least squares.
Definition edge_flow.c:247
void calc_previous_frame_nr(struct opticflow_result_t *result, struct opticflow_t *opticflow, uint8_t current_frame_nr, uint8_t *previous_frame_offset, uint8_t *previous_frame_nr)
Calc_previous_frame_nr; adaptive Time Horizon.
Definition edge_flow.c:39
calculate optical flow with EdgeFlow
#define DISP_RANGE_MAX
Definition edge_flow.h:53
#define MAX_HORIZON
Definition edge_flow.h:46
void image_draw_line(struct image_t *img, struct point_t *from, struct point_t *to)
Draw a pink line on the image.
Definition image.c:917
uint32_t y
The y coordinate of the point.
Definition image.h:60
@ IMAGE_GRAYSCALE
Grayscale image with only the Y part (uint8 per pixel)
Definition image.h:37
@ IMAGE_YUV422
UYVY format (uint16 per pixel)
Definition image.h:36
int16_t flow_x
Flow in x direction from the camera (in subpixels) with X positive to the right.
int16_t flow_y
Flow in y direction from the camera (in subpixels) with Y positive to the bottom.
uint16_t foo
Definition main_demo5.c:58
static uint32_t idx
uint8_t direction
uint16_t search_distance
Search distance for blockmatching alg.
struct opticflow_t opticflow[ACTIVE_CAMERAS]
Opticflow calculations.
static float D
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
int int32_t
Typedef defining 32 bit int type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
short int16_t
Typedef defining 16 bit short type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.