81 if (pyramid_level == 0) {
83 return opticFlowLK_flat(new_img, old_img, points, points_cnt, half_window_size, subpixel_factor, max_iterations,
84 step_threshold, max_points, keep_bad_points);
88 struct flow_t *vectors = calloc(max_points,
sizeof(
struct flow_t));
95 uint16_t border_size = padded_patch_size / 2 + 2;
98 struct image_t *pyramid_old = malloc(
sizeof(
struct image_t) * (pyramid_level + 1));
99 struct image_t *pyramid_new = malloc(
sizeof(
struct image_t) * (pyramid_level + 1));
102 pyramid_build(old_img, pyramid_old, pyramid_level, border_size);
103 pyramid_build(new_img, pyramid_new, pyramid_level, border_size);
106 struct image_t window_I, window_J, window_DX, window_DY, window_diff;
114 for (
int8_t LVL = pyramid_level; LVL != -1; LVL--) {
120 float skip_points = (points_orig > max_points) ? (
float)points_orig / max_points : 1;
123 for (
uint16_t i = 0; i < max_points && i < points_orig; i++) {
126 if (LVL == pyramid_level) {
128 vectors[new_p].
pos.
x = (points[
p].
x * subpixel_factor) >> pyramid_level;
129 vectors[new_p].
pos.
y = (points[
p].
y * subpixel_factor) >> pyramid_level;
130 vectors[new_p].
flow_x = 0;
131 vectors[new_p].
flow_y = 0;
135 vectors[new_p].
pos.
x = vectors[
p].
pos.
x << 1;
136 vectors[new_p].
pos.
y = vectors[
p].
pos.
y << 1;
143 || ((vectors[new_p].
pos.
x + vectors[new_p].
flow_x) > (
uint32_t)((pyramid_new[LVL].
w - 1 - 2 * border_size)*
146 || ((vectors[new_p].
pos.
y + vectors[new_p].
flow_y) > (
uint32_t)((pyramid_new[LVL].
h - 1 - 2 * border_size)*
148 if (keep_bad_points) {
158 image_subpixel_window(&pyramid_old[LVL], &window_I, &vectors[new_p].pos, subpixel_factor, border_size);
168 int32_t Det = (G[0] * G[3] - G[1] * G[2]);
172 if (keep_bad_points) {
183 for (
uint8_t it = max_iterations; it--;) {
190 if ((((
int32_t)vectors[new_p].pos.x + vectors[new_p].
flow_x) < 0)
191 || (new_point.
x > (
uint32_t)((pyramid_new[LVL].w - 1 - 2 * border_size)*subpixel_factor))
192 || (((
int32_t)vectors[new_p].pos.y + vectors[new_p].
flow_y) < 0)
193 || (new_point.
y > (
uint32_t)((pyramid_new[LVL].
h - 1 - 2 * border_size)*subpixel_factor))) {
204 if (error > error_threshold && it < max_iterations / 2) {
214 int16_t step_x = (((
int64_t) G[3] * b_x - G[1] * b_y) * subpixel_factor) / Det;
215 int16_t step_y = (((
int64_t) G[0] * b_y - G[2] * b_x) * subpixel_factor) / Det;
219 vectors[new_p].
error = error;
222 if ((abs(step_x) + abs(step_y)) < step_threshold) {
231 }
else if (keep_bad_points) {
232 vectors[new_p].
flow_x = 0;
233 vectors[new_p].
flow_y = 0;
249 for (
int8_t i = pyramid_level; i != -1; i--) {
291 struct flow_t *vectors = calloc(max_points,
sizeof(
struct flow_t));
302 struct image_t window_I, window_J, window_DX, window_DY, window_diff;
310 float skip_points = (points_orig > max_points) ? (
float)points_orig / max_points : 1;
313 for (
uint16_t i = 0; i < max_points && i < points_orig; i++) {
317 vectors[new_p].
pos.
x = points[
p].
x * subpixel_factor;
318 vectors[new_p].
pos.
y = points[
p].
y * subpixel_factor;
321 if (points[
p].x < half_window_size || (old_img->
w - points[
p].
x) < half_window_size
322 || points[
p].
y < half_window_size || (old_img->
h - points[
p].
y) < half_window_size) {
323 if (keep_bad_points) {
342 int32_t Det = (G[0] * G[3] - G[1] * G[2]) / subpixel_factor;
346 if (keep_bad_points) {
360 for (
uint8_t it = 0; it < max_iterations; it++) {
367 if (new_point.
x / subpixel_factor < half_window_size || (old_img->
w - new_point.
x / subpixel_factor) <= half_window_size
368 || new_point.
y / subpixel_factor < half_window_size || (old_img->
h - new_point.
y / subpixel_factor) <= half_window_size
369 || new_point.
x / subpixel_factor > old_img->
w || new_point.
y / subpixel_factor > old_img->
h) {
380 if (error > error_threshold && it > max_iterations / 2) {
389 int16_t step_x = (G[3] * b_x - G[1] * b_y) / Det;
390 int16_t step_y = (G[0] * b_y - G[2] * b_x) / Det;
391 vectors[new_p].
flow_x += step_x;
392 vectors[new_p].
flow_y += step_y;
393 vectors[new_p].
error = error;
396 if ((abs(step_x) + abs(step_y)) < step_threshold) {
405 }
else if (keep_bad_points) {
406 vectors[new_p].
flow_x = 0;
407 vectors[new_p].
flow_y = 0;