Evaluating 2024 Euro Cup and COPA America Cup Jersey Color Accessibility
This past weekend, around 30 million people tuned in to watch the 2024 Euro Cup and COPA America Cup finals. The two tournaments hosted the finest players in the world for a month of competitive and fast-paced football (or soccer), drawing in fans from all over the world watching from their phones, laptops, and TV screens.
Amongst these fans are likely those with visual impairments who benefit greatly from high contrast colors used where possible. For example, jerseys that have high colour contrasts are more readable and thus accessible to a wider audience.
While we know which countries went home with a trophy for being the best in the world at their sport, do we know which country has the most visually accessible jerseys? We can use Roboflow to find out! Here’s how we can do that:
- Use an instance segmentation model to detect jerseys in a football game;
- Upload data to Roboflow so we can annotate the jerseys in our dataset;
- Train our model using Roboflow Train;
- Use clustering to identify the colors in our jerseys, and;
- Check if the contrast of the jersey number against the jersey color passes WCAG 2.1 color accessibility requirements
Step #1: Gather our data
We are going to use computer vision to tell us if the contrast between a jersey’s number and the jersey’s color meets the Web Content Accessibility Guidelines (WCAG) and requirements for color contrast. To do that, we’re going to grab some videos of football players and drop that link into Roboflow.
From this step, we will get the frames from our videos that we can use to annotate.
Step #2: Annotate the jersey images
Next, we’re going to annotate our data so our model can identify what a jersey is and where it is located in our frames. We can use the “Smart Polygon” tool in the Roboflow Annotate web interface to help us quickly draw annotations for the shapes of our jerseys. For our first version, we’ll aim to have ~50 frames annotated.
Step #3: Train a jersey recognition model
After we have annotated our images, we can move on to training our model.
Step #4: Use clustering to identify the colors in our jerseys
With a trained model that can segment jerseys from an image, we can now use clustering to identify the colors in our jerseys. We can follow another Roboflow blog post to do so.
After following the steps in the blog post, our code should look something like this:
import numpy as np
import supervision as sv
from PIL import Image
from roboflow import Roboflow
from sklearn.cluster import KMeans
rf = Roboflow(api_key="mS0usHY07JhvTGERNl3q")
project = rf.workspace().project("jersey-contrast")
model = project.version(2).model
classes = "jersey"
image_name = "example.jpg"
inference_results = model.predict(image_name).json()
results = sv.Detections.from_inference(inference_results)
image = Image.open(image_name)
image = np.array(image)
mask_annotator = sv.MaskAnnotator()
image[results.mask[0] == 0] = 0
pixels = image.reshape((-1, 3))
clt = KMeans(n_clusters=3)
clt.fit(pixels)
centers = clt.cluster_centers_
rgb = [[int(i) for i in center] for center in centers]
rgb = [i for i in rgb if sum(i) > 0]
print(rgb)
In this code, we:
- Load our Roboflow model;
- Specify the class our model has been trained to identify (jersey);
- Run inference on our model using Roboflow Inference;
- Retrieve the first detection from the model;
- Replace all pixels outside the first detection region with black;
- Apply K-Means clustering to identify the three most dominant colors, and;
- Remove the black pixels that we applied earlier.
This code will print the background (jersey) and foreground (jersey number) colors of the jersey in our “example.jpg” image in RGB.
Step #5: Check color contrast
Next, we will use the `color-contrast` Python library to check if the contrast of the jersey number against the jersey color passes WCAG2.1 requirements. To do so, we will first convert our RGB to HEX values and then define our background (jersey) color:
def rgb2hex(c):
return "#{:02x}{:02x}{:02x}".format(c[0], c[1], c[2])
bg = Color(rgb2hex(rgb[1]))
After, we will run the contrast checker to see if our jersey is WCAG2.1 compliant:
print("Team :" + image_name)
print("Jersey Colors: " + str(rgb))
check_contrast_AA = check_contrast(rgb2hex(rgb[0]), bg, level=AccessibilityLevel.AA)
check_contrast_AAA = check_contrast(rgb2hex(rgb[0]), bg, level=AccessibilityLevel.AA)
print("WCAG Level AA Compliant? " +str(check_contrast_AA))
print("WCAG Level AAA Compliant? " + str(check_contrast_AAA))
Step #6: Testing the script
Let’s run our Python script to see if our 2024 Euros and COPA America Cup winners have accessible jerseys:
Team Spain:
Location of the jersey detected by our system:
Results:
Team Argentina:
Location of the jersey detected by our system:
Results:
As we can see, the jerseys for Team Spain and Team Argentina both do not pass WCAG2.1 requirements for color contrast.
Conclusion
In this guide, we demonstrated how we can use Roboflow and instance segmentation to analyze and compare the colors of jerseys. We then used this information to determine if the contrast between the jersey color and the jersey number color are WCAG2.1 compliant.
With the 2024 Summer Olympics just around the corner, we can continue to think on how Roboflow can make an impact on improving accessibility in sports broadcasting.