## install.packages("remotes")
remotes::install_github("openvolley/opensportml")
The opensportml
package provides image and video machine learning
tools for sports analytics. Many of its functions are re-exported from
the openvolley/ovml and
openvolley/ovideo packages,
which provide similar functionality but specifically for volleyball.
Currently two versions of the YOLO object detection algorithm are included. These have been implemented on top of the torch R package, meaning that no Python installation is required on your system.
Use a YOLOv4 network to recognize objects in an image. We use an example image bundled with the package:
library(opensportml)
img <- os_example_image()
ovml_ggplot(img)
Construct the network. The first time this function is run, it will download and cache the network weights file (\~250MB).
dn <- ovml_yolo()
Now we can use the network to detect objects in our image:
dets <- ovml_yolo_detect(dn, img)
ovml_ggplot(img, dets)
We can transform the image detections to real-world court coordinates.
First we need to define the court reference points needed for the
transformation. We can use the os_shiny_court_ref
helper app for this:
ref <- os_shiny_court_ref(img)
ref
should look something like:
ref
#> $video_width
#> [1] 1024
#>
#> $video_height
#> [1] 768
#>
#> $court_ref
#> # A tibble: 4 x 4
#> image_x image_y court_x court_y
#> <dbl> <dbl> <dbl> <dbl>
#> 1 0.0256 0.386 12.5 46
#> 2 0.283 0.117 100 0
#> 3 0.867 0.475 87.5 154
#> 4 0.582 0.626 0 200
Now use it with the ov_transform_points
function (note that currently
this function expects the image coordinates to be normalized with
respect to the image width and height):
court_xy <- ov_transform_points(x = (dets$xmin + dets$xmax)/2/ref$video_width, y = dets$ymin/ref$video_height,
ref = ref$court_ref, direction = "to_court")
dets <- cbind(dets, court_xy)
And plot it:
library(ggplot2)
ggplot(dets, aes(x, y)) +
os_ggcourt(line_colour = "white") + geom_point(colour = "blue", size = 3) +
ggplot2::theme(panel.background = ggplot2::element_rect(fill = "#95a264"))
Keep in mind that ov_transform_points
is using the middle-bottom of
each bounding box and transforming it assuming that this represents a
point on the court surface (the floor). Locations associated with
truncated object boxes, or objects not on the court surface (a tennis
racket in a player’s hand, players jumping, people in elevated positions
such as the referee’s stand) will appear further away from the camera
than they actually are.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.