lucas buchalla sestivalencia, spain +34 666 277 651rev. 2026 — applied ai / mobile systemsen/es
back to the portfolioresearch log — 14 measured phases

Player identity
in amateur football

Fourteen measured phases against one 55-minute match, trying to hold a player’s identity across a full game from a single fixed camera. Most of them failed. The failures are the point: each one is written up with the number that killed it, so it never gets run twice.

independent researchaug 2026 — presentyolo · osnet reid · pytorch · mpsfull log on github
415 ids
for 17 real people, in one 55-minute match
76.5%
of pairs inside a cluster are different people
0.952
pair auc, fine-tuned cnn — still unsolved
90.9%
of hand-labelled fragments contaminated

The problem

A fixed camera at the corner of a pitch, 4K, dusk, 8v8. The pipeline detects and tracks people frame by frame, then stitches the tracks back together. It ends a 55-minute match with 415 IDs for 17 real people. Team assignment works. Person identity does not.

Fragmentation is the visible symptom and it is not the real one. Nobody had measured the composition of the clusters the system already forms, because every early phase measured recall and never precision. When it was finally measured against human labels, 76.5% of the pairs inside a cluster turned out to be two different people. The system is fragmented and contaminated, and optimising recall alone would have made both worse.

The log

14 / 14

Same skeleton every time: hypothesis, what I changed, metric before and after, verdict, why. Four phases closed a line of work outright. Four improved a number without solving anything. One invalidated the labelling scheme that three earlier phases had been built on.

  1. 01ReID and trajectory in the stitching costdead endbaseline separation 5.0 beats every variant; no stable weight region
  2. 02Audit of 8 historical tracker errorslandedall eight are stitcher decisions over 6-16s gaps, not live association
  3. 03Six reacquisition experiments in the trackerdead endnet-gain category 0 of 32; one variant cascaded 1,995 → 14,350 events
  4. 04Can the stitcher recover more?dead end68 audited pairs: 1 same, 21 different, 46 information-limited
  5. 05First capture proposalsupersededright instinct, filed before the representation was exhausted
  6. 06Free labels from track halvespartialproduction feature measured at AUC 0.637; the labels later proved contaminated
  7. 0777 human pair labelslandedreal false-merge rate 76.5%; the automatic proxy ranked the features backwards
  8. 08Clustering with K=16 knownpartialcontamination 76.5% → 12% at 33% recall; 4-6 of 16 identities coherent
  9. 09Is a raw track one person?landedno — a third to a half swap person mid-track, which invalidates the phase 06 labels
  10. 10Confidence gate; handcrafted colour featurespartialteam consistency solved, person identity not; ReID beats every colour feature
  11. 11Visual judge on the undecided pairslandedfirst clean identities in the whole investigation: 3 of 16
  12. 12Global assignment + CNN fine-tuningpartialAUC 0.913 → 0.952, one identity correct, ceiling found: label quality
  13. 13Hand-labelling UI, 121 pairslanded90.9% contaminated, zero clean negatives — the distribution is the result
  14. 14The three swap-detection signalsdead endappearance points the wrong way, motion cannot exist, crowding is noise

Three things worth taking away

labels

The training was running on noise

The positives were two halves of the same track: free, plentiful, and principled-looking. Then a hand-labelled sample showed that a third to a half of raw tracks swap person mid-track, and that 90.9% of fragments contain more than one person. Every feature comparison built on those labels was measuring against noise, and it ranked the features in the wrong order — which only a human sample caught.

representation

A better model did not move the problem

ReID fine-tuned in-domain on 26,760 crops with InfoNCE and co-present same-team batches: AUC 0.913 → 0.952, curve still climbing at epoch 9. One identity out of sixteen came out correct. No training recipe beats a bad label, and the ceiling was the label rather than the network. A separate attempt to harden the positives dropped AUC to 0.439, below chance, which quantified the contamination for free.

the answer

The information is not in the video

A face is ~16px in this footage and face recognition needs 80-110px between the eyes. Shirt numbers are not legible. The only individual signal left in a crop is shorts and shoe colour, which does not separate teammates. The three signals that could detect a mid-track swap were each measured against human labels: appearance points the wrong way, motion cannot exist because the tracker forbids the jump, crowding is noise. That ends the algorithmic line and moves the work to capture — two overlapping 8K cameras, where the same player from two angles at the same instant is a clean positive label for free.

What landed

The virtual camera: turn a fixed wide shot into a crop that follows the action.

Two ideas did it. Offline video already has the future, so the causal predictor that was faking anticipation came out and the whole target series is smoothed non-causally instead. And aim at the mode, never the mean — a mean over a spread-out set regresses to the centre by construction, which is why fifteen versions were literally incapable of pointing at the attacking third.

25.1 → 3.7direction reversals per minute
653 → 457pxaim error vs 18 hand-labelled ball positions
34×lower rms acceleration

What happens next

The rig, and the measurements that can kill it.

Two separated masts do not frame the pitch at any realistic field of view — they cover 66-79%, and widening the lens leaves the near touchline uncovered, which is exactly where a player is largest. So both cameras go on one head, ten metres back from the centre of the touchline. The second camera is not there for resolution: the same player, at the same instant, from two angles is a proven positive label, free and with no human in the loop. That is the clean label all fourteen phases lacked.

1 mast
both cameras co-located on one head
10 m back
setback beats height — scale ratio 9.4× → 5.4×
4.0 m
lens height, 56% occlusion immunity
±35° yaw
100% coverage, 4 m overlap band at midfield
18° pitch
printed into the part, swappable at 15/21°
2 × 8K30
stabilisation off, ae/awb locked on the pitch
flash + clap
at start and end — clocks drift 1-2.7 frames in 30 min
3 guy lines
unguyed: 13px of blur on a 25px shirt number

Two things the plan does not promise. A legible shirt number over the whole pitch does not happen at this field of view: it happens over about two thirds of the area, so the number gets read when the player crosses the legible zone and the track carries it from there. And the largest risk is not mechanical — Samsung already blocks 4K60 from third-party apps, so 8K may not exist outside the vendor’s own camera app. That is the first measurement, it takes ten minutes, and it decides the rest.

Data and ethics

The footage is mine, recorded at matches I play in, with the players’ knowledge. I live in Spain, so GDPR applies: a person identifiable in an image is personal data, and re-identification by face touches biometric data. Recording for myself falls under the household exemption. Publishing does not.

So the repository holds no video, no frames and no crops, and it was started clean so none are in its history either. What it does publish is everything derived and non-identifying: the metric tables, the hand labels as IDs and timestamps, and figures drawn from those tables. The constraint costs almost nothing here — the central finding is a number, not a picture.

no footage · no frames · no crops · numbers only

Every number and every dead end is in the repository.

github.com/lucas-sesti/football-player-identity-investigation