Everyframe · computer vision

Reading one motion.

A pose-driven pipeline that watches one golf swing, finds address, top, impact and finish from the hands, and measures the tempo golfers quote as 3 to 1. Then the analysis edits the clip: the downswing plays at quarter speed, cut at the frames the detector found.

0 swings read pipeline pose → phases → edit 17-keypoint RTMPose four phases, hands only the analysis cuts the video
01

The swing, live

One swing as the engine returns it: skeleton burned on, the phase named as it happens, the tempo revealed at impact, and the downswing stretched to quarter speed. Under it, the hands' height the detector read, with the four phases marked. The scope runs in source time; the video runs in the engine's edit, and the playhead maps between the two.

setup phase
0.000 s source time
tempo

Hands height · address, top, impact, finish marked

Height is the hands' offset above the hips, divided by the torso length, so the distance to the camera cancels. Tempo is the backswing (address to top) over the downswing (top to impact). Top is the moment the hands start down in earnest; the club reverses a little after the hands peak, so this is the closer reading.

02

Ranked by tempo

Every swing the pipeline read, sorted by tempo. Backswing and downswing are frame counts divided by the frame rate; the ratio is the number a golfer already knows. A swing the detector could not settle (address or finish cut off, a second swing in the file) says so instead of pretending.

Swing View Backswing Downswing Tempo Read
03

Two swings, aligned at the top

Click either clip and both play from one second before their own top, so the downswings start together. Everything after that is the difference the tempo number describes.

04

The pipeline

Three stages. Perception and the edit run inside the Everyframe engine; reading the phases is plain signal processing on the extracted joints, the same shape as the rep-counting showcase.

1

Perceive Everyframe

Person detection, then top-down pose per person, then one skeleton record per frame through sink_pose_jsonl . The recipe is the rep-counting one, unchanged.

// examples/ai/golf_extract_pose.rs
let dets    = detect_with(&v, "dfine_l_coco", …);   // person boxes
let persons = filter_detections(dets, "person");
let poses   = estimate_pose_detections(&v, persons,
                  "rtmpose-m", …)?;                // 17 COCO keypoints
sink_pose_jsonl("pose.jsonl", poses);            // one line per frame
2

Read signal processing

The hands are the mean of both wrists, relative to the hips and divided by the torso length. The swing is anchored where the hands fall fastest, which only a downswing does; the other three phases follow from that anchor. No learned model, no per-golfer rules.

# golf_phases.py
fall    = fall_rate(height)              # how fast the hands drop
impact  = lowest hands inside the fastest fall
address = hands leave their settled spot before it
top     = hands start down in earnest
finish  = hands held high after impact
tempo   = (top - address) / (impact - top)
3

Edit Everyframe

Back in the engine: the skeleton is drawn on the original frames, each phase name is a drawtext gated to its window, and speed_ramp plays top to impact at a quarter of the speed. Every boundary comes from the detector's output; nothing is typed by hand.

// examples/ai/golf_label.rs
v = v.try_pipe(draw_skeleton_with(poses, …))?;
for (text, a, b) in phases {               // time-gated labels
  v = v.pipe(drawtext(DrawText { text, enable: between(t,a,b), … }));
}
v = v.pipe(speed_ramp(&[                   // the edit, from the numbers
  (top, 1.0), (impact - top, 0.25), (rest, 1.0),
]));
05

What it does not do

The page states what the pipeline measured and nothing past it. Four limits worth knowing before reading the numbers as more than they are.

No club, no ball

The pose model has 17 body joints and none for a club or a ball. Club path, face angle, ball speed and launch angle are not measured here and are not claimed.

Frame rate is the gate

Impact is known to within one frame: about 4 ms at 240 fps, 33 ms at 30 fps. A downswing lasts a quarter of a second, so at 30 fps the tempo ratio is coarse. Film fast or read the number as a range.

Consistency, not anatomy

Every number is 2D from a fixed camera and normalised by torso length. Two swings from the same spot compare cleanly; a joint angle in degrees is not on offer from one lens.

Hands, not club

Top is where the hands start down in earnest. The club reverses a little later, so the ratio here runs slightly under a club-timed one. It is stated the same way for every swing, which is what a ranking needs.