# Detecting court keypoints from a pickleball video

**URL:** <https://community.ultralytics.com/t/detecting-court-keypoints-from-a-pickleball-video/1703>\
**Category:** Support\
**Tags:** troubleshooting, question, yolo, support\
**Created:** [December 20, 2025, 6:08pm UTC](https://community.ultralytics.com/t/detecting-court-keypoints-from-a-pickleball-video/1703 "2025-12-20T18:08:07Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![kunal](https://sea1.discourse-cdn.com/flex001/user_avatar/community.ultralytics.com/kunal/32/1210_2.png) [@kunal](https://community.ultralytics.com/u/kunal)\
**Post date:** [December 20, 2025, 6:08pm UTC](https://community.ultralytics.com/t/detecting-court-keypoints-from-a-pickleball-video/1703/1 "2025-12-20T18:08:07Z")

</div>

I am trying to train a Yolov8 model to detect the keypoints of a pickleball court. I have annotated a [dataset](https://app.roboflow.com/pb-rrerm/pb-9bsin/browse) of 2000 images (1920 x 1080) which I have split into 1400 train - 400 valid - 200 test.

In addition I applied the following preprocessing and augmentation methods to my dataset:

- Preprocessing: Auto-Orient, Resize: Fit within 640x640
- Augmentations: Outputs per training example: 2, Grayscale: Apply to 25% of images, Hue: Between -25° and +25°

I trained a Roboflow 3.0 Keypoint Detection (Accurate) model on the platform itself and got fairly good [results](https://app.roboflow.com/pb-rrerm/pb-9bsin/models/pb-9bsin/3). However, when I trained my custom Yolov8-pose model on this dataset, it is performing terribly, as visible in the screenshot below:

 ![image](https://us1.discourse-cdn.com/flex001/uploads/ultralytics1/original/2X/6/69b6fe944a506db8d3c59ed9055b60eba452973d.jpeg)

My code for training the model:

from ultralytics import YOLO

model = YOLO(‘yolov8l-pose.pt’)

results = model.train(  
data = ‘/content/PB-3/data.yaml’,  
epochs=100,  
imgsz=640,  
device=0,  
batch=16)

My code for detecting keypoints in my video:

model = YOLO(‘models/court\_best\_2.pt’) # Load the pre-trained YOLOv8l-pose model

model.predict(source=r’file.jpg’, save=True, device=0)

Can someone please explain where I am going wrong in my approach and how can I improve on this? Thanks in advance!

---

<div class="post-metadata">

**Author:** ![Toxite](https://sea1.discourse-cdn.com/flex001/user_avatar/community.ultralytics.com/toxite/32/123_2.png) [@Toxite](https://community.ultralytics.com/u/Toxite)\
**Post date:** [December 21, 2025, 11:37am UTC](https://community.ultralytics.com/t/detecting-court-keypoints-from-a-pickleball-video/1703/2 "2025-12-21T11:37:00Z")

</div>

Can you post your data.yaml file?

Are all the keypoints consistent? They appear in the same position everytime.

---

<div class="post-metadata">

**Author:** ![kunal](https://sea1.discourse-cdn.com/flex001/user_avatar/community.ultralytics.com/kunal/32/1210_2.png) [@kunal](https://community.ultralytics.com/u/kunal)\
**Post date:** [December 21, 2025, 6:00pm UTC](https://community.ultralytics.com/t/detecting-court-keypoints-from-a-pickleball-video/1703/3 "2025-12-21T18:00:50Z")

</div>

My data.yaml:

flip\_idx:

- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11  
kpt\_shape:
- 12
- 3  
names:
- kps  
nc: 1  
roboflow:  
license: CC BY 4.0  
project: pb-9bsin  
url: [https://universe.roboflow.com/pb-rrerm/pb-9bsin/dataset/3](https://universe.roboflow.com/pb-rrerm/pb-9bsin/dataset/3)  
version: 3  
workspace: pb-rrerm  
test: ../test/images  
train: ../train/images  
val: ../valid/images

Yes all the keypoints are consistent, you can check out this embedded [link](https://app.roboflow.com/pb-rrerm/pb-9bsin/browse) to view my annotated dataset.

---

<div class="post-metadata">

**Author:** ![Toxite](https://sea1.discourse-cdn.com/flex001/user_avatar/community.ultralytics.com/toxite/32/123_2.png) [@Toxite](https://community.ultralytics.com/u/Toxite)\
**Post date:** [December 21, 2025, 6:21pm UTC](https://community.ultralytics.com/t/detecting-court-keypoints-from-a-pickleball-video/1703/4 "2025-12-21T18:21:37Z")

</div>

The `flip_idx` is incorrect:

> <https://github.com/ultralytics/ultralytics/issues/17736#issuecomment-2495671651>
>
> \### Search before asking
> 
> \- \[X\] I have searched the Ultralytics YOLO \[issues\](ht…tps://github.com/ultralytics/ultralytics/issues) and \[discussions\](https://github.com/ultralytics/ultralytics/discussions) and found no similar questions.
> 
> 
> \### Question
> 
> Hello.
> 
> I have a dataset of labeled objects. Skeletons consist of 13 points, so when training the model (yolo pose) I can determine the property:
> 
> flip\_idx: \[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12\]
> 
> However the objects are symmetrical so I want to define the property like this:
> 
> flip\_idx: \[0, 1, 2, 3, 4, 7, 5, 8, 6, 10, 9, 12, 11\]
> 
> 
> Because points 5 and 7, 6 and 8, 9 and 10, 11 and 12 are symmetrical.
> 
> Is it possible to do this? Or should symmetrical points have sequential numbers? For example, in my case, 9 and 10 are symmetrical points with sequential numbers, and 5 and 7 are symmetrical, but not sequentially numbered.
> 
> \### Additional
> 
> \_No response\_

---

<div class="post-metadata">

**Author:** ![kunal](https://sea1.discourse-cdn.com/flex001/user_avatar/community.ultralytics.com/kunal/32/1210_2.png) [@kunal](https://community.ultralytics.com/u/kunal)\
**Post date:** [December 21, 2025, 6:56pm UTC](https://community.ultralytics.com/t/detecting-court-keypoints-from-a-pickleball-video/1703/5 "2025-12-21T18:56:36Z")

</div>

I am unable to understand what’s being discussed, what does it mean when the user says points 5 and 7 are symmetrical?

---

<div class="post-metadata">

**Author:** ![kunal](https://sea1.discourse-cdn.com/flex001/user_avatar/community.ultralytics.com/kunal/32/1210_2.png) [@kunal](https://community.ultralytics.com/u/kunal)\
**Post date:** [December 21, 2025, 7:40pm UTC](https://community.ultralytics.com/t/detecting-court-keypoints-from-a-pickleball-video/1703/6 "2025-12-21T19:40:18Z")

</div>

I just read up on how the yolov8-pose training includes flipping the images horizontally and this is what the flip\_idx is for. Given my annotations, how can I find out which integer idx (0,1,2…) corresponds to the respective court key points?

DeepSeek recommend training a model with fliplr = 0.0 since all my images have been taken just from the behind the baseline angle. Is this recommended?

---

<div class="post-metadata">

**Author:** ![Toxite](https://sea1.discourse-cdn.com/flex001/user_avatar/community.ultralytics.com/toxite/32/123_2.png) [@Toxite](https://community.ultralytics.com/u/Toxite)\
**Post date:** [December 21, 2025, 11:36pm UTC](https://community.ultralytics.com/t/detecting-court-keypoints-from-a-pickleball-video/1703/7 "2025-12-21T23:36:38Z")

</div>

> [@kunal](#):
>
> Given my annotations, how can I find out which integer idx (0,1,2…) corresponds to the respective court key points?

That depends on the labelling tool you used. Probably based on the order you labelled the keypoints. The first keypoint you labeled is 0, second is 1 and so on.

This is why asked if your keypoints are consistent. By consistency, I was referring to each keypoint always being used for the same visual point. The order of keypoints is important. You can’t use inconsistent or arbritrary order, like the first keypoint you label is top left corner in one image, but in the next image, the first keypoint is top right. This is inconsistent and wouldn’t work.

`flip_idx` is used to fix the keypoints when horizontal and vertical flip augmentations are applied. For the same reason mentioned before, i.e., the order of keypoints is important, so after flipping if the keypoint that’s in top left becomes top right, it should be swapped because visually, top left looks like top right after flipping horizontally, so the keypoint indices are also swapped, otherwise it will make the labels inconsistent. The keypoints are visually tied to a dedicated location. They are not arbritrary or random.

You can use `fliplr=0`, but if your keypoint order isn’t consistent, then it will still cause issue.

---

<div class="post-metadata">

**Author:** ![kunal](https://sea1.discourse-cdn.com/flex001/user_avatar/community.ultralytics.com/kunal/32/1210_2.png) [@kunal](https://community.ultralytics.com/u/kunal)\
**Post date:** [December 22, 2025, 7:57am UTC](https://community.ultralytics.com/t/detecting-court-keypoints-from-a-pickleball-video/1703/8 "2025-12-22T07:57:20Z")

</div>

I used Roboflow itself to annotate these images. And yes, my keypoints are consistent throughout the images - to annotate them I had to draw the skeleton on the images and drag each point to the respective point on the court. I have figured out the order of the points:

0 - background baseline left

1 - background baseline mid

2 - background baseline right

3 - background kitchen-line right

4 - background kitchen-line mid

5 - background kitchen-line left

6 - foreground kitchen-line left

7 - foreground kitchen-line mid

8 - foreground kitchen-line right

9 - foreground baseline right

10 - foreground baseline mid

11 - foreground baseline left

Which indices will get flipped for my use case?

---

<div class="post-metadata">

**Author:** ![pderrenger](https://sea1.discourse-cdn.com/flex001/user_avatar/community.ultralytics.com/pderrenger/32/73_2.png) [@pderrenger](https://community.ultralytics.com/u/pderrenger)\
**Post date:** [December 23, 2025, 12:41am UTC](https://community.ultralytics.com/t/detecting-court-keypoints-from-a-pickleball-video/1703/9 "2025-12-23T00:41:55Z")

</div>

For your keypoint ordering, a horizontal flip should only swap left/right points within the same “background” or “foreground” line. Your “mid” points stay the same.

So your `flip_idx` should be:

```yaml
kpt_shape: [12, 3]
flip_idx: [2, 1, 0, 5, 4, 3, 8, 7, 6, 11, 10, 9]
names:
  0: court

```

This matches how `flip_idx` is intended to work for pose (left-right symmetric keypoints get exchanged during `fliplr` augmentation), as described in the [pose dataset YAML format docs](https://docs.ultralytics.com/datasets/pose/).

If all your videos are always shot from the same baseline side and you _never_ expect mirrored views, setting `fliplr=0.0` is reasonable (and then `flip_idx` won’t matter during training). But even with `fliplr=0.0`, you still need consistent keypoint ordering (which you have).

If results are still “terrible” after fixing this, the next quick sanity check is to open the training mosaic/label preview images saved in your run folder and confirm the rendered keypoints land exactly on the court corners/lines (this catches any export/resize/orientation mismatch from the dataset pipeline).

---

<div class="post-metadata">

**Author:** ![kunal](https://sea1.discourse-cdn.com/flex001/user_avatar/community.ultralytics.com/kunal/32/1210_2.png) [@kunal](https://community.ultralytics.com/u/kunal)\
**Post date:** [December 23, 2025, 12:48pm UTC](https://community.ultralytics.com/t/detecting-court-keypoints-from-a-pickleball-video/1703/10 "2025-12-23T12:48:58Z")

</div>

Thank you @pderrenger @Toxite , I’m getting much better performance after setting fliplr = 0.0. Setting pose = 24.0 also helped significantly.

 ![image](https://us1.discourse-cdn.com/flex001/uploads/ultralytics1/original/2X/8/8ae29be3098fe9fc2825d43f866f596f8c2e69da.jpeg)

Is it possible to improve model performance beyond this? Do you have any suggestions to do the same?  
I am trying to implement early stopping based on some combination of validation and train pose loss and I don’t know how to go about it - I am using a solution that DeepSeek suggested but unsure if it’s working.

---

<div class="post-metadata">

**Author:** ![VietHung103](https://sea1.discourse-cdn.com/flex001/user_avatar/community.ultralytics.com/viethung103/32/1508_2.png) [@VietHung103](https://community.ultralytics.com/u/VietHung103)\
**Post date:** [May 12, 2026, 12:34pm UTC](https://community.ultralytics.com/t/detecting-court-keypoints-from-a-pickleball-video/1703/11 "2026-05-12T12:34:50Z")

</div>

i have read a website i think the post process in this article, you can apply for help the better result. [Improving Tennis Court Line Detection with Machine Learning](https://www.ml6.eu/en/blog/improving-tennis-court-line-detection-with-machine-learning) .
