Training new YOLO models and integrating them

EDIT - I’m going to put my process at the bottom ofthis post.

Starting a new thread for this.

Using google ai, I’ve managed to run some YOLO models training on datasets from Roboflow, and convert them to onnx files.

The issue comes with then using them in the video stitcher, likely due to classes etc not aligning or similar. How can I take a yolo model I’ve trained to track a rugby ball, and successfully use it in the software?


How I made a model (couple of options).

Firstly a disclaimer. I’m comfortable with computers, but I am not a programmer, I’ve tinkered here and there, but absolute minimum basics. 95% of what I did ,was done asking Google AI for instructions. Using Googles AI results, as well as Roboflow, I’ve managed to build a few models now. I have no doubt someone with actual knowledge could do much better/quicker etc.

First thing is the dataset. You need images that have your target boxed up (annotated). Using the roboflow universe I found a few that fit my needs ( https://universe.roboflow.com/ ).

I’m using YOLO26 since it’s apparently the most advanced one yet. I’ve also just switched to using the Small version rather than the Nano, since the small has a lot more detection layers. It takes longer to use, but gives better results.

I logged in, created a project, and started adding datasets to my asset library. Then I trimmed the dataset to only contain information I needed (so only those with balls boxed, not those with players/refs etc also boxed). I then saved this to my new project. I then modified it’s class names, so instead of ball, rugbyball, rugby ball etc, they all were ball.

Roboflow then literally has models that you can train on their website. You get so many free credits per month from what I can tell. I used Google AI to suggest what settings I needed to get the best results. As I was trying to detect a rugby ball, that included making the image size larger than normal, and not using something called “mosaic”, I suggest anyone doing ball training does the same. Unfortunately I used a Nano model instead of a Small one, so it didn’t work that well, and now I don’t have enough credits until next month I suspect! Using roboflow is completely set and forget for training which is nice. No programming skills required.

Next option is Google Colab. Using gemini, I got the instructions for how to run a Yolo26 training on this. Make sure you select the runtime type of T4 GPU before you do anything else at all. Google’s AI doesn’t always give you the instructions in the correct order, so read through first.

The AI literally gave me the programming code I needed to paste into Google Colab to get it all going. The only bit that came from elsewhere, is the dataset info from roboflow, and they gave me the code I needed anyway.

In google colab, you do need to keep the tab open and need to visit it fairly frequently preventing it shutting down. You should get 4 hours free no issue, and then upto 12 hours, but apparently you can shutdown, so try and keep things within the 4 hours for training. I found 50 epochs (number of times it goes over the images) to be a good number at the speed it was going.

TLDR: Use Googles AI to instruct you in how to train a YOLO model.

Hey, thanks for trying to improve the AI. It’s one of the best ways the community can help at Reco’s current stage.

Since you trained YOLO26, your ONNX export is already in the format Reco wants, so that’s not your problem. Reco looks for a class named literally ball (or sports ball), case-insensitive, no partial matching. Roboflow usually names it something like rugby-ball, which doesn’t match. Reco then falls back to COCO id 32 while your model only outputs id 0, so you get zero detections and just a warning in the log:

Class 'ball' not found in model labels; using COCO default id 32

Fix it at export: model.names = {0: "ball"}, or {0: "ball", 1: "person"} if you also train players. You can probably patch the exported file too.

To check what your model actually declares:

import onnx

m = onnx.load("model.onnx")

print([p.value for p in m.metadata_props if p.key == "names"])

print([d.dim_value for d in m.graph.output[0].type.tensor_type.shape.dim]) # want [1, N, 6]

If you want to sanity check, grab yolo26n.onnx from the v0.5.2 release and run it with --tracking field. This one should work.

On tracking mode: --tracking field (the default) follows ball + players; --tracking ball follows the ball alone. If your model only has a ball class, pass --tracking ball explicitly. Field mode won’t fall back gracefully.

And don’t worry about mixed kit, player detection doesn’t care what people wear. Kit only matters for assigning players to teams, which Reco doesn’t do; it just uses the player cluster to frame the shot. Kits is important and practical for analysis, which will come once we will have good tracking.

Do not hesitate to checkout the logs, and use the .jsonl exports to see exactly the detections. There is a python script in the repo that will allow you to visualise the detections, and make sure all is working well.

Thank you, and please let me know if you have any issues. If so, please share your training pipeline, especially how it gets exported. I also understand that all of this is far from convenient, and it will eventually become much more robust, simple, and extensible.

1 Like

I plan on putting up my process soon, but until I actually get some positive results, I don’t see the point just yet :D. I will edit the first post once I do.

In the meantime, what effect would using a YOLO small, rather than nano, have on the reco software when exporting? I’m aware it’ll be harder to run it on google colab, but want to know the impact on the export for reco too, if any?

I’m asking because yolo small seems to be more recommended for something as exacting as ball tracking (especially as the ball can be small and awkward to detect).

EDIT - I think using YOLO small (from what I understand) is pretty much required for ball tracking. Nano simply cannot get the accuracy, Small can apparently use more contextual clues too.

So I’ve trained a Small model (going to try and continue I think).

It does actually follow the ball fairly frequently. Still misses it and the action a bit, but it is actually tracking, which is a huge improvement over the nano. Even though the MAP50 values are very similar, the Small model is much better, maybe some more training will help further.

I’m going to add the process I used in the opening post.

I realise at the moment there’s only weighting for Person and Ball. Is it easy to add more? Could that be opened up in the Advanced tab where the weighting can be edited? For now Cluster mode, with a high weighting to the ball, could probably do the job for rugby with rucks/mauls.

Guess I need to train another model detecting both ball and person.

1 Like

What other weights do you want to add/change? Because you aren’t adding a new class right? Also, I recommend you use CLI to iterate fast.

Sounds promising, keep up the good work!

Here’s where my ignorance comes in :smiley: what do you mean by CLI?

I’d like to add other classes if possible, I have no idea on how complex this would be though.

For now, person and ball is probably enough, so don’t worry about it.

Unfortunately the footage I’m using has a large group of people stood outside of the pitch in the middle (far side), and the players aren’t wearing kit. So training a model on the datasets I’ve found, probably won’t work that well, but I’m going to give it a go. With the weighting favouring the ball quite heavily.

First up will be trying to train the ball tracking model further though I think.

Don’t forget that Reco supports a field ROI, which can filter detections outside the pitch when it is correctly configured.

CLI means Command Line Interface. It is the terminal version of Reco rather than the desktop app (GUI: Graphical User Interface). It is useful for testing the same footage repeatedly with different models and tracking settings:

reco stitch left.mp4 right.mp4 -c calibration.json -o test.mp4 --model rugby.onnx --tracking field --panner-config rugby.json

rugby.json could initially contain:

{"ball_weight": 0.8}

For rugby, I would start with field mode, a high ball_weight, and a model that detects both the ball and players. You probably do not need kit or team classification for camera framing. A correctly configured ROI should remove most spectators outside the pitch.

Also consider YOLO inference resolution. For a small rugby ball, input resolution can matter as much as, or more than, choosing Nano versus Small.

The tracking stack is:

  1. YOLO detects objects and returns classes, boxes, and confidence.

  2. ROI filtering removes off-field detections.

  3. Coordinate mapping converts detections into panorama positions.

  4. Trackers reject noise and maintain ball/player state across frames.

  5. The panner converts that state into camera pan, tilt, and zoom.

  6. The renderer applies that pose to the stitched panorama.

ball_weight is a panner setting, not a YOLO model weight. It controls how strongly the ball influences the virtual camera.

Adding a new YOLO class only makes Reco detect it. For that class to affect framing, Reco also needs tracking/state support and panner logic describing what the camera should do with it.

Every field-panner setting can be overridden through the JSON configuration. Some lower-level detector and tracker settings still require code changes. The code is modular, so those changes should remain localized.

Building the CLI from source requires more setup than the GUI , including Rust and FFmpeg development libraries. Also, making this stack clearer and easier to configure is one of the goals of v0.6.0.