nx_motion.nx
buildroot/runtime/nx_motion.nx
about
nx_motion.nx -- frame-to-frame motion (Lucas-Kanade optical flow).
Brightness-constancy + small-motion assumption:
I(x, y, t) = I(x + u, y + v, t + 1)
Taylor expand:
I_x * u + I_y * v + I_t = 0
Over an N-pixel window this is N equations in 2 unknowns; solve
via 2x2 least-squares (normal equations + Cramer's rule).
What this unlocks:
+ motion detection (frame diff)
+ tracking (per-pixel flow vectors)
+ camera-motion estimation (mean flow direction)
+ scene-cut detection (flow magnitude spike)
+ activity recognition substrate
Returns flow in Q8 sub-pixel precision (1 unit = 1/256 pixel).
5x5 integration window default.
genealogy_id: lucas_kanade_1981 + horn_schunck_1981
lineage_id: gradient_based_optical_flow + 2x2_least_squares
dependencies 2 imports · 3 importers
imports: syscalls.nxnx_image.nx
imported by: nx_dynaoracle.nxnx_dynaoracle_gate.nxnx_motion_test.nx
structs
| 97 | struct FlowField |
| 323 | struct MotionPyr |
consts
| 32 | const NX_MOTION_Q: i64 = 256 // Q8 sub-pixel |
| 33 | const NX_MOTION_WIN: i64 = 5 // 5x5 integration |
| 40 | const NX_MOTION_LK_DOMAIN_Q8: i64 = (NX_MOTION_WIN / 2) * NX_MOTION_Q |
| 321 | const NX_MOTION_PYR_MAX: i64 = 6 |
| 334 | const NX_MOTION_PYR_BYTES: i64 = 72 |
functions
| 46 | func nx_motion_frame_diff(a: *Image, b: *Image) -> *Image |
| 71 | func nx_motion_temporal_grad_into(frame1: *Image, frame2: *Image, dst: *ImageS64) -> *ImageS64 called by 2: nx_motion_lucas_kanade_intonx_motion_temporal_grad calls 2: nx_image_getnx_image_s64_set |
| 109 | func nx_motion_lucas_kanade_into(frame1: *Image, frame2: *Image, |
| 212 | func nx_motion_mean_flow_rect_bounded(flow: *FlowField, mag_threshold: i64, max_mag_q8: i64, |
| 269 | func nx_motion_mean_flow_rect(flow: *FlowField, mag_threshold: i64, |
| 278 | func nx_motion_mean_flow(flow: *FlowField, mag_threshold: i64, |
| 290 | func nx_motion_temporal_grad(frame1: *Image, frame2: *Image) -> *ImageS64 |
| 295 | func nx_motion_lucas_kanade(frame1: *Image, frame2: *Image) -> *FlowField |
| 339 | func nx_motion_pyr_levels(w: i64, h: i64) -> i64 called by 1: nx_motion_pyr_new |
| 355 | func nx_motion_pyr_new(w: i64, h: i64) -> *MotionPyr |
| 387 | func nx_motion_copy_into(src: *Image, dst: *Image) -> *Image |
| 402 | func nx_motion_mean_flow_pyr(p: *MotionPyr, f1: *Image, f2: *Image, mag_threshold: i64, |