48 #define OPTICFLOW_SHOW_FLOW 0
49 #define OPTICFLOW_SHOW_CORNERS 0
59 #ifndef OPTICFLOW_FOV_W
60 #define OPTICFLOW_FOV_W 0.89360857702
64 #ifndef OPTICFLOW_FOV_H
65 #define OPTICFLOW_FOV_H 0.67020643276
70 #define OPTICFLOW_FX 343.1211
75 #define OPTICFLOW_FY 348.5053
80 #ifndef OPTICFLOW_MAX_TRACK_CORNERS
81 #define OPTICFLOW_MAX_TRACK_CORNERS 25
85 #ifndef OPTICFLOW_WINDOW_SIZE
86 #define OPTICFLOW_WINDOW_SIZE 10
90 #ifndef OPTICFLOW_SEARCH_DISTANCE
91 #define OPTICFLOW_SEARCH_DISTANCE 20
93 PRINT_CONFIG_VAR(OPTICFLOW_MAX_SEARCH_DISTANCE)
95 #ifndef OPTICFLOW_SUBPIXEL_FACTOR
96 #define OPTICFLOW_SUBPIXEL_FACTOR 10
100 #ifndef OPTICFLOW_MAX_ITERATIONS
101 #define OPTICFLOW_MAX_ITERATIONS 10
105 #ifndef OPTICFLOW_THRESHOLD_VEC
106 #define OPTICFLOW_THRESHOLD_VEC 2
110 #ifndef OPTICFLOW_PYRAMID_LEVEL
111 #define OPTICFLOW_PYRAMID_LEVEL 0
115 #ifndef OPTICFLOW_FAST9_ADAPTIVE
116 #define OPTICFLOW_FAST9_ADAPTIVE TRUE
120 #ifndef OPTICFLOW_FAST9_THRESHOLD
121 #define OPTICFLOW_FAST9_THRESHOLD 20
125 #ifndef OPTICFLOW_FAST9_MIN_DISTANCE
126 #define OPTICFLOW_FAST9_MIN_DISTANCE 10
130 #ifndef OPTICFLOW_FAST9_PADDING
131 #define OPTICFLOW_FAST9_PADDING 20
136 #define FAST9_LOW_THRESHOLD 5
137 #define FAST9_HIGH_THRESHOLD 60
139 #ifndef OPTICFLOW_METHOD
140 #define OPTICFLOW_METHOD 0
144 #if OPTICFLOW_METHOD > 1
145 #error WARNING: Both Lukas Kanade and EdgeFlow are NOT selected
148 #ifndef OPTICFLOW_DEROTATION
149 #define OPTICFLOW_DEROTATION TRUE
153 #ifndef OPTICFLOW_MEDIAN_FILTER
154 #define OPTICFLOW_MEDIAN_FILTER TRUE
159 #include "filters/median_filter.h"
165 static int cmp_flow(
const void *a,
const void *b);
226 float size_divergence;
int n_samples;
229 float error_threshold;
230 int n_iterations_RANSAC, n_samples_RANSAC, success_fit;
269 #if OPTICFLOW_SHOW_CORNERS
290 #if OPTICFLOW_SHOW_FLOW
291 printf(
"show: n tracked = %d\n", result->
tracked_cnt);
305 error_threshold = 10.0f;
306 n_iterations_RANSAC = 20;
307 n_samples_RANSAC = 5;
309 n_samples_RANSAC, img->
w, img->
h, &fit_info);
347 float diff_flow_x = 0;
348 float diff_flow_y = 0;
376 result->
vel_x = vel_x;
377 result->
vel_y = vel_y;
409 static uint8_t current_frame_nr = 0;
411 static uint8_t previous_frame_offset[2] = {1, 1};
415 displacement.
x = malloc(
sizeof(
int32_t) * img->
w);
416 displacement.
y = malloc(
sizeof(
int32_t) * img->
h);
423 edge_hist[i].
x = malloc(
sizeof(
int32_t) * img->
w);
424 edge_hist[i].
y = malloc(
sizeof(
int32_t) * img->
h);
449 int32_t *edge_hist_x = edge_hist[current_frame_nr].
x;
450 int32_t *edge_hist_y = edge_hist[current_frame_nr].
y;
457 edge_hist[current_frame_nr].
rates = state->
rates;
464 int32_t *prev_edge_histogram_x = edge_hist[previous_frame_nr[0]].
x;
465 int32_t *prev_edge_histogram_y = edge_hist[previous_frame_nr[1]].
y;
472 der_shift_x = (
int16_t)((edge_hist[previous_frame_nr[0]].rates.p + edge_hist[current_frame_nr].
rates.
p) / 2.0f /
475 der_shift_y = (
int16_t)((edge_hist[previous_frame_nr[1]].rates.q + edge_hist[current_frame_nr].
rates.
q) / 2.0f /
482 displacement.
x, img->
w,
483 window_size, disp_range, der_shift_x);
485 displacement.
y, img->
h,
486 window_size, disp_range, der_shift_y);
492 window_size + disp_range, RES);
495 window_size + disp_range, RES);
528 float time_diff_x = (
float)(
timeval_diff(&edge_hist[previous_frame_nr[0]].frame_time, &img->
ts)) / 1000.;
529 float time_diff_y = (float)(
timeval_diff(&edge_hist[previous_frame_nr[1]].frame_time, &img->
ts)) / 1000.;
530 fps_x = 1 / (time_diff_x);
531 fps_y = 1 / (time_diff_y);
544 result->
vel_x = vel_x;
545 result->
vel_y = vel_y;
552 #if OPTICFLOW_SHOW_FLOW
556 current_frame_nr = (current_frame_nr + 1) % MAX_HORIZON;
573 static int8_t switch_counter = -1;
574 if (switch_counter != opticflow->
method) {
576 switch_counter = opticflow->
method;
582 if (opticflow->
method == 0) {
584 }
else if (opticflow->
method == 1) {
599 msec = (finishtime->tv_sec - starttime->tv_sec) * 1000;
600 msec += (finishtime->tv_usec - starttime->tv_usec) / 1000;
int16_t flow_y
Flow in y direction from the camera (in subpixels)
uint16_t fast9_min_distance
Minimum distance in pixels between corners.
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.
int16_t flow_der_y
The derotated flow calculation in the y direction (in subpixels)
#define FAST9_HIGH_THRESHOLD
float div_size
Divergence as determined with the size_divergence script.
uint8_t max_iterations
The maximum amount of iterations the Lucas Kanade algorithm should do.
struct opticflow_t opticflow
Opticflow calculations.
uint16_t window_size
Window size for the blockmatching algorithm (general value for all methods)
struct FloatRates rates
Body rates.
calculate optical flow with EdgeFlow
void image_switch(struct image_t *a, struct image_t *b)
This will switch image *a and *b This is faster as image_copy because it doesn't copy the whole image...
void calc_edgeflow_tot(struct opticflow_t *opticflow, struct opticflow_state_t *state, struct image_t *img, struct opticflow_result_t *result)
Run the optical flow with EDGEFLOW on a new image frame.
uint16_t fast9_rsize
Amount of corners allocated.
void opticflow_calc_init(struct opticflow_t *opticflow, uint16_t w, uint16_t h)
Initialize the opticflow calculator.
#define OPTICFLOW_PYRAMID_LEVEL
struct flow_t * opticFlowLK(struct image_t *new_img, struct image_t *old_img, struct point_t *points, uint16_t *points_cnt, uint16_t half_window_size, uint16_t subpixel_factor, uint8_t max_iterations, uint8_t step_threshold, uint8_t max_points, uint8_t pyramid_level)
Calculate velocity from optic flow.
bool median_filter
Decides to use a median filter on the velocity.
#define OPTICFLOW_MEDIAN_FILTER
void image_create(struct image_t *img, uint16_t width, uint16_t height, enum image_type type)
Create a new image.
#define FLOAT_RATES_ZERO(_r)
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 ...
#define OPTICFLOW_THRESHOLD_VEC
#define OPTICFLOW_FAST9_MIN_DISTANCE
void image_copy(struct image_t *input, struct image_t *output)
Copy an image from inut to output This will only work if the formats are the same.
#define OPTICFLOW_FAST9_ADAPTIVE
void image_show_points(struct image_t *img, struct point_t *points, uint16_t points_cnt)
Show points in an image by coloring them through giving the pixels the maximum value.
static int cmp_flow(const void *a, const void *b)
Compare two flow vectors based on flow distance Used for sorting.
Calculate divergence from flow vectors by looking at line sizes beteween the points.
uint8_t threshold_vec
The threshold in x, y subpixels which the algorithm should stop.
void image_show_flow(struct image_t *img, struct flow_t *vectors, uint16_t points_cnt, uint8_t subpixel_factor)
Shows the flow from a specific point to a new point This works on YUV422 and Grayscale images...
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.
bool derotation
Derotation switched on or off (depended on the quality of the gyroscope measurement) ...
uint8_t method
Method to use to calculate the optical flow.
uint8_t max_track_corners
Maximum amount of corners Lucas Kanade should track.
float agl
height above ground [m]
struct MedianFilterInt vel_x_filt vel_y_filt
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.
void opticflow_calc_frame(struct opticflow_t *opticflow, struct opticflow_state_t *state, struct image_t *img, struct opticflow_result_t *result)
Run the optical flow on a new image frame.
Image helper functions like resizing, color filter, converters...
void fast9_detect(struct image_t *img, uint8_t threshold, uint16_t min_dist, uint16_t x_padding, uint16_t y_padding, uint16_t *num_corners, uint16_t *ret_corners_length, struct point_t *ret_corners)
Do a FAST9 corner detection.
uint16_t tracked_cnt
The amount of tracked corners.
uint16_t subpixel_factor
The amount of subpixels per pixel.
#define OPTICFLOW_FAST9_PADDING
int16_t flow_x
The x direction flow in subpixels.
struct point_t * fast9_ret_corners
Corners.
struct timeval prev_timestamp
Timestamp of the previous frame, used for FPS calculation.
#define OPTICFLOW_FAST9_THRESHOLD
struct image_t prev_img_gray
Previous gray image frame.
uint8_t fast9_threshold
FAST9 corner detection threshold.
bool just_switched_method
#define OPTICFLOW_WINDOW_SIZE
void image_to_grayscale(struct image_t *input, struct image_t *output)
Convert an image to grayscale.
struct image_t img_gray
Current gray image frame.
float vel_x
The velocity in the x direction (image coordinates)
uint16_t corner_cnt
The amount of coners found by FAST9.
float vel_y
The velocity in the y direction (image coordinates)
float fps
Frames per second of the optical flow calculation.
efficient fixed-point optical-flow calculation
int analyze_linear_flow_field(struct flow_t *vectors, int count, float error_threshold, int n_iterations, int n_samples, int im_width, int im_height, struct linear_flow_fit_info *info)
Analyze a linear flow field, retrieving information such as divergence, surface roughness, focus of expansion, etc.
#define OPTICFLOW_DEROTATION
struct timeval ts
The timestamp of creation.
bool got_first_img
If we got a image to work with.
float divergence
Basically, relative_velocity_z. Actual divergence of a 2D flow field is 2 * relative_velocity_z.
#define OPTICFLOW_SEARCH_DISTANCE
uint16_t fast9_padding
Padding used in FAST9 detector.
float surface_roughness
The error of the linear fit is a measure of surface roughness.
bool fast9_adaptive
Whether the FAST9 threshold should be adaptive.
void calc_fast9_lukas_kanade(struct opticflow_t *opticflow, struct opticflow_state_t *state, struct image_t *img, struct opticflow_result_t *result)
Run the optical flow with fast9 and lukaskanade on a new image frame.
Grayscale image with only the Y part (uint8 per pixel)
static uint32_t timeval_diff(struct timeval *starttime, struct timeval *finishtime)
Calculate the difference from start till finish.
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.
#define OPTICFLOW_MAX_TRACK_CORNERS
struct FloatRates prev_rates
Gyro Rates from the previous image frame.
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.
#define OPTICFLOW_SUBPIXEL_FACTOR
int16_t flow_x
Flow in x direction from the camera (in subpixels)
#define OPTICFLOW_MAX_ITERATIONS
uint32_t getAmountPeaks(int32_t *edgehist, uint32_t thres, int32_t size)
getAmountPeaks, calculates the amount of peaks in a edge histogram
uint8_t pyramid_level
Number of pyramid levels used in Lucas Kanade algorithm (0 == no pyramids used)
float noise_measurement
noise of measurement, for state filter
#define FAST9_LOW_THRESHOLD
int16_t flow_y
The y direction flow in subpixels.
uint16_t search_distance
Search distance for blockmatching alg.
float divergence
Divergence as determined with a linear flow fit.
float surface_roughness
Surface roughness as determined with a linear optical flow fit.
struct timeval frame_time
int16_t flow_der_x
The derotated flow calculation in the x direction (in subpixels)