67 struct flow_t *vectors = malloc(
sizeof(
struct flow_t) * max_points);
73 uint16_t patch_size = 2 * half_window_size;
74 uint32_t error_threshold = (25 * 25) *(patch_size *patch_size);
75 uint16_t padded_patch_size = patch_size + 2;
78 struct image_t window_I, window_J, window_DX, window_DY, window_diff;
86 float skip_points = (points_orig > max_points) ? points_orig / max_points : 1;
89 for (
uint16_t i = 0; i < max_points && i < points_orig; i++) {
93 if (points[p].x < half_window_size || (old_img->
w - points[p].
x) < half_window_size
94 || points[
p].
y < half_window_size || (old_img->
h - points[
p].
y) < half_window_size) {
99 vectors[new_p].
pos.
x = points[
p].
x * subpixel_factor;
100 vectors[new_p].
pos.
y = points[
p].
y * subpixel_factor;
101 vectors[new_p].
flow_x = 0;
102 vectors[new_p].
flow_y = 0;
115 int32_t Det = (G[0] * G[3] - G[1] * G[2]) / subpixel_factor;
127 bool_t tracked =
TRUE;
128 for (
uint8_t it = 0; it < max_iterations; it++) {
134 if (new_point.
x / subpixel_factor < half_window_size || (old_img->
w - new_point.
x / subpixel_factor) < half_window_size
135 || new_point.
y / subpixel_factor < half_window_size || (old_img->
h - new_point.
y / subpixel_factor) < half_window_size) {
145 if (error > error_threshold && it > max_iterations / 2) {
154 int16_t step_x = (G[3] * b_x - G[1] * b_y) / Det;
155 int16_t step_y = (G[0] * b_y - G[2] * b_x) / Det;
156 vectors[new_p].
flow_x += step_x;
157 vectors[new_p].
flow_y += step_y;
160 if ((abs(step_x) + abs(step_y)) < step_threshold) {
void image_gradients(struct image_t *input, struct image_t *dx, struct image_t *dy)
Calculate the gradients using the following matrix: [0 -1 0; -1 0 1; 0 1 0].
uint16_t x
The x coordinate of the point.
uint32_t image_difference(struct image_t *img_a, struct image_t *img_b, struct image_t *diff)
Calculate the difference between two images and return the error This will only work with grayscale i...
void image_free(struct image_t *img)
Free the image.
void image_create(struct image_t *img, uint16_t width, uint16_t height, enum image_type type)
Create a new image.
int16_t flow_x
The x direction flow in subpixels.
struct point_t pos
The original position the flow comes from.
efficient fixed-point optical-flow calculation
Grayscale image with only the Y part (uint8 per pixel)
uint16_t y
The y coordinate of the point.
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, uint16_t max_points)
Compute the optical flow of several points using the Lucas-Kanade algorithm by Yves Bouguet The initi...
void image_calculate_g(struct image_t *dx, struct image_t *dy, int32_t *g)
Calculate the G vector of an image gradient This is used for optical flow calculation.
void image_subpixel_window(struct image_t *input, struct image_t *output, struct point_t *center, uint16_t subpixel_factor)
This outputs a subpixel window image in grayscale Currently only works with Grayscale images as input...
An image gradient (int16 per pixel)
int16_t flow_y
The y direction flow in subpixels.
int32_t image_multiply(struct image_t *img_a, struct image_t *img_b, struct image_t *mult)
Calculate the multiplication between two images and return the error This will only work with image g...