CoolFace
Datasetpublic

caiotheodoro/cyclegraph-flow-gain

cyclegraph flow gain How much of a hand's motion a dense optical flow estimator actually recovers, and what it reports instead once it stops. Rendered under the corpus's own fisheye, where the true flow field is known exactly, which is the only reason a gain is measurable at all. The finding, in one line: past a displacement knee the estimator reports the background, at a gain equal to hand distance over background distance (0.45 / 2.5 = 0.18) — and the ego-motion correction… See the full description on the dataset page: https://huggingface.co/datasets/caiotheodoro/cyclegraph-flow-gain.

sourceHugging Faceapache-2.0updated 16d agoView on Hugging Face
0likes84downloads
Dataset Card

cyclegraph flow gain

How much of a hand's motion a dense optical flow estimator actually recovers, and what it reports instead once it stops. Rendered under the corpus's own fisheye, where the true flow field is known exactly, which is the only reason a gain is measurable at all.

The finding, in one line: past a displacement knee the estimator reports the background, at a gain equal to hand distance over background distance (0.45 / 2.5 = 0.18) — and the ego-motion correction that ought to catch this subtracts the background, so the error cancels into a small plausible number rather than a loud one.

Run it against your own estimator. The harness ships in this repository, needs numpy and nothing else, and needs no corpus, no token and no GPU.

python
from cyclegraph_flow_gain import gain_curve

def my_estimator(first, second):   # -> (H, W, 2) float32, or None on failure
    ...

curve = gain_curve(my_estimator, width=960)
print(curve.knee_px, curve.floor_gain, curve.floor_ratio_expected)
print(curve.verdict(operating_displacement_px=12.0))

Passing is not gain near 1.0 everywhere; no dense estimator does that. Passing is your knee sitting outside the displacements your work actually produces, which is why verdict() takes that displacement instead of assuming one.

The knee belongs to the estimator, the floor belongs to the geometry

Both files below share the 0.25 s pair baseline, so they compare directly.

hand displacementfarneback-cv2raft-small
22.794 px0.99250.9946
34.181 px0.20240.9738
45.539 px0.23230.32
68.025 px0.17730.1724

RAFT-small buys roughly one more doubling of usable displacement and lands on the same floor. A better estimator moves where the cliff is and does not touch what is underneath it.

Higher decode resolution is not better

At 0.236 of the hand box width, the same physical displacement at four decode sizes:

decode480x270960x5401440x8101920x1080
gain0.76560.99250.20360.1978

960x540 is a measured optimum. 1920x1080 does worse than 480x270.

The lens does most of the work

BENCHMARK_CARD.md carries the argument. Under pure rotation at 10 degrees per second the corpus fisheye leaves 10.0916 mm/s of apparent hand speed, where a narrow lens leaves 0.1328 mm/s. That is 76 times more from the same scalar-median subtraction, because rotational flow on a fisheye varies with radius and a scalar cannot cancel a field that does.

The exact-geometry residual is the control: 1.1461 px, computed closed-form with no estimator involved. farneback-cv2 reports 1.2171 px and raft-small reports 1.014 px — below the floor an ideal estimator would leave, which is under-recovery rather than accuracy.

Configs

configrowswhat one row is
displacement_gain18farneback, one decode scale and displacement, 0.25 s baseline
displacement_gain_raft18raft-small, same sweep and baseline
gain_by_resolution36farneback across four decode sizes, 0.0333333 s baseline
estimator_benchmark2one estimator: its A14 rotation residual against the exact-geometry floor
geometry_floor20closed-form apparent speed under one camera motion

On baselines. displacement_gain and displacement_gain_raft use the 0.25 s pair interval; gain_by_resolution uses the clip's own rate, 0.0333333 s. Displacements and gains are identical either way — the interval only rescales true_speed_mm_s. Compare estimators on hand_displacement_px and never across files on mm/s. Every row carries its own pair_interval_s.

What this cannot tell you

  • Whether a real hand crosses the knee. That depends on your frame rate and your work. The harness reports the knee for your geometry; it does not know your job.
  • Anything about the corpus. No corpus frame was decoded for any number here. The measurement cyclegraph exists to make is blocked on cost and one human step, and has not run.
  • Whether the ergonomic instrument is valid. No ergonomist scored anything.
  • The corpus's real ego-motion distribution. The floor table assumes a camera motion.
  • Whether synthetic texture behaves like factory video. The lens is the corpus's. The content is not.

The depth planes — 0.45 m and 2.5 m — are stated assumptions about workstation geometry, not measurements, and the floor sits at their ratio, so a different workstation gives a different floor. That is a prediction and it is untested.

Provenance and terms

Apache-2.0, as is builddotai/Egocentric-10K itself. The lens calibration is the vendor's published intrinsics.json, identical for all 2,144 shipped workers. ETHICS.md in this repository records the limit of what the licence settles:

Apache-2.0 is the vendor's licence to grant. It is not a worker's consent, and section 2 records that the consent instrument is unknown.

No frame, no worker, no factory and no pilot value appears in this release.

  • Repository, including what is blocked and why: https://github.com/caiotheodoro/cyclegraph
  • The data behind every table above, interactively: https://huggingface.co/spaces/caiotheodoro/cyclegraph