53 #define OPTICFLOW_SHOW_FLOW 0
54 #define OPTICFLOW_SHOW_CORNERS 0
64 #ifndef OPTICFLOW_FOV_W
65 #define OPTICFLOW_FOV_W 0.89360857702
69 #ifndef OPTICFLOW_FOV_H
70 #define OPTICFLOW_FOV_H 0.67020643276
75 #define OPTICFLOW_FX 343.1211
80 #define OPTICFLOW_FY 348.5053
85 #ifndef OPTICFLOW_MAX_TRACK_CORNERS
86 #define OPTICFLOW_MAX_TRACK_CORNERS 25
90 #ifndef OPTICFLOW_WINDOW_SIZE
91 #define OPTICFLOW_WINDOW_SIZE 10
95 #ifndef OPTICFLOW_SEARCH_DISTANCE
96 #define OPTICFLOW_SEARCH_DISTANCE 20
100 #ifndef OPTICFLOW_SUBPIXEL_FACTOR
101 #define OPTICFLOW_SUBPIXEL_FACTOR 10
105 #ifndef OPTICFLOW_RESOLUTION_FACTOR
106 #define OPTICFLOW_RESOLUTION_FACTOR 100
110 #ifndef OPTICFLOW_MAX_ITERATIONS
111 #define OPTICFLOW_MAX_ITERATIONS 10
115 #ifndef OPTICFLOW_THRESHOLD_VEC
116 #define OPTICFLOW_THRESHOLD_VEC 2
120 #ifndef OPTICFLOW_PYRAMID_LEVEL
121 #define OPTICFLOW_PYRAMID_LEVEL 2
125 #ifndef OPTICFLOW_FAST9_ADAPTIVE
126 #define OPTICFLOW_FAST9_ADAPTIVE TRUE
130 #ifndef OPTICFLOW_FAST9_THRESHOLD
131 #define OPTICFLOW_FAST9_THRESHOLD 20
135 #ifndef OPTICFLOW_FAST9_MIN_DISTANCE
136 #define OPTICFLOW_FAST9_MIN_DISTANCE 10
140 #ifndef OPTICFLOW_FAST9_PADDING
141 #define OPTICFLOW_FAST9_PADDING 20
146 #define FAST9_LOW_THRESHOLD 5
147 #define FAST9_HIGH_THRESHOLD 60
149 #ifndef OPTICFLOW_METHOD
150 #define OPTICFLOW_METHOD 0
154 #if OPTICFLOW_METHOD > 1
155 #error WARNING: Both Lukas Kanade and EdgeFlow are NOT selected
158 #ifndef OPTICFLOW_DEROTATION
159 #define OPTICFLOW_DEROTATION TRUE
163 #ifndef OPTICFLOW_DEROTATION_CORRECTION_FACTOR_X
164 #define OPTICFLOW_DEROTATION_CORRECTION_FACTOR_X 1.0
168 #ifndef OPTICFLOW_DEROTATION_CORRECTION_FACTOR_Y
169 #define OPTICFLOW_DEROTATION_CORRECTION_FACTOR_Y 1.0
173 #ifndef OPTICFLOW_MEDIAN_FILTER
174 #define OPTICFLOW_MEDIAN_FILTER FALSE
178 #ifndef OPTICFLOW_KALMAN_FILTER
179 #define OPTICFLOW_KALMAN_FILTER TRUE
183 #ifndef OPTICFLOW_KALMAN_FILTER_PROCESS_NOISE
184 #define OPTICFLOW_KALMAN_FILTER_PROCESS_NOISE 0.01
188 #ifndef OPTICFLOW_FEATURE_MANAGEMENT
189 #define OPTICFLOW_FEATURE_MANAGEMENT 1
193 #ifndef OPTICFLOW_FAST9_REGION_DETECT
194 #define OPTICFLOW_FAST9_REGION_DETECT 1
198 #ifndef OPTICFLOW_FAST9_NUM_REGIONS
199 #define OPTICFLOW_FAST9_NUM_REGIONS 9
204 #include "filters/median_filter.h"
210 static int cmp_flow(
const void *a,
const void *b);
211 static int cmp_array(
const void *a,
const void *b);
274 float size_divergence;
int n_samples;
277 float error_threshold;
278 int n_iterations_RANSAC, n_samples_RANSAC, success_fit;
311 region_count[i] = malloc(
sizeof(
uint16_t) * 2);
312 region_count[i][0] = 0;
313 region_count[i][1] = i;
341 free(region_count[i]);
369 #if OPTICFLOW_SHOW_CORNERS
392 #if OPTICFLOW_SHOW_FLOW
406 error_threshold = 10.0f;
407 n_iterations_RANSAC = 20;
408 n_samples_RANSAC = 5;
410 n_samples_RANSAC, img->
w, img->
h, &fit_info);
448 float diff_flow_x = 0;
449 float diff_flow_y = 0;
456 diff_flow_x = (cam_state->
rates.
p) / result->
fps * img->
w /
458 diff_flow_y = (cam_state->
rates.
q) / result->
fps * img->
h /
479 result->
vel_x = vel_x;
480 result->
vel_y = vel_y;
524 static uint8_t current_frame_nr = 0;
526 static uint8_t previous_frame_offset[2] = {1, 1};
530 displacement.
x = malloc(
sizeof(
int32_t) * img->
w);
531 displacement.
y = malloc(
sizeof(
int32_t) * img->
h);
538 edge_hist[i].
x = malloc(
sizeof(
int32_t) * img->
w);
539 edge_hist[i].
y = malloc(
sizeof(
int32_t) * img->
h);
564 int32_t *edge_hist_x = edge_hist[current_frame_nr].
x;
565 int32_t *edge_hist_y = edge_hist[current_frame_nr].
y;
572 edge_hist[current_frame_nr].
rates = cam_state->
rates;
579 int32_t *prev_edge_histogram_x = edge_hist[previous_frame_nr[0]].
x;
580 int32_t *prev_edge_histogram_y = edge_hist[previous_frame_nr[1]].
y;
587 der_shift_x = (
int16_t)(edge_hist[current_frame_nr].rates.p /
590 der_shift_y = (
int16_t)(edge_hist[current_frame_nr].rates.q /
597 displacement.
x, img->
w,
598 window_size, disp_range, der_shift_x);
600 displacement.
y, img->
h,
601 window_size, disp_range, der_shift_y);
607 window_size + disp_range, RES);
610 window_size + disp_range, RES);
646 float time_diff_x = (
float)(
timeval_diff(&edge_hist[previous_frame_nr[0]].frame_time, &img->
ts)) / 1000.;
647 float time_diff_y = (float)(
timeval_diff(&edge_hist[previous_frame_nr[1]].frame_time, &img->
ts)) / 1000.;
648 fps_x = 1 / (time_diff_x);
649 fps_y = 1 / (time_diff_y);
662 result->
vel_x = vel_x;
663 result->
vel_y = vel_y;
670 #if OPTICFLOW_SHOW_FLOW
674 current_frame_nr = (current_frame_nr + 1) % MAX_HORIZON;
677 free(displacement.
x);
678 free(displacement.
y);
695 static int8_t switch_counter = -1;
696 if (switch_counter != opticflow->
method) {
698 switch_counter = opticflow->
method;
706 if (opticflow->
method == 0) {
708 }
else if (opticflow->
method == 1) {
722 static bool reinitialize_kalman =
true;
724 static uint8_t wait_filter_counter =
730 wait_filter_counter = 0;
731 reinitialize_kalman =
true;
734 if (wait_filter_counter > 50) {
743 float acceleration_measurement[2];
744 acceleration_measurement[0] = accel_meas_body.
x;
745 acceleration_measurement[1] = accel_meas_body.
y;
749 if (reinitialize_kalman) {
750 reinitialize_kalman =
false;
754 wait_filter_counter++;
757 reinitialize_kalman =
true;
773 float *measurement_noise,
float kalman_process_noise,
bool reinitialize_kalman)
776 static float covariance_x[4], covariance_y[4], state_estimate_x[2], state_estimate_y[2];
777 float measurements_x[2], measurements_y[2];
779 if (reinitialize_kalman) {
780 state_estimate_x[0] = 0.0f;
781 state_estimate_x[1] = 0.0f;
782 covariance_x[0] = 1.0f;
783 covariance_x[1] = 1.0f;
784 covariance_x[2] = 1.0f;
785 covariance_x[3] = 1.0f;
787 state_estimate_y[0] = 0.0f;
788 state_estimate_y[1] = 0.0f;
789 covariance_y[0] = 1.0f;
790 covariance_y[1] = 1.0f;
791 covariance_y[2] = 1.0f;
792 covariance_y[3] = 1.0f;
802 float model[4] = {1.0f, 1.0f / fps , 0.0f , 1.0f};
803 float process_noise[2] = {kalman_process_noise, kalman_process_noise};
806 measurements_x[0] = *velocity_x;
807 measurements_x[1] = acceleration_measurement[0];
809 measurements_y[0] = *velocity_y;
810 measurements_y[1] = acceleration_measurement[1];
816 *velocity_x = state_estimate_x[0];
817 *velocity_y = state_estimate_y[0];
829 msec = (finishtime->tv_sec - starttime->tv_sec) * 1000;
830 msec += (finishtime->tv_usec - starttime->tv_usec) / 1000;
860 return pa[0] - pb[0];
float vel_body_x
The velocity in the x direction (body fixed coordinates)
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.
bool feature_management
Decides whether to keep track corners in memory for the next frame instead of re-detecting every time...
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)
static gazebo::physics::ModelPtr model
struct FloatRates rates
Body rates.
void kalman_filter_linear_2D_float(float *model, float *measurements, float *covariance, float *state, float *process_noise, float *measurement_noise)
A simple linear 2D kalman filter, computed using floats and matrices.
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...
uint16_t fast9_rsize
Amount of corners allocated.
#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.
uint32_t x
The x coordinate of the point.
uint16_t resolution_factor
The resolution in EdgeFlow to determine the Divergence.
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) ...
uint16_t y_sub
The y subpixel coordinate of the point.
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]
uint8_t fast9_num_regions
The number of regions of interest the image is split into.
struct MedianFilterInt vel_x_filt vel_y_filt
void opticflow_calc_init(struct opticflow_t *opticflow)
Initialize the opticflow calculator.
#define OPTICFLOW_DEROTATION_CORRECTION_FACTOR_Y
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.
Image helper functions like resizing, color filter, converters...
uint16_t tracked_cnt
The amount of tracked corners.
float vel_body_y
The velocity in the y direction (body fixed coordinates)
#define OPTICFLOW_RESOLUTION_FACTOR
#define OPTICFLOW_FEATURE_MANAGEMENT
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.
void calc_edgeflow_tot(struct opticflow_t *opticflow, struct opticflow_state_t *cam_state, struct image_t *img, struct opticflow_result_t *result)
Run the optical flow with EDGEFLOW on a new image frame.
void calc_fast9_lukas_kanade(struct opticflow_t *opticflow, struct opticflow_state_t *cam_state, struct image_t *img, struct opticflow_result_t *result)
Run the optical flow with fast9 and lukaskanade on a new image frame.
#define OPTICFLOW_FAST9_THRESHOLD
struct image_t prev_img_gray
Previous gray image frame.
struct Int32Vect3 accel_imu_meas
imu acceleration in imu's coordinates
void float_quat_vmult(struct FloatVect3 *v_out, struct FloatQuat *q, const struct FloatVect3 *v_in)
rotate 3D vector by quaternion.
uint8_t fast9_threshold
FAST9 corner detection threshold.
bool just_switched_method
Boolean to check if methods has been switched (for reinitialization)
#define OPTICFLOW_FAST9_REGION_DETECT
struct FloatQuat imu_to_body_quat
imu to body quaternion
struct point_t pos
The original position the flow comes from.
Inertial Measurement Unit interface.
#define ACCELS_FLOAT_OF_BFP(_ef, _ei)
uint32_t y
The y coordinate of the point.
#define OPTICFLOW_WINDOW_SIZE
void image_to_grayscale(struct image_t *input, struct image_t *output)
Convert an image to grayscale.
uint16_t x_sub
The x subpixel coordinate of the point.
struct image_t img_gray
Current gray image frame.
static int cmp_array(const void *a, const void *b)
Compare the rows of an integer (uint16_t) 2D array based on the first column.
float vel_x
The velocity in the x direction (image coordinates)
#define OPTICFLOW_FAST9_NUM_REGIONS
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 kalman_filter
Decide to use Kalman filter to filter velocity with accelerometers.
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
bool fast9_region_detect
Decides whether to detect fast9 corners in specific regions of interest or the whole image (only for ...
#define OPTICFLOW_DEROTATION_CORRECTION_FACTOR_X
#define OPTICFLOW_KALMAN_FILTER_PROCESS_NOISE
uint16_t count
Number of times the point has been tracked successfully.
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 kalman_filter_opticflow_velocity(float *velocity_x, float *velocity_y, float *acceleration_measurement, float fps, float *measurement_noise, float kalman_process_noise, bool reinitialize_kalman)
Filter the velocity with a simple linear kalman filter, together with the accelerometers.
float derotation_correction_factor_x
Correction factor for derotation in x axis, determined from a fit from the gyros and flow rotation...
void opticflow_calc_frame(struct opticflow_t *opticflow, struct opticflow_state_t *cam_state, struct image_t *img, struct opticflow_result_t *result)
Run the optical flow 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
float kalman_filter_process_noise
Process noise of the model used in the kalman filter.
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 OPTICFLOW_KALMAN_FILTER
#define FAST9_LOW_THRESHOLD
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, uint16_t *roi)
Do a FAST9 corner detection.
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 derotation_correction_factor_y
Correction factor for derotation in Y axis, determined from a fit from the gyros and flow rotation...
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)