Racket detection and 5-keypoint pose estimation module, built on RTMDet (detection) and RTMPose (pose estimation) from the OpenMMLab ecosystem.
The module runs a two-stage pipeline:
- RTMDet-M detects racket bounding boxes (3 classes: badminton / tabletennis / tennis racket).
- RTMPose-M estimates 5 keypoints per detected racket:
top,bottom,handle,left,right.
RacketPose/
├── configs/
│ ├── detection/
│ │ ├── rtmdet_m_racket.py # Full training config
│ │ ├── rtmdet_m_racket_infer.py # Inference-only config (no _base_)
│ │ └── rtmdet_toy.py # Toy config for pipeline testing
│ ├── pose/
│ │ ├── rtmpose_m_racket.py # Full training config
│ │ ├── rtmpose_m_racket_infer.py # Inference-only config (no _base_)
│ │ └── rtmpose_toy.py # Toy config for pipeline testing
│ └── _base_/ # Shared base configs
├── checkpoints/
│ ├── epoch_300.pth # RTMDet pre-trained weights
│ └── best_PCK_epoch_90.pth # RTMPose pre-trained weights
├── datasets/ # Custom dataset classes
├── evaluation/ # Custom metrics
├── tools/
│ ├── train_detection.py # RTMDet training entry point
│ ├── train_pose.py # RTMPose training entry point
│ ├── test_detection.py # RTMDet evaluation entry point
│ ├── test_pose.py # RTMPose evaluation entry point
│ └── inference.py # Batch det+pose inference
└── README.md
RacketPose requires mmdet and mmpose (tested with mmengine==0.10.7, mmcv==2.1.0, mmdet==3.3.0, mmpose==1.3.2). Use the same uball conda environment as the rest of the project; see the repository README for installation instructions.
conda activate uball
python tools/train_detection.py configs/detection/rtmdet_m_racket.pypython tools/train_pose.py configs/pose/rtmpose_m_racket.pyBoth scripts use data_root from the config's _base_/datasets/ files. The default expects COCO-format annotations in data/info/.
python tools/test_detection.py configs/detection/rtmdet_m_racket.py \
--checkpoint checkpoints/epoch_300.pthpython tools/test_pose.py configs/pose/rtmpose_m_racket.py \
--checkpoint checkpoints/best_PCK_epoch_90.pthBoth test scripts load the checkpoint, disable training components, and run runner.test(). You can override config values with --cfg-options, e.g.:
python tools/test_detection.py configs/detection/rtmdet_m_racket.py \
--checkpoint checkpoints/epoch_300.pth \
--cfg-options test_dataloader.batch_size=16Run detection + pose estimation on all clips in a split:
python tools/inference.py \
--det_config configs/detection/rtmdet_m_racket_infer.py \
--det_ckpt checkpoints/epoch_300.pth \
--pose_config configs/pose/rtmpose_m_racket_infer.py \
--pose_ckpt checkpoints/best_PCK_epoch_90.pth \
--data_root ../data \
--sport badminton \
--split test \
--device cudaOutput: ../data/<sport>/pred_racket/<match>/<rally>/result.json
Each output JSON is a list of frames. Each frame contains a list of detected rackets:
[
[
{
"bbox": [[x1, y1, x2, y2]],
"bbox_score": 0.95,
"keypoints": [[x1, y1], [x2, y2], [x3, y3], [x4, y4], [x5, y5]],
"keypoint_scores": [0.9, 0.8, 0.7, 0.6, 0.5]
}
],
[],
...
]| Flag | Default | Description |
|---|---|---|
--sport |
badminton |
Target sport (badminton / tabletennis / tennis) |
--bbox_thr |
0.3 | Detection confidence threshold |
--device |
cuda |
cuda or cpu |
--debug |
off | Process only the first clip |
- Training configs (
rtmdet_m_racket.py,rtmpose_m_racket.py) use_base_inheritance and require dataset registration viaimport datasets. - Inference configs (
*_infer.py) are standalone single-file configs with no_base_dependencies. They useBNinstead ofSyncBNfor compatibility with single-GPU and CPU inference. - Detection uses
num_classes=3(one per sport's racket type), not 4.