Production-oriented, low-latency ball detection + trajectory prediction with angle output for Arduino control.
camera.pycapture thread (low latency)roi.py4-point ROI + perspective warp (save/load)mask.pyHSV masking + color pick helperdetection.pycontour filtering (area + circularity)tracking.pyconstant-velocity Kalman tracker + trajectory historyprediction.pylinear lookahead predictiongeometry.pyangle calculationserial_out.pynon-blocking Arduino serial outputui.pyTkinter UI + vision worker threadmain.pyentry point
- Activate your venv (recommended):
venv\\Scripts\\activate
- Install dependencies:
pip install -r requirements.txt
- (Optional) Setup config:
- Copy
config.example.jsontoconfig.jsonto start with default values.
- Copy
- Run:
python main.py
Builds a portable folder you can copy to another laptop.
.\build.ps1Output:
dist\BallTracker\BallTracker.exe
Copy to another PC:
- Copy the whole
dist\BallTracker\folder (not only the.exe).
- Click Reset ROI (click 4 points).
- Click 4 corners of the playfield / goal plane in the camera view.
- The app switches to Tracking mode and processes only the warped ROI output.
Two options:
- Manual sliders: adjust
H/S/V min/maxuntil the ball is isolated in the mask thumbnail. - Pick color on click: enable, then click on the ball in the tracking view to auto-set HSV.
- Enable Set reference point on click, then click the desired point in the tracking view.
- Or press Center reference to use the ROI center.
- Select COM port + baud → Connect
- The app sends:
A:<angle>\\n(integer degrees)
Settings are stored in config.json (auto-saved on exit):
- Camera settings
- ROI points
- HSV range
- Detection thresholds
- Prediction lookahead
- Reference point
- Serial port + baud
Example config.json keys:
camera.index,camera.width,camera.heighthsv.h_min...hsv.v_maxdetection.min_area,detection.max_area,detection.min_circularityprediction.enabled,prediction.lookahead_sreference_point(in ROI output coordinates)roi.points(4 points in camera image coordinates)
- Choose ROI corners on a planar surface that matches the robot’s control frame.
- Use a stable camera mount; avoid wide-angle distortion if possible.
- Keep lighting stable; if lighting changes, re-pick HSV.
Practical tips:
- Pick ROI points on a rectangle that corresponds to the goal plane / field plane.
- ROI clicks can be in any order (the code orders them internally).
- If your camera feed is mirrored/rotated by drivers, fix that first (OpenCV capture), then calibrate ROI.
The app sends ASCII lines like:
A:45\\n
Minimal Arduino sketch (reads one line and parses the angle):
String line;
void setup() {
Serial.begin(115200);
}
void loop() {
while (Serial.available()) {
char c = (char)Serial.read();
if (c == '\\n') {
if (line.startsWith("A:")) {
int angle = line.substring(2).toInt();
// TODO: map angle -> servo/motor command
}
line = "";
} else if (c != '\\r') {
line += c;
}
}
}- Black UI / no video: ensure camera index is correct (edit
config.json→camera.index). - Low FPS: reduce camera resolution in
config.json(e.g. 640x480). - Ball not detected:
- Use Pick mode and click the ball
- Increase
detection.min_areaor relaxdetection.min_circularity
- Serial connect fails:
- Install driver (CH340/CP210x depending on your board)
- Ensure no other app is using the COM port