Commit a53a851b authored by chenzk's avatar chenzk
Browse files

v1.0

parents
Pipeline #1184 failed with stages
in 0 seconds
# YOLOv8 - Int8-TFLite Runtime
Welcome to the YOLOv8 Int8 TFLite Runtime for efficient and optimized object detection project. This README provides comprehensive instructions for installing and using our YOLOv8 implementation.
## Installation
Ensure a smooth setup by following these steps to install necessary dependencies.
### Installing Required Dependencies
Install all required dependencies with this simple command:
```bash
pip install -r requirements.txt
```
### Installing `tflite-runtime`
To load TFLite models, install the `tflite-runtime` package using:
```bash
pip install tflite-runtime
```
### Installing `tensorflow-gpu` (For NVIDIA GPU Users)
Leverage GPU acceleration with NVIDIA GPUs by installing `tensorflow-gpu`:
```bash
pip install tensorflow-gpu
```
**Note:** Ensure you have compatible GPU drivers installed on your system.
### Installing `tensorflow` (CPU Version)
For CPU usage or non-NVIDIA GPUs, install TensorFlow with:
```bash
pip install tensorflow
```
## Usage
Follow these instructions to run YOLOv8 after successful installation.
Convert the YOLOv8 model to Int8 TFLite format:
```bash
yolo export model=yolov8n.pt imgsz=640 format=tflite int8
```
Locate the Int8 TFLite model in `yolov8n_saved_model`. Choose `best_full_integer_quant` or verify quantization at [Netron](https://netron.app/). Then, execute the following in your terminal:
```bash
python main.py --model yolov8n_full_integer_quant.tflite --img image.jpg --conf-thres 0.5 --iou-thres 0.5
```
Replace `best_full_integer_quant.tflite` with your model file's path, `image.jpg` with your input image, and adjust the confidence (conf-thres) and IoU thresholds (iou-thres) as necessary.
### Output
The output is displayed as annotated images, showcasing the model's detection capabilities:
![image](https://github.com/wamiqraza/Attribute-recognition-and-reidentification-Market1501-dataset/blob/main/img/bus.jpg)
# Ultralytics YOLO 🚀, AGPL-3.0 license
import argparse
import cv2
import numpy as np
from tflite_runtime import interpreter as tflite
from ultralytics.utils import ASSETS, yaml_load
from ultralytics.utils.checks import check_yaml
# Declare as global variables, can be updated based trained model image size
img_width = 640
img_height = 640
class LetterBox:
def __init__(
self, new_shape=(img_width, img_height), auto=False, scaleFill=False, scaleup=True, center=True, stride=32
):
self.new_shape = new_shape
self.auto = auto
self.scaleFill = scaleFill
self.scaleup = scaleup
self.stride = stride
self.center = center # Put the image in the middle or top-left
def __call__(self, labels=None, image=None):
"""Return updated labels and image with added border."""
if labels is None:
labels = {}
img = labels.get("img") if image is None else image
shape = img.shape[:2] # current shape [height, width]
new_shape = labels.pop("rect_shape", self.new_shape)
if isinstance(new_shape, int):
new_shape = (new_shape, new_shape)
# Scale ratio (new / old)
r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
if not self.scaleup: # only scale down, do not scale up (for better val mAP)
r = min(r, 1.0)
# Compute padding
ratio = r, r # width, height ratios
new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding
if self.auto: # minimum rectangle
dw, dh = np.mod(dw, self.stride), np.mod(dh, self.stride) # wh padding
elif self.scaleFill: # stretch
dw, dh = 0.0, 0.0
new_unpad = (new_shape[1], new_shape[0])
ratio = new_shape[1] / shape[1], new_shape[0] / shape[0] # width, height ratios
if self.center:
dw /= 2 # divide padding into 2 sides
dh /= 2
if shape[::-1] != new_unpad: # resize
img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)
top, bottom = int(round(dh - 0.1)) if self.center else 0, int(round(dh + 0.1))
left, right = int(round(dw - 0.1)) if self.center else 0, int(round(dw + 0.1))
img = cv2.copyMakeBorder(
img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=(114, 114, 114)
) # add border
if labels.get("ratio_pad"):
labels["ratio_pad"] = (labels["ratio_pad"], (left, top)) # for evaluation
if len(labels):
labels = self._update_labels(labels, ratio, dw, dh)
labels["img"] = img
labels["resized_shape"] = new_shape
return labels
else:
return img
def _update_labels(self, labels, ratio, padw, padh):
"""Update labels."""
labels["instances"].convert_bbox(format="xyxy")
labels["instances"].denormalize(*labels["img"].shape[:2][::-1])
labels["instances"].scale(*ratio)
labels["instances"].add_padding(padw, padh)
return labels
class Yolov8TFLite:
def __init__(self, tflite_model, input_image, confidence_thres, iou_thres):
"""
Initializes an instance of the Yolov8TFLite class.
Args:
tflite_model: Path to the TFLite model.
input_image: Path to the input image.
confidence_thres: Confidence threshold for filtering detections.
iou_thres: IoU (Intersection over Union) threshold for non-maximum suppression.
"""
self.tflite_model = tflite_model
self.input_image = input_image
self.confidence_thres = confidence_thres
self.iou_thres = iou_thres
# Load the class names from the COCO dataset
self.classes = yaml_load(check_yaml("coco128.yaml"))["names"]
# Generate a color palette for the classes
self.color_palette = np.random.uniform(0, 255, size=(len(self.classes), 3))
def draw_detections(self, img, box, score, class_id):
"""
Draws bounding boxes and labels on the input image based on the detected objects.
Args:
img: The input image to draw detections on.
box: Detected bounding box.
score: Corresponding detection score.
class_id: Class ID for the detected object.
Returns:
None
"""
# Extract the coordinates of the bounding box
x1, y1, w, h = box
# Retrieve the color for the class ID
color = self.color_palette[class_id]
# Draw the bounding box on the image
cv2.rectangle(img, (int(x1), int(y1)), (int(x1 + w), int(y1 + h)), color, 2)
# Create the label text with class name and score
label = f"{self.classes[class_id]}: {score:.2f}"
# Calculate the dimensions of the label text
(label_width, label_height), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
# Calculate the position of the label text
label_x = x1
label_y = y1 - 10 if y1 - 10 > label_height else y1 + 10
# Draw a filled rectangle as the background for the label text
cv2.rectangle(
img,
(int(label_x), int(label_y - label_height)),
(int(label_x + label_width), int(label_y + label_height)),
color,
cv2.FILLED,
)
# Draw the label text on the image
cv2.putText(img, label, (int(label_x), int(label_y)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, cv2.LINE_AA)
def preprocess(self):
"""
Preprocesses the input image before performing inference.
Returns:
image_data: Preprocessed image data ready for inference.
"""
# Read the input image using OpenCV
self.img = cv2.imread(self.input_image)
print("image before", self.img)
# Get the height and width of the input image
self.img_height, self.img_width = self.img.shape[:2]
letterbox = LetterBox(new_shape=[img_width, img_height], auto=False, stride=32)
image = letterbox(image=self.img)
image = [image]
image = np.stack(image)
image = image[..., ::-1].transpose((0, 3, 1, 2))
img = np.ascontiguousarray(image)
# n, h, w, c
image = img.astype(np.float32)
return image / 255
def postprocess(self, input_image, output):
"""
Performs post-processing on the model's output to extract bounding boxes, scores, and class IDs.
Args:
input_image (numpy.ndarray): The input image.
output (numpy.ndarray): The output of the model.
Returns:
numpy.ndarray: The input image with detections drawn on it.
"""
boxes = []
scores = []
class_ids = []
for pred in output:
pred = np.transpose(pred)
for box in pred:
x, y, w, h = box[:4]
x1 = x - w / 2
y1 = y - h / 2
boxes.append([x1, y1, w, h])
idx = np.argmax(box[4:])
scores.append(box[idx + 4])
class_ids.append(idx)
indices = cv2.dnn.NMSBoxes(boxes, scores, self.confidence_thres, self.iou_thres)
for i in indices:
# Get the box, score, and class ID corresponding to the index
box = boxes[i]
gain = min(img_width / self.img_width, img_height / self.img_height)
pad = (
round((img_width - self.img_width * gain) / 2 - 0.1),
round((img_height - self.img_height * gain) / 2 - 0.1),
)
box[0] = (box[0] - pad[0]) / gain
box[1] = (box[1] - pad[1]) / gain
box[2] = box[2] / gain
box[3] = box[3] / gain
score = scores[i]
class_id = class_ids[i]
if score > 0.25:
print(box, score, class_id)
# Draw the detection on the input image
self.draw_detections(input_image, box, score, class_id)
return input_image
def main(self):
"""
Performs inference using a TFLite model and returns the output image with drawn detections.
Returns:
output_img: The output image with drawn detections.
"""
# Create an interpreter for the TFLite model
interpreter = tflite.Interpreter(model_path=self.tflite_model)
self.model = interpreter
interpreter.allocate_tensors()
# Get the model inputs
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
# Store the shape of the input for later use
input_shape = input_details[0]["shape"]
self.input_width = input_shape[1]
self.input_height = input_shape[2]
# Preprocess the image data
img_data = self.preprocess()
img_data = img_data
# img_data = img_data.cpu().numpy()
# Set the input tensor to the interpreter
print(input_details[0]["index"])
print(img_data.shape)
img_data = img_data.transpose((0, 2, 3, 1))
scale, zero_point = input_details[0]["quantization"]
interpreter.set_tensor(input_details[0]["index"], img_data)
# Run inference
interpreter.invoke()
# Get the output tensor from the interpreter
output = interpreter.get_tensor(output_details[0]["index"])
scale, zero_point = output_details[0]["quantization"]
output = (output.astype(np.float32) - zero_point) * scale
output[:, [0, 2]] *= img_width
output[:, [1, 3]] *= img_height
print(output)
# Perform post-processing on the outputs to obtain output image.
return self.postprocess(self.img, output)
if __name__ == "__main__":
# Create an argument parser to handle command-line arguments
parser = argparse.ArgumentParser()
parser.add_argument(
"--model", type=str, default="yolov8n_full_integer_quant.tflite", help="Input your TFLite model."
)
parser.add_argument("--img", type=str, default=str(ASSETS / "bus.jpg"), help="Path to input image.")
parser.add_argument("--conf-thres", type=float, default=0.5, help="Confidence threshold")
parser.add_argument("--iou-thres", type=float, default=0.5, help="NMS IoU threshold")
args = parser.parse_args()
# Create an instance of the Yolov8TFLite class with the specified arguments
detection = Yolov8TFLite(args.model, args.img, args.conf_thres, args.iou_thres)
# Perform object detection and obtain the output image
output_image = detection.main()
# Display the output image in a window
cv2.imshow("Output", output_image)
# Wait for a key press to exit
cv2.waitKey(0)
# Regions Counting Using YOLOv8 (Inference on Video)
- Region counting is a method employed to tally the objects within a specified area, allowing for more sophisticated analyses when multiple regions are considered. These regions can be adjusted interactively using a Left Mouse Click, and the counting process occurs in real time.
- Regions can be adjusted to suit the user's preferences and requirements.
<div>
<p align="center">
<img src="https://github.com/RizwanMunawar/ultralytics/assets/62513924/5ab3bbd7-fd12-4849-928e-5f294d6c3fcf" width="45%" alt="YOLOv8 region counting visual 1">
<img src="https://github.com/RizwanMunawar/ultralytics/assets/62513924/e7c1aea7-474d-4d78-8d48-b50854ffe1ca" width="45%" alt="YOLOv8 region counting visual 2">
</p>
</div>
## Table of Contents
- [Step 1: Install the Required Libraries](#step-1-install-the-required-libraries)
- [Step 2: Run the Region Counting Using Ultralytics YOLOv8](#step-2-run-the-region-counting-using-ultralytics-yolov8)
- [Usage Options](#usage-options)
- [FAQ](#faq)
## Step 1: Install the Required Libraries
Clone the repository, install dependencies and `cd` to this local directory for commands in Step 2.
```bash
# Clone ultralytics repo
git clone https://github.com/ultralytics/ultralytics
# cd to local directory
cd ultralytics/examples/YOLOv8-Region-Counter
```
## Step 2: Run the Region Counting Using Ultralytics YOLOv8
Here are the basic commands for running the inference:
### Note
After the video begins playing, you can freely move the region anywhere within the video by simply clicking and dragging using the left mouse button.
```bash
# If you want to save results
python yolov8_region_counter.py --source "path/to/video.mp4" --save-img --view-img
# If you want to run model on CPU
python yolov8_region_counter.py --source "path/to/video.mp4" --save-img --view-img --device cpu
# If you want to change model file
python yolov8_region_counter.py --source "path/to/video.mp4" --save-img --weights "path/to/model.pt"
# If you want to detect specific class (first class and third class)
python yolov8_region_counter.py --source "path/to/video.mp4" --classes 0 2 --weights "path/to/model.pt"
# If you dont want to save results
python yolov8_region_counter.py --source "path/to/video.mp4" --view-img
```
## Usage Options
- `--source`: Specifies the path to the video file you want to run inference on.
- `--device`: Specifies the device `cpu` or `0`
- `--save-img`: Flag to save the detection results as images.
- `--weights`: Specifies a different YOLOv8 model file (e.g., `yolov8n.pt`, `yolov8s.pt`, `yolov8m.pt`, `yolov8l.pt`, `yolov8x.pt`).
- `--classes`: Specifies the class to be detected
- `--line-thickness`: Specifies the bounding box thickness
- `--region-thickness`: Specifies the region boxes thickness
- `--track-thickness`: Specifies the track line thickness
## FAQ
**1. What Does Region Counting Involve?**
Region counting is a computational method utilized to ascertain the quantity of objects within a specific area in recorded video or real-time streams. This technique finds frequent application in image processing, computer vision, and pattern recognition, facilitating the analysis and segmentation of objects or features based on their spatial relationships.
**2. Is Friendly Region Plotting Supported by the Region Counter?**
The Region Counter offers the capability to create regions in various formats, such as polygons and rectangles. You have the flexibility to modify region attributes, including coordinates, colors, and other details, as demonstrated in the following code:
```python
from shapely.geometry import Polygon
counting_regions = [
{
"name": "YOLOv8 Polygon Region",
"polygon": Polygon(
[(50, 80), (250, 20), (450, 80), (400, 350), (100, 350)]
), # Polygon with five points (Pentagon)
"counts": 0,
"dragging": False,
"region_color": (255, 42, 4), # BGR Value
"text_color": (255, 255, 255), # Region Text Color
},
{
"name": "YOLOv8 Rectangle Region",
"polygon": Polygon(
[(200, 250), (440, 250), (440, 550), (200, 550)]
), # Rectangle with four points
"counts": 0,
"dragging": False,
"region_color": (37, 255, 225), # BGR Value
"text_color": (0, 0, 0), # Region Text Color
},
]
```
**3. Why Combine Region Counting with YOLOv8?**
YOLOv8 specializes in the detection and tracking of objects in video streams. Region counting complements this by enabling object counting within designated areas, making it a valuable application of YOLOv8.
**4. How Can I Troubleshoot Issues?**
To gain more insights during inference, you can include the `--debug` flag in your command:
```bash
python yolov8_region_counter.py --source "path to video file" --debug
```
**5. Can I Employ Other YOLO Versions?**
Certainly, you have the flexibility to specify different YOLO model weights using the `--weights` option.
**6. Where Can I Access Additional Information?**
For a comprehensive guide on using YOLOv8 with Object Tracking, please refer to [Multi-Object Tracking with Ultralytics YOLO](https://docs.ultralytics.com/modes/track/).
# Ultralytics YOLO 🚀, AGPL-3.0 license
import argparse
from collections import defaultdict
from pathlib import Path
import cv2
import numpy as np
from shapely.geometry import Polygon
from shapely.geometry.point import Point
from ultralytics import YOLO
from ultralytics.utils.files import increment_path
from ultralytics.utils.plotting import Annotator, colors
track_history = defaultdict(list)
current_region = None
counting_regions = [
{
"name": "YOLOv8 Polygon Region",
"polygon": Polygon([(50, 80), (250, 20), (450, 80), (400, 350), (100, 350)]), # Polygon points
"counts": 0,
"dragging": False,
"region_color": (255, 42, 4), # BGR Value
"text_color": (255, 255, 255), # Region Text Color
},
{
"name": "YOLOv8 Rectangle Region",
"polygon": Polygon([(200, 250), (440, 250), (440, 550), (200, 550)]), # Polygon points
"counts": 0,
"dragging": False,
"region_color": (37, 255, 225), # BGR Value
"text_color": (0, 0, 0), # Region Text Color
},
]
def mouse_callback(event, x, y, flags, param):
"""
Handles mouse events for region manipulation.
Parameters:
event (int): The mouse event type (e.g., cv2.EVENT_LBUTTONDOWN).
x (int): The x-coordinate of the mouse pointer.
y (int): The y-coordinate of the mouse pointer.
flags (int): Additional flags passed by OpenCV.
param: Additional parameters passed to the callback (not used in this function).
Global Variables:
current_region (dict): A dictionary representing the current selected region.
Mouse Events:
- LBUTTONDOWN: Initiates dragging for the region containing the clicked point.
- MOUSEMOVE: Moves the selected region if dragging is active.
- LBUTTONUP: Ends dragging for the selected region.
Notes:
- This function is intended to be used as a callback for OpenCV mouse events.
- Requires the existence of the 'counting_regions' list and the 'Polygon' class.
Example:
>>> cv2.setMouseCallback(window_name, mouse_callback)
"""
global current_region
# Mouse left button down event
if event == cv2.EVENT_LBUTTONDOWN:
for region in counting_regions:
if region["polygon"].contains(Point((x, y))):
current_region = region
current_region["dragging"] = True
current_region["offset_x"] = x
current_region["offset_y"] = y
# Mouse move event
elif event == cv2.EVENT_MOUSEMOVE:
if current_region is not None and current_region["dragging"]:
dx = x - current_region["offset_x"]
dy = y - current_region["offset_y"]
current_region["polygon"] = Polygon(
[(p[0] + dx, p[1] + dy) for p in current_region["polygon"].exterior.coords]
)
current_region["offset_x"] = x
current_region["offset_y"] = y
# Mouse left button up event
elif event == cv2.EVENT_LBUTTONUP:
if current_region is not None and current_region["dragging"]:
current_region["dragging"] = False
def run(
weights="yolov8n.pt",
source=None,
device="cpu",
view_img=False,
save_img=False,
exist_ok=False,
classes=None,
line_thickness=2,
track_thickness=2,
region_thickness=2,
):
"""
Run Region counting on a video using YOLOv8 and ByteTrack.
Supports movable region for real time counting inside specific area.
Supports multiple regions counting.
Regions can be Polygons or rectangle in shape
Args:
weights (str): Model weights path.
source (str): Video file path.
device (str): processing device cpu, 0, 1
view_img (bool): Show results.
save_img (bool): Save results.
exist_ok (bool): Overwrite existing files.
classes (list): classes to detect and track
line_thickness (int): Bounding box thickness.
track_thickness (int): Tracking line thickness
region_thickness (int): Region thickness.
"""
vid_frame_count = 0
# Check source path
if not Path(source).exists():
raise FileNotFoundError(f"Source path '{source}' does not exist.")
# Setup Model
model = YOLO(f"{weights}")
model.to("cuda") if device == "0" else model.to("cpu")
# Extract classes names
names = model.model.names
# Video setup
videocapture = cv2.VideoCapture(source)
frame_width, frame_height = int(videocapture.get(3)), int(videocapture.get(4))
fps, fourcc = int(videocapture.get(5)), cv2.VideoWriter_fourcc(*"mp4v")
# Output setup
save_dir = increment_path(Path("ultralytics_rc_output") / "exp", exist_ok)
save_dir.mkdir(parents=True, exist_ok=True)
video_writer = cv2.VideoWriter(str(save_dir / f"{Path(source).stem}.mp4"), fourcc, fps, (frame_width, frame_height))
# Iterate over video frames
while videocapture.isOpened():
success, frame = videocapture.read()
if not success:
break
vid_frame_count += 1
# Extract the results
results = model.track(frame, persist=True, classes=classes)
if results[0].boxes.id is not None:
boxes = results[0].boxes.xyxy.cpu()
track_ids = results[0].boxes.id.int().cpu().tolist()
clss = results[0].boxes.cls.cpu().tolist()
annotator = Annotator(frame, line_width=line_thickness, example=str(names))
for box, track_id, cls in zip(boxes, track_ids, clss):
annotator.box_label(box, str(names[cls]), color=colors(cls, True))
bbox_center = (box[0] + box[2]) / 2, (box[1] + box[3]) / 2 # Bbox center
track = track_history[track_id] # Tracking Lines plot
track.append((float(bbox_center[0]), float(bbox_center[1])))
if len(track) > 30:
track.pop(0)
points = np.hstack(track).astype(np.int32).reshape((-1, 1, 2))
cv2.polylines(frame, [points], isClosed=False, color=colors(cls, True), thickness=track_thickness)
# Check if detection inside region
for region in counting_regions:
if region["polygon"].contains(Point((bbox_center[0], bbox_center[1]))):
region["counts"] += 1
# Draw regions (Polygons/Rectangles)
for region in counting_regions:
region_label = str(region["counts"])
region_color = region["region_color"]
region_text_color = region["text_color"]
polygon_coords = np.array(region["polygon"].exterior.coords, dtype=np.int32)
centroid_x, centroid_y = int(region["polygon"].centroid.x), int(region["polygon"].centroid.y)
text_size, _ = cv2.getTextSize(
region_label, cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.7, thickness=line_thickness
)
text_x = centroid_x - text_size[0] // 2
text_y = centroid_y + text_size[1] // 2
cv2.rectangle(
frame,
(text_x - 5, text_y - text_size[1] - 5),
(text_x + text_size[0] + 5, text_y + 5),
region_color,
-1,
)
cv2.putText(
frame, region_label, (text_x, text_y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, region_text_color, line_thickness
)
cv2.polylines(frame, [polygon_coords], isClosed=True, color=region_color, thickness=region_thickness)
if view_img:
if vid_frame_count == 1:
cv2.namedWindow("Ultralytics YOLOv8 Region Counter Movable")
cv2.setMouseCallback("Ultralytics YOLOv8 Region Counter Movable", mouse_callback)
cv2.imshow("Ultralytics YOLOv8 Region Counter Movable", frame)
if save_img:
video_writer.write(frame)
for region in counting_regions: # Reinitialize count for each region
region["counts"] = 0
if cv2.waitKey(1) & 0xFF == ord("q"):
break
del vid_frame_count
video_writer.release()
videocapture.release()
cv2.destroyAllWindows()
def parse_opt():
"""Parse command line arguments."""
parser = argparse.ArgumentParser()
parser.add_argument("--weights", type=str, default="yolov8n.pt", help="initial weights path")
parser.add_argument("--device", default="", help="cuda device, i.e. 0 or 0,1,2,3 or cpu")
parser.add_argument("--source", type=str, required=True, help="video file path")
parser.add_argument("--view-img", action="store_true", help="show results")
parser.add_argument("--save-img", action="store_true", help="save results")
parser.add_argument("--exist-ok", action="store_true", help="existing project/name ok, do not increment")
parser.add_argument("--classes", nargs="+", type=int, help="filter by class: --classes 0, or --classes 0 2 3")
parser.add_argument("--line-thickness", type=int, default=2, help="bounding box thickness")
parser.add_argument("--track-thickness", type=int, default=2, help="Tracking line thickness")
parser.add_argument("--region-thickness", type=int, default=4, help="Region thickness")
return parser.parse_args()
def main(opt):
"""Main function."""
run(**vars(opt))
if __name__ == "__main__":
opt = parse_opt()
main(opt)
# YOLOv8 with SAHI (Inference on Video)
[SAHI](https://docs.ultralytics.com/guides/sahi-tiled-inference/) is designed to optimize object detection algorithms for large-scale and high-resolution imagery. It partitions images into manageable slices, performs object detection on each slice, and then stitches the results back together. This tutorial will guide you through the process of running YOLOv8 inference on video files with the aid of SAHI.
## Table of Contents
- [Step 1: Install the Required Libraries](#step-1-install-the-required-libraries)
- [Step 2: Run the Inference with SAHI using Ultralytics YOLOv8](#step-2-run-the-inference-with-sahi-using-ultralytics-yolov8)
- [Usage Options](#usage-options)
- [FAQ](#faq)
## Step 1: Install the Required Libraries
Clone the repository, install dependencies and `cd` to this local directory for commands in Step 2.
```bash
# Clone ultralytics repo
git clone https://github.com/ultralytics/ultralytics
# Install dependencies
pip install sahi ultralytics
# cd to local directory
cd ultralytics/examples/YOLOv8-SAHI-Inference-Video
```
## Step 2: Run the Inference with SAHI using Ultralytics YOLOv8
Here are the basic commands for running the inference:
```bash
#if you want to save results
python yolov8_sahi.py --source "path/to/video.mp4" --save-img
#if you want to change model file
python yolov8_sahi.py --source "path/to/video.mp4" --save-img --weights "yolov8n.pt"
```
## Usage Options
- `--source`: Specifies the path to the video file you want to run inference on.
- `--save-img`: Flag to save the detection results as images.
- `--weights`: Specifies a different YOLOv8 model file (e.g., `yolov8n.pt`, `yolov8s.pt`, `yolov8m.pt`, `yolov8l.pt`, `yolov8x.pt`).
## FAQ
**1. What is SAHI?**
SAHI stands for Slicing, Analysis, and Healing of Images. It is a library designed to optimize object detection algorithms for large-scale and high-resolution images. The library source code is available on [GitHub](https://github.com/obss/sahi).
**2. Why use SAHI with YOLOv8?**
SAHI can handle large-scale images by slicing them into smaller, more manageable sizes without compromising the detection quality. This makes it a great companion to YOLOv8, especially when working with high-resolution videos.
**3. How do I debug issues?**
You can add the `--debug` flag to your command to print out more information during inference:
```bash
python yolov8_sahi.py --source "path to video file" --debug
```
**4. Can I use other YOLO versions?**
Yes, you can specify different YOLO model weights using the `--weights` option.
**5. Where can I find more information?**
For a full guide to YOLOv8 with SAHI see [https://docs.ultralytics.com/guides/sahi-tiled-inference](https://docs.ultralytics.com/guides/sahi-tiled-inference/).
# Ultralytics YOLO 🚀, AGPL-3.0 license
import argparse
from pathlib import Path
import cv2
from sahi import AutoDetectionModel
from sahi.predict import get_sliced_prediction
from sahi.utils.yolov8 import download_yolov8s_model
from ultralytics.utils.files import increment_path
def run(weights="yolov8n.pt", source="test.mp4", view_img=False, save_img=False, exist_ok=False):
"""
Run object detection on a video using YOLOv8 and SAHI.
Args:
weights (str): Model weights path.
source (str): Video file path.
view_img (bool): Show results.
save_img (bool): Save results.
exist_ok (bool): Overwrite existing files.
"""
# Check source path
if not Path(source).exists():
raise FileNotFoundError(f"Source path '{source}' does not exist.")
yolov8_model_path = f"models/{weights}"
download_yolov8s_model(yolov8_model_path)
detection_model = AutoDetectionModel.from_pretrained(
model_type="yolov8", model_path=yolov8_model_path, confidence_threshold=0.3, device="cpu"
)
# Video setup
videocapture = cv2.VideoCapture(source)
frame_width, frame_height = int(videocapture.get(3)), int(videocapture.get(4))
fps, fourcc = int(videocapture.get(5)), cv2.VideoWriter_fourcc(*"mp4v")
# Output setup
save_dir = increment_path(Path("ultralytics_results_with_sahi") / "exp", exist_ok)
save_dir.mkdir(parents=True, exist_ok=True)
video_writer = cv2.VideoWriter(str(save_dir / f"{Path(source).stem}.mp4"), fourcc, fps, (frame_width, frame_height))
while videocapture.isOpened():
success, frame = videocapture.read()
if not success:
break
results = get_sliced_prediction(
frame, detection_model, slice_height=512, slice_width=512, overlap_height_ratio=0.2, overlap_width_ratio=0.2
)
object_prediction_list = results.object_prediction_list
boxes_list = []
clss_list = []
for ind, _ in enumerate(object_prediction_list):
boxes = (
object_prediction_list[ind].bbox.minx,
object_prediction_list[ind].bbox.miny,
object_prediction_list[ind].bbox.maxx,
object_prediction_list[ind].bbox.maxy,
)
clss = object_prediction_list[ind].category.name
boxes_list.append(boxes)
clss_list.append(clss)
for box, cls in zip(boxes_list, clss_list):
x1, y1, x2, y2 = box
cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (56, 56, 255), 2)
label = str(cls)
t_size = cv2.getTextSize(label, 0, fontScale=0.6, thickness=1)[0]
cv2.rectangle(
frame, (int(x1), int(y1) - t_size[1] - 3), (int(x1) + t_size[0], int(y1) + 3), (56, 56, 255), -1
)
cv2.putText(
frame, label, (int(x1), int(y1) - 2), 0, 0.6, [255, 255, 255], thickness=1, lineType=cv2.LINE_AA
)
if view_img:
cv2.imshow(Path(source).stem, frame)
if save_img:
video_writer.write(frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
video_writer.release()
videocapture.release()
cv2.destroyAllWindows()
def parse_opt():
"""Parse command line arguments."""
parser = argparse.ArgumentParser()
parser.add_argument("--weights", type=str, default="yolov8n.pt", help="initial weights path")
parser.add_argument("--source", type=str, required=True, help="video file path")
parser.add_argument("--view-img", action="store_true", help="show results")
parser.add_argument("--save-img", action="store_true", help="save results")
parser.add_argument("--exist-ok", action="store_true", help="existing project/name ok, do not increment")
return parser.parse_args()
def main(opt):
"""Main function."""
run(**vars(opt))
if __name__ == "__main__":
opt = parse_opt()
main(opt)
# YOLOv8-Segmentation-ONNXRuntime-Python Demo
This repository provides a Python demo for performing segmentation with YOLOv8 using ONNX Runtime, highlighting the interoperability of YOLOv8 models without the need for the full PyTorch stack.
## Features
- **Framework Agnostic**: Runs segmentation inference purely on ONNX Runtime without importing PyTorch.
- **Efficient Inference**: Supports both FP32 and FP16 precision for ONNX models, catering to different computational needs.
- **Ease of Use**: Utilizes simple command-line arguments for model execution.
- **Broad Compatibility**: Leverages Numpy and OpenCV for image processing, ensuring broad compatibility with various environments.
## Installation
Install the required packages using pip. You will need `ultralytics` for exporting YOLOv8-seg ONNX model and using some utility functions, `onnxruntime-gpu` for GPU-accelerated inference, and `opencv-python` for image processing.
```bash
pip install ultralytics
pip install onnxruntime-gpu # For GPU support
# pip install onnxruntime # Use this instead if you don't have an NVIDIA GPU
pip install numpy
pip install opencv-python
```
## Getting Started
### 1. Export the YOLOv8 ONNX Model
Export the YOLOv8 segmentation model to ONNX format using the provided `ultralytics` package.
```bash
yolo export model=yolov8s-seg.pt imgsz=640 format=onnx opset=12 simplify
```
### 2. Run Inference
Perform inference with the exported ONNX model on your images.
```bash
python main.py --model-path <MODEL_PATH> --source <IMAGE_PATH>
```
### Example Output
After running the command, you should see segmentation results similar to this:
<img src="https://user-images.githubusercontent.com/51357717/279988626-eb74823f-1563-4d58-a8e4-0494025b7c9a.jpg" alt="Segmentation Demo" width="800">
## Advanced Usage
For more advanced usage, including real-time video processing, please refer to the `main.py` script's command-line arguments.
## Contributing
We welcome contributions to improve this demo! Please submit issues and pull requests for bug reports, feature requests, or submitting a new algorithm enhancement.
## License
This project is licensed under the AGPL-3.0 License - see the [LICENSE](https://github.com/ultralytics/ultralytics/blob/main/LICENSE) file for details.
## Acknowledgments
- The YOLOv8-Segmentation-ONNXRuntime-Python demo is contributed by GitHub user [jamjamjon](https://github.com/jamjamjon).
- Thanks to the ONNX Runtime community for providing a robust and efficient inference engine.
# Ultralytics YOLO 🚀, AGPL-3.0 license
import argparse
import cv2
import numpy as np
import onnxruntime as ort
from ultralytics.utils import ASSETS, yaml_load
from ultralytics.utils.checks import check_yaml
from ultralytics.utils.plotting import Colors
class YOLOv8Seg:
"""YOLOv8 segmentation model."""
def __init__(self, onnx_model):
"""
Initialization.
Args:
onnx_model (str): Path to the ONNX model.
"""
# Build Ort session
self.session = ort.InferenceSession(
onnx_model,
providers=["CUDAExecutionProvider", "CPUExecutionProvider"]
if ort.get_device() == "GPU"
else ["CPUExecutionProvider"],
)
# Numpy dtype: support both FP32 and FP16 onnx model
self.ndtype = np.half if self.session.get_inputs()[0].type == "tensor(float16)" else np.single
# Get model width and height(YOLOv8-seg only has one input)
self.model_height, self.model_width = [x.shape for x in self.session.get_inputs()][0][-2:]
# Load COCO class names
self.classes = yaml_load(check_yaml("coco128.yaml"))["names"]
# Create color palette
self.color_palette = Colors()
def __call__(self, im0, conf_threshold=0.4, iou_threshold=0.45, nm=32):
"""
The whole pipeline: pre-process -> inference -> post-process.
Args:
im0 (Numpy.ndarray): original input image.
conf_threshold (float): confidence threshold for filtering predictions.
iou_threshold (float): iou threshold for NMS.
nm (int): the number of masks.
Returns:
boxes (List): list of bounding boxes.
segments (List): list of segments.
masks (np.ndarray): [N, H, W], output masks.
"""
# Pre-process
im, ratio, (pad_w, pad_h) = self.preprocess(im0)
# Ort inference
preds = self.session.run(None, {self.session.get_inputs()[0].name: im})
# Post-process
boxes, segments, masks = self.postprocess(
preds,
im0=im0,
ratio=ratio,
pad_w=pad_w,
pad_h=pad_h,
conf_threshold=conf_threshold,
iou_threshold=iou_threshold,
nm=nm,
)
return boxes, segments, masks
def preprocess(self, img):
"""
Pre-processes the input image.
Args:
img (Numpy.ndarray): image about to be processed.
Returns:
img_process (Numpy.ndarray): image preprocessed for inference.
ratio (tuple): width, height ratios in letterbox.
pad_w (float): width padding in letterbox.
pad_h (float): height padding in letterbox.
"""
# Resize and pad input image using letterbox() (Borrowed from Ultralytics)
shape = img.shape[:2] # original image shape
new_shape = (self.model_height, self.model_width)
r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
ratio = r, r
new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
pad_w, pad_h = (new_shape[1] - new_unpad[0]) / 2, (new_shape[0] - new_unpad[1]) / 2 # wh padding
if shape[::-1] != new_unpad: # resize
img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)
top, bottom = int(round(pad_h - 0.1)), int(round(pad_h + 0.1))
left, right = int(round(pad_w - 0.1)), int(round(pad_w + 0.1))
img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=(114, 114, 114))
# Transforms: HWC to CHW -> BGR to RGB -> div(255) -> contiguous -> add axis(optional)
img = np.ascontiguousarray(np.einsum("HWC->CHW", img)[::-1], dtype=self.ndtype) / 255.0
img_process = img[None] if len(img.shape) == 3 else img
return img_process, ratio, (pad_w, pad_h)
def postprocess(self, preds, im0, ratio, pad_w, pad_h, conf_threshold, iou_threshold, nm=32):
"""
Post-process the prediction.
Args:
preds (Numpy.ndarray): predictions come from ort.session.run().
im0 (Numpy.ndarray): [h, w, c] original input image.
ratio (tuple): width, height ratios in letterbox.
pad_w (float): width padding in letterbox.
pad_h (float): height padding in letterbox.
conf_threshold (float): conf threshold.
iou_threshold (float): iou threshold.
nm (int): the number of masks.
Returns:
boxes (List): list of bounding boxes.
segments (List): list of segments.
masks (np.ndarray): [N, H, W], output masks.
"""
x, protos = preds[0], preds[1] # Two outputs: predictions and protos
# Transpose the first output: (Batch_size, xywh_conf_cls_nm, Num_anchors) -> (Batch_size, Num_anchors, xywh_conf_cls_nm)
x = np.einsum("bcn->bnc", x)
# Predictions filtering by conf-threshold
x = x[np.amax(x[..., 4:-nm], axis=-1) > conf_threshold]
# Create a new matrix which merge these(box, score, cls, nm) into one
# For more details about `numpy.c_()`: https://numpy.org/doc/1.26/reference/generated/numpy.c_.html
x = np.c_[x[..., :4], np.amax(x[..., 4:-nm], axis=-1), np.argmax(x[..., 4:-nm], axis=-1), x[..., -nm:]]
# NMS filtering
x = x[cv2.dnn.NMSBoxes(x[:, :4], x[:, 4], conf_threshold, iou_threshold)]
# Decode and return
if len(x) > 0:
# Bounding boxes format change: cxcywh -> xyxy
x[..., [0, 1]] -= x[..., [2, 3]] / 2
x[..., [2, 3]] += x[..., [0, 1]]
# Rescales bounding boxes from model shape(model_height, model_width) to the shape of original image
x[..., :4] -= [pad_w, pad_h, pad_w, pad_h]
x[..., :4] /= min(ratio)
# Bounding boxes boundary clamp
x[..., [0, 2]] = x[:, [0, 2]].clip(0, im0.shape[1])
x[..., [1, 3]] = x[:, [1, 3]].clip(0, im0.shape[0])
# Process masks
masks = self.process_mask(protos[0], x[:, 6:], x[:, :4], im0.shape)
# Masks -> Segments(contours)
segments = self.masks2segments(masks)
return x[..., :6], segments, masks # boxes, segments, masks
else:
return [], [], []
@staticmethod
def masks2segments(masks):
"""
It takes a list of masks(n,h,w) and returns a list of segments(n,xy) (Borrowed from
https://github.com/ultralytics/ultralytics/blob/465df3024f44fa97d4fad9986530d5a13cdabdca/ultralytics/utils/ops.py#L750)
Args:
masks (numpy.ndarray): the output of the model, which is a tensor of shape (batch_size, 160, 160).
Returns:
segments (List): list of segment masks.
"""
segments = []
for x in masks.astype("uint8"):
c = cv2.findContours(x, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0] # CHAIN_APPROX_SIMPLE
if c:
c = np.array(c[np.array([len(x) for x in c]).argmax()]).reshape(-1, 2)
else:
c = np.zeros((0, 2)) # no segments found
segments.append(c.astype("float32"))
return segments
@staticmethod
def crop_mask(masks, boxes):
"""
It takes a mask and a bounding box, and returns a mask that is cropped to the bounding box. (Borrowed from
https://github.com/ultralytics/ultralytics/blob/465df3024f44fa97d4fad9986530d5a13cdabdca/ultralytics/utils/ops.py#L599)
Args:
masks (Numpy.ndarray): [n, h, w] tensor of masks.
boxes (Numpy.ndarray): [n, 4] tensor of bbox coordinates in relative point form.
Returns:
(Numpy.ndarray): The masks are being cropped to the bounding box.
"""
n, h, w = masks.shape
x1, y1, x2, y2 = np.split(boxes[:, :, None], 4, 1)
r = np.arange(w, dtype=x1.dtype)[None, None, :]
c = np.arange(h, dtype=x1.dtype)[None, :, None]
return masks * ((r >= x1) * (r < x2) * (c >= y1) * (c < y2))
def process_mask(self, protos, masks_in, bboxes, im0_shape):
"""
Takes the output of the mask head, and applies the mask to the bounding boxes. This produces masks of higher quality
but is slower. (Borrowed from https://github.com/ultralytics/ultralytics/blob/465df3024f44fa97d4fad9986530d5a13cdabdca/ultralytics/utils/ops.py#L618)
Args:
protos (numpy.ndarray): [mask_dim, mask_h, mask_w].
masks_in (numpy.ndarray): [n, mask_dim], n is number of masks after nms.
bboxes (numpy.ndarray): bboxes re-scaled to original image shape.
im0_shape (tuple): the size of the input image (h,w,c).
Returns:
(numpy.ndarray): The upsampled masks.
"""
c, mh, mw = protos.shape
masks = np.matmul(masks_in, protos.reshape((c, -1))).reshape((-1, mh, mw)).transpose(1, 2, 0) # HWN
masks = np.ascontiguousarray(masks)
masks = self.scale_mask(masks, im0_shape) # re-scale mask from P3 shape to original input image shape
masks = np.einsum("HWN -> NHW", masks) # HWN -> NHW
masks = self.crop_mask(masks, bboxes)
return np.greater(masks, 0.5)
@staticmethod
def scale_mask(masks, im0_shape, ratio_pad=None):
"""
Takes a mask, and resizes it to the original image size. (Borrowed from
https://github.com/ultralytics/ultralytics/blob/465df3024f44fa97d4fad9986530d5a13cdabdca/ultralytics/utils/ops.py#L305)
Args:
masks (np.ndarray): resized and padded masks/images, [h, w, num]/[h, w, 3].
im0_shape (tuple): the original image shape.
ratio_pad (tuple): the ratio of the padding to the original image.
Returns:
masks (np.ndarray): The masks that are being returned.
"""
im1_shape = masks.shape[:2]
if ratio_pad is None: # calculate from im0_shape
gain = min(im1_shape[0] / im0_shape[0], im1_shape[1] / im0_shape[1]) # gain = old / new
pad = (im1_shape[1] - im0_shape[1] * gain) / 2, (im1_shape[0] - im0_shape[0] * gain) / 2 # wh padding
else:
pad = ratio_pad[1]
# Calculate tlbr of mask
top, left = int(round(pad[1] - 0.1)), int(round(pad[0] - 0.1)) # y, x
bottom, right = int(round(im1_shape[0] - pad[1] + 0.1)), int(round(im1_shape[1] - pad[0] + 0.1))
if len(masks.shape) < 2:
raise ValueError(f'"len of masks shape" should be 2 or 3, but got {len(masks.shape)}')
masks = masks[top:bottom, left:right]
masks = cv2.resize(
masks, (im0_shape[1], im0_shape[0]), interpolation=cv2.INTER_LINEAR
) # INTER_CUBIC would be better
if len(masks.shape) == 2:
masks = masks[:, :, None]
return masks
def draw_and_visualize(self, im, bboxes, segments, vis=False, save=True):
"""
Draw and visualize results.
Args:
im (np.ndarray): original image, shape [h, w, c].
bboxes (numpy.ndarray): [n, 4], n is number of bboxes.
segments (List): list of segment masks.
vis (bool): imshow using OpenCV.
save (bool): save image annotated.
Returns:
None
"""
# Draw rectangles and polygons
im_canvas = im.copy()
for (*box, conf, cls_), segment in zip(bboxes, segments):
# draw contour and fill mask
cv2.polylines(im, np.int32([segment]), True, (255, 255, 255), 2) # white borderline
cv2.fillPoly(im_canvas, np.int32([segment]), self.color_palette(int(cls_), bgr=True))
# draw bbox rectangle
cv2.rectangle(
im,
(int(box[0]), int(box[1])),
(int(box[2]), int(box[3])),
self.color_palette(int(cls_), bgr=True),
1,
cv2.LINE_AA,
)
cv2.putText(
im,
f"{self.classes[cls_]}: {conf:.3f}",
(int(box[0]), int(box[1] - 9)),
cv2.FONT_HERSHEY_SIMPLEX,
0.7,
self.color_palette(int(cls_), bgr=True),
2,
cv2.LINE_AA,
)
# Mix image
im = cv2.addWeighted(im_canvas, 0.3, im, 0.7, 0)
# Show image
if vis:
cv2.imshow("demo", im)
cv2.waitKey(0)
cv2.destroyAllWindows()
# Save image
if save:
cv2.imwrite("demo.jpg", im)
if __name__ == "__main__":
# Create an argument parser to handle command-line arguments
parser = argparse.ArgumentParser()
parser.add_argument("--model", type=str, required=True, help="Path to ONNX model")
parser.add_argument("--source", type=str, default=str(ASSETS / "bus.jpg"), help="Path to input image")
parser.add_argument("--conf", type=float, default=0.25, help="Confidence threshold")
parser.add_argument("--iou", type=float, default=0.45, help="NMS IoU threshold")
args = parser.parse_args()
# Build model
model = YOLOv8Seg(args.model)
# Read image by OpenCV
img = cv2.imread(args.source)
# Inference
boxes, segments, _ = model(img, conf_threshold=args.conf, iou_threshold=args.iou)
# Draw bboxes and polygons
if len(boxes) > 0:
model.draw_and_visualize(img, boxes, segments, vis=False, save=True)
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"gpuType": "T4"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"source": [
"<div align=\"center\">\n",
"\n",
" <a href=\"https://ultralytics.com/yolov8\" target=\"_blank\">\n",
" <img width=\"1024\", src=\"https://raw.githubusercontent.com/ultralytics/assets/main/yolov8/banner-yolov8.png\"></a>\n",
"\n",
" [中文](https://docs.ultralytics.com/zh/) | [한국어](https://docs.ultralytics.com/ko/) | [日本語](https://docs.ultralytics.com/ja/) | [Русский](https://docs.ultralytics.com/ru/) | [Deutsch](https://docs.ultralytics.com/de/) | [Français](https://docs.ultralytics.com/fr/) | [Español](https://docs.ultralytics.com/es/) | [Português](https://docs.ultralytics.com/pt/) | [हिन्दी](https://docs.ultralytics.com/hi/) | [العربية](https://docs.ultralytics.com/ar/)\n",
"\n",
" <a href=\"https://colab.research.google.com/github/ultralytics/ultralytics/blob/main/examples/heatmaps.ipynb\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>\n",
"\n",
"Welcome to the Ultralytics YOLOv8 🚀 notebook! <a href=\"https://github.com/ultralytics/ultralytics\">YOLOv8</a> is the latest version of the YOLO (You Only Look Once) AI models developed by <a href=\"https://ultralytics.com\">Ultralytics</a>. This notebook serves as the starting point for exploring the <a href=\"https://docs.ultralytics.com/guides/heatmaps/\">heatmaps</a> and understand its features and capabilities.\n",
"\n",
"YOLOv8 models are fast, accurate, and easy to use, making them ideal for various object detection and image segmentation tasks. They can be trained on large datasets and run on diverse hardware platforms, from CPUs to GPUs.\n",
"\n",
"We hope that the resources in this notebook will help you get the most out of <a href=\"https://docs.ultralytics.com/guides/heatmaps/\">Ultralytics Heatmaps</a>. Please browse the YOLOv8 <a href=\"https://docs.ultralytics.com/\">Docs</a> for details, raise an issue on <a href=\"https://github.com/ultralytics/ultralytics\">GitHub</a> for support, and join our <a href=\"https://ultralytics.com/discord\">Discord</a> community for questions and discussions!\n",
"\n",
"</div>"
],
"metadata": {
"id": "PN1cAxdvd61e"
}
},
{
"cell_type": "markdown",
"source": [
"# Setup\n",
"\n",
"Pip install `ultralytics` and [dependencies](https://github.com/ultralytics/ultralytics/blob/main/pyproject.toml) and check software and hardware."
],
"metadata": {
"id": "o68Sg1oOeZm2"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "9dSwz_uOReMI"
},
"outputs": [],
"source": [
"!pip install ultralytics"
]
},
{
"cell_type": "markdown",
"source": [
"# Ultralytics Heatmaps\n",
"\n",
"Heatmap is color-coded matrix, generated by Ultralytics YOLOv8, simplifies intricate data by using vibrant colors. This visual representation employs warmer hues for higher intensities and cooler tones for lower values. Heatmaps are effective in illustrating complex data patterns, correlations, and anomalies, providing a user-friendly and engaging way to interpret data across various domains."
],
"metadata": {
"id": "m7VkxQ2aeg7k"
}
},
{
"cell_type": "code",
"source": [
"from ultralytics import YOLO\n",
"from ultralytics.solutions import heatmap\n",
"import cv2\n",
"\n",
"model = YOLO(\"yolov8n.pt\")\n",
"cap = cv2.VideoCapture(\"path/to/video/file.mp4\")\n",
"assert cap.isOpened(), \"Error reading video file\"\n",
"w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))\n",
"\n",
"# Video writer\n",
"video_writer = cv2.VideoWriter(\"heatmap_output.avi\",\n",
" cv2.VideoWriter_fourcc(*'mp4v'),\n",
" fps,\n",
" (w, h))\n",
"\n",
"# Init heatmap\n",
"heatmap_obj = heatmap.Heatmap()\n",
"heatmap_obj.set_args(colormap=cv2.COLORMAP_PARULA,\n",
" imw=w,\n",
" imh=h,\n",
" view_img=True,\n",
" shape=\"circle\")\n",
"\n",
"while cap.isOpened():\n",
" success, im0 = cap.read()\n",
" if not success:\n",
" print(\"Video frame is empty or video processing has been successfully completed.\")\n",
" break\n",
" tracks = model.track(im0, persist=True, show=False)\n",
"\n",
" im0 = heatmap_obj.generate_heatmap(im0, tracks)\n",
" video_writer.write(im0)\n",
"\n",
"cap.release()\n",
"video_writer.release()\n",
"cv2.destroyAllWindows()"
],
"metadata": {
"id": "Cx-u59HQdu2o"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"#Community Support\n",
"\n",
"For more information, you can explore <a href=\"https://docs.ultralytics.com/guides/heatmaps/#heatmap-colormaps\">Ultralytics Heatmaps Docs</a>\n",
"\n",
"Ultralytics ⚡ resources\n",
"- About Us – https://ultralytics.com/about\n",
"- Join Our Team – https://ultralytics.com/work\n",
"- Contact Us – https://ultralytics.com/contact\n",
"- Discord – https://ultralytics.com/discord\n",
"- Ultralytics License – https://ultralytics.com/license\n",
"\n",
"YOLOv8 🚀 resources\n",
"- GitHub – https://github.com/ultralytics/ultralytics\n",
"- Docs – https://docs.ultralytics.com/"
],
"metadata": {
"id": "QrlKg-y3fEyD"
}
}
]
}
\ No newline at end of file
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "Ultralytics HUB",
"provenance": []
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "FIzICjaph_Wy"
},
"source": [
"<a align=\"center\" href=\"https://hub.ultralytics.com\" target=\"_blank\">\n",
"<img width=\"1024\", src=\"https://github.com/ultralytics/assets/raw/main/im/ultralytics-hub.png\"></a>\n",
"\n",
"<div align=\"center\">\n",
"\n",
"[中文](https://docs.ultralytics.com/zh/) | [한국어](https://docs.ultralytics.com/ko/) | [日本語](https://docs.ultralytics.com/ja/) | [Русский](https://docs.ultralytics.com/ru/) | [Deutsch](https://docs.ultralytics.com/de/) | [Français](https://docs.ultralytics.com/fr/) | [Español](https://docs.ultralytics.com/es/) | [Português](https://docs.ultralytics.com/pt/) | [हिन्दी](https://docs.ultralytics.com/hi/) | [العربية](https://docs.ultralytics.com/ar/)\n",
"\n",
" <a href=\"https://github.com/ultralytics/hub/actions/workflows/ci.yaml\">\n",
" <img src=\"https://github.com/ultralytics/hub/actions/workflows/ci.yaml/badge.svg\" alt=\"CI CPU\"></a>\n",
" <a href=\"https://colab.research.google.com/github/ultralytics/hub/blob/master/hub.ipynb\">\n",
" <img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>\n",
"\n",
"Welcome to the [Ultralytics](https://ultralytics.com/) HUB notebook!\n",
"\n",
"This notebook allows you to train [YOLOv5](https://github.com/ultralytics/yolov5) and [YOLOv8](https://github.com/ultralytics/ultralytics) 🚀 models using [HUB](https://hub.ultralytics.com/). Please browse the HUB <a href=\"https://docs.ultralytics.com/hub/\">Docs</a> for details, raise an issue on <a href=\"https://github.com/ultralytics/hub/issues/new/choose\">GitHub</a> for support, and join our <a href=\"https://ultralytics.com/discord\">Discord</a> community for questions and discussions!\n",
"</div>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "eRQ2ow94MiOv"
},
"source": [
"# Setup\n",
"\n",
"Pip install `ultralytics` and [dependencies](https://github.com/ultralytics/ultralytics/blob/main/pyproject.toml) and check software and hardware."
]
},
{
"cell_type": "code",
"metadata": {
"id": "FyDnXd-n4c7Y",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "01e34b44-a26f-4dbc-a5a1-6e29bca01a1b"
},
"source": [
"%pip install ultralytics # install\n",
"from ultralytics import YOLO, checks, hub\n",
"checks() # checks"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"Ultralytics YOLOv8.0.210 🚀 Python-3.10.12 torch-2.0.1+cu118 CUDA:0 (Tesla T4, 15102MiB)\n",
"Setup complete ✅ (2 CPUs, 12.7 GB RAM, 24.4/78.2 GB disk)\n"
]
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cQ9BwaAqxAm4"
},
"source": [
"# Start\n",
"\n",
"Login with your [API key](https://hub.ultralytics.com/settings?tab=api+keys), select your YOLO 🚀 model and start training!"
]
},
{
"cell_type": "code",
"metadata": {
"id": "XSlZaJ9Iw_iZ"
},
"source": [
"hub.login('API_KEY') # use your API key\n",
"\n",
"model = YOLO('https://hub.ultralytics.com/MODEL_ID') # use your model URL\n",
"results = model.train() # train model"
],
"execution_count": null,
"outputs": []
}
]
}
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"gpuType": "T4"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"source": [
"<div align=\"center\">\n",
"\n",
" <a href=\"https://ultralytics.com/yolov8\" target=\"_blank\">\n",
" <img width=\"1024\", src=\"https://raw.githubusercontent.com/ultralytics/assets/main/yolov8/banner-yolov8.png\"></a>\n",
"\n",
" [中文](https://docs.ultralytics.com/zh/) | [한국어](https://docs.ultralytics.com/ko/) | [日本語](https://docs.ultralytics.com/ja/) | [Русский](https://docs.ultralytics.com/ru/) | [Deutsch](https://docs.ultralytics.com/de/) | [Français](https://docs.ultralytics.com/fr/) | [Español](https://docs.ultralytics.com/es/) | [Português](https://docs.ultralytics.com/pt/) | [हिन्दी](https://docs.ultralytics.com/hi/) | [العربية](https://docs.ultralytics.com/ar/)\n",
"\n",
" <a href=\"https://colab.research.google.com/github/ultralytics/ultralytics/blob/main/examples/object_counting.ipynb\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>\n",
"\n",
"Welcome to the Ultralytics YOLOv8 🚀 notebook! <a href=\"https://github.com/ultralytics/ultralytics\">YOLOv8</a> is the latest version of the YOLO (You Only Look Once) AI models developed by <a href=\"https://ultralytics.com\">Ultralytics</a>. This notebook serves as the starting point for exploring the <a href=\"https://docs.ultralytics.com/guides/object-counting/\">Object Counting</a> and understand its features and capabilities.\n",
"\n",
"YOLOv8 models are fast, accurate, and easy to use, making them ideal for various object detection and image segmentation tasks. They can be trained on large datasets and run on diverse hardware platforms, from CPUs to GPUs.\n",
"\n",
"We hope that the resources in this notebook will help you get the most out of <a href=\"https://docs.ultralytics.com/guides/object-counting/\">Ultralytics Object Counting</a>. Please browse the YOLOv8 <a href=\"https://docs.ultralytics.com/\">Docs</a> for details, raise an issue on <a href=\"https://github.com/ultralytics/ultralytics\">GitHub</a> for support, and join our <a href=\"https://ultralytics.com/discord\">Discord</a> community for questions and discussions!\n",
"\n",
"</div>"
],
"metadata": {
"id": "PN1cAxdvd61e"
}
},
{
"cell_type": "markdown",
"source": [
"# Setup\n",
"\n",
"Pip install `ultralytics` and [dependencies](https://github.com/ultralytics/ultralytics/blob/main/pyproject.toml) and check software and hardware."
],
"metadata": {
"id": "o68Sg1oOeZm2"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "9dSwz_uOReMI"
},
"outputs": [],
"source": [
"!pip install ultralytics"
]
},
{
"cell_type": "markdown",
"source": [
"# Ultralytics Object Counting\n",
"\n",
"Counting objects using Ultralytics YOLOv8 entails the precise detection and enumeration of specific objects within videos and camera streams. YOLOv8 demonstrates exceptional performance in real-time applications, delivering efficient and accurate object counting across diverse scenarios such as crowd analysis and surveillance. This is attributed to its advanced algorithms and deep learning capabilities."
],
"metadata": {
"id": "m7VkxQ2aeg7k"
}
},
{
"cell_type": "code",
"source": [
"from ultralytics import YOLO\n",
"from ultralytics.solutions import object_counter\n",
"import cv2\n",
"\n",
"model = YOLO(\"yolov8n.pt\")\n",
"cap = cv2.VideoCapture(\"path/to/video/file.mp4\")\n",
"assert cap.isOpened(), \"Error reading video file\"\n",
"w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))\n",
"\n",
"# Define region points\n",
"region_points = [(20, 400), (1080, 404), (1080, 360), (20, 360)]\n",
"\n",
"# Video writer\n",
"video_writer = cv2.VideoWriter(\"object_counting_output.avi\",\n",
" cv2.VideoWriter_fourcc(*'mp4v'),\n",
" fps,\n",
" (w, h))\n",
"\n",
"# Init Object Counter\n",
"counter = object_counter.ObjectCounter()\n",
"counter.set_args(view_img=True,\n",
" reg_pts=region_points,\n",
" classes_names=model.names,\n",
" draw_tracks=True)\n",
"\n",
"while cap.isOpened():\n",
" success, im0 = cap.read()\n",
" if not success:\n",
" print(\"Video frame is empty or video processing has been successfully completed.\")\n",
" break\n",
" tracks = model.track(im0, persist=True, show=False)\n",
"\n",
" im0 = counter.start_counting(im0, tracks)\n",
" video_writer.write(im0)\n",
"\n",
"cap.release()\n",
"video_writer.release()\n",
"cv2.destroyAllWindows()"
],
"metadata": {
"id": "Cx-u59HQdu2o"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"#Community Support\n",
"\n",
"For more information, you can explore <a href=\"https://docs.ultralytics.com/guides/object-counting/\">Ultralytics Object Counting Docs</a>\n",
"\n",
"Ultralytics ⚡ resources\n",
"- About Us – https://ultralytics.com/about\n",
"- Join Our Team – https://ultralytics.com/work\n",
"- Contact Us – https://ultralytics.com/contact\n",
"- Discord – https://ultralytics.com/discord\n",
"- Ultralytics License – https://ultralytics.com/license\n",
"\n",
"YOLOv8 🚀 resources\n",
"- GitHub – https://github.com/ultralytics/ultralytics\n",
"- Docs – https://docs.ultralytics.com/"
],
"metadata": {
"id": "QrlKg-y3fEyD"
}
}
]
}
\ No newline at end of file
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"gpuType": "T4"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"source": [
"<div align=\"center\">\n",
"\n",
" <a href=\"https://ultralytics.com/yolov8\" target=\"_blank\">\n",
" <img width=\"1024\", src=\"https://raw.githubusercontent.com/ultralytics/assets/main/yolov8/banner-yolov8.png\"></a>\n",
"\n",
" [中文](https://docs.ultralytics.com/zh/) | [한국어](https://docs.ultralytics.com/ko/) | [日本語](https://docs.ultralytics.com/ja/) | [Русский](https://docs.ultralytics.com/ru/) | [Deutsch](https://docs.ultralytics.com/de/) | [Français](https://docs.ultralytics.com/fr/) | [Español](https://docs.ultralytics.com/es/) | [Português](https://docs.ultralytics.com/pt/) | [हिन्दी](https://docs.ultralytics.com/hi/) | [العربية](https://docs.ultralytics.com/ar/)\n",
"\n",
" <a href=\"https://colab.research.google.com/github/ultralytics/ultralytics/blob/main/examples/object_tracking.ipynb\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>\n",
"\n",
"Welcome to the Ultralytics YOLOv8 🚀 notebook! <a href=\"https://github.com/ultralytics/ultralytics\">YOLOv8</a> is the latest version of the YOLO (You Only Look Once) AI models developed by <a href=\"https://ultralytics.com\">Ultralytics</a>. This notebook serves as the starting point for exploring the <a href=\"https://docs.ultralytics.com/modes/track/\">Object Tracking</a> and understand its features and capabilities.\n",
"\n",
"YOLOv8 models are fast, accurate, and easy to use, making them ideal for various object detection and image segmentation tasks. They can be trained on large datasets and run on diverse hardware platforms, from CPUs to GPUs.\n",
"\n",
"We hope that the resources in this notebook will help you get the most out of <a href=\"https://docs.ultralytics.com/modes/track/\">Ultralytics Object Tracking</a>. Please browse the YOLOv8 <a href=\"https://docs.ultralytics.com/\">Docs</a> for details, raise an issue on <a href=\"https://github.com/ultralytics/ultralytics\">GitHub</a> for support, and join our <a href=\"https://ultralytics.com/discord\">Discord</a> community for questions and discussions!\n",
"\n",
"</div>"
],
"metadata": {
"id": "PN1cAxdvd61e"
}
},
{
"cell_type": "markdown",
"source": [
"# Setup\n",
"\n",
"Pip install `ultralytics` and [dependencies](https://github.com/ultralytics/ultralytics/blob/main/pyproject.toml) and check software and hardware."
],
"metadata": {
"id": "o68Sg1oOeZm2"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "9dSwz_uOReMI"
},
"outputs": [],
"source": [
"!pip install ultralytics"
]
},
{
"cell_type": "markdown",
"source": [
"# Ultralytics Object Tracking\n",
"\n",
"Within the domain of video analytics, object tracking stands out as a crucial undertaking. It goes beyond merely identifying the location and class of objects within the frame; it also involves assigning a unique ID to each detected object as the video unfolds. The applications of this technology are vast, spanning from surveillance and security to real-time sports analytics."
],
"metadata": {
"id": "m7VkxQ2aeg7k"
}
},
{
"cell_type": "markdown",
"source": [
"## CLI"
],
"metadata": {
"id": "-ZF9DM6e6gz0"
}
},
{
"cell_type": "code",
"source": [
"!yolo track source=\"/path/to/video/file.mp4\" save=True"
],
"metadata": {
"id": "-XJqhOwo6iqT"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"## Python\n",
"\n",
"- Draw Object tracking trails"
],
"metadata": {
"id": "XRcw0vIE6oNb"
}
},
{
"cell_type": "code",
"source": [
"import cv2\n",
"import numpy as np\n",
"from ultralytics import YOLO\n",
"\n",
"from ultralytics.utils.checks import check_imshow\n",
"from ultralytics.utils.plotting import Annotator, colors\n",
"\n",
"from collections import defaultdict\n",
"\n",
"track_history = defaultdict(lambda: [])\n",
"model = YOLO(\"yolov8n.pt\")\n",
"names = model.model.names\n",
"\n",
"video_path = \"/path/to/video/file.mp4\"\n",
"cap = cv2.VideoCapture(video_path)\n",
"assert cap.isOpened(), \"Error reading video file\"\n",
"\n",
"w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))\n",
"\n",
"result = cv2.VideoWriter(\"object_tracking.avi\",\n",
" cv2.VideoWriter_fourcc(*'mp4v'),\n",
" fps,\n",
" (w, h))\n",
"\n",
"while cap.isOpened():\n",
" success, frame = cap.read()\n",
" if success:\n",
" results = model.track(frame, persist=True, verbose=False)\n",
" boxes = results[0].boxes.xyxy.cpu()\n",
"\n",
" if results[0].boxes.id is not None:\n",
"\n",
" # Extract prediction results\n",
" clss = results[0].boxes.cls.cpu().tolist()\n",
" track_ids = results[0].boxes.id.int().cpu().tolist()\n",
" confs = results[0].boxes.conf.float().cpu().tolist()\n",
"\n",
" # Annotator Init\n",
" annotator = Annotator(frame, line_width=2)\n",
"\n",
" for box, cls, track_id in zip(boxes, clss, track_ids):\n",
" annotator.box_label(box, color=colors(int(cls), True), label=names[int(cls)])\n",
"\n",
" # Store tracking history\n",
" track = track_history[track_id]\n",
" track.append((int((box[0] + box[2]) / 2), int((box[1] + box[3]) / 2)))\n",
" if len(track) > 30:\n",
" track.pop(0)\n",
"\n",
" # Plot tracks\n",
" points = np.array(track, dtype=np.int32).reshape((-1, 1, 2))\n",
" cv2.circle(frame, (track[-1]), 7, colors(int(cls), True), -1)\n",
" cv2.polylines(frame, [points], isClosed=False, color=colors(int(cls), True), thickness=2)\n",
"\n",
" result.write(frame)\n",
" if cv2.waitKey(1) & 0xFF == ord(\"q\"):\n",
" break\n",
" else:\n",
" break\n",
"\n",
"result.release()\n",
"cap.release()\n",
"cv2.destroyAllWindows()"
],
"metadata": {
"id": "Cx-u59HQdu2o"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"#Community Support\n",
"\n",
"For more information, you can explore <a href=\"https://docs.ultralytics.com/modes/track/\">Ultralytics Object Tracking Docs</a>\n",
"\n",
"Ultralytics ⚡ resources\n",
"- About Us – https://ultralytics.com/about\n",
"- Join Our Team – https://ultralytics.com/work\n",
"- Contact Us – https://ultralytics.com/contact\n",
"- Discord – https://ultralytics.com/discord\n",
"- Ultralytics License – https://ultralytics.com/license\n",
"\n",
"YOLOv8 🚀 resources\n",
"- GitHub – https://github.com/ultralytics/ultralytics\n",
"- Docs – https://docs.ultralytics.com/"
],
"metadata": {
"id": "QrlKg-y3fEyD"
}
}
]
}
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "YOLOv8 Tutorial",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "t6MPjfT5NrKQ"
},
"source": [
"<div align=\"center\">\n",
"\n",
" <a href=\"https://ultralytics.com/yolov8\" target=\"_blank\">\n",
" <img width=\"1024\", src=\"https://raw.githubusercontent.com/ultralytics/assets/main/yolov8/banner-yolov8.png\"></a>\n",
"\n",
" [中文](https://docs.ultralytics.com/zh/) | [한국어](https://docs.ultralytics.com/ko/) | [日本語](https://docs.ultralytics.com/ja/) | [Русский](https://docs.ultralytics.com/ru/) | [Deutsch](https://docs.ultralytics.com/de/) | [Français](https://docs.ultralytics.com/fr/) | [Español](https://docs.ultralytics.com/es/) | [Português](https://docs.ultralytics.com/pt/) | [हिन्दी](https://docs.ultralytics.com/hi/) | [العربية](https://docs.ultralytics.com/ar/)\n",
"\n",
" <a href=\"https://console.paperspace.com/github/ultralytics/ultralytics\"><img src=\"https://assets.paperspace.io/img/gradient-badge.svg\" alt=\"Run on Gradient\"/></a>\n",
" <a href=\"https://colab.research.google.com/github/ultralytics/ultralytics/blob/main/examples/tutorial.ipynb\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>\n",
" <a href=\"https://www.kaggle.com/ultralytics/yolov8\"><img src=\"https://kaggle.com/static/images/open-in-kaggle.svg\" alt=\"Open In Kaggle\"></a>\n",
"\n",
"Welcome to the Ultralytics YOLOv8 🚀 notebook! <a href=\"https://github.com/ultralytics/ultralytics\">YOLOv8</a> is the latest version of the YOLO (You Only Look Once) AI models developed by <a href=\"https://ultralytics.com\">Ultralytics</a>. This notebook serves as the starting point for exploring the various resources available to help you get started with YOLOv8 and understand its features and capabilities.\n",
"\n",
"YOLOv8 models are fast, accurate, and easy to use, making them ideal for various object detection and image segmentation tasks. They can be trained on large datasets and run on diverse hardware platforms, from CPUs to GPUs.\n",
"\n",
"We hope that the resources in this notebook will help you get the most out of YOLOv8. Please browse the YOLOv8 <a href=\"https://docs.ultralytics.com/\">Docs</a> for details, raise an issue on <a href=\"https://github.com/ultralytics/ultralytics\">GitHub</a> for support, and join our <a href=\"https://ultralytics.com/discord\">Discord</a> community for questions and discussions!\n",
"\n",
"</div>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7mGmQbAO5pQb"
},
"source": [
"# Setup\n",
"\n",
"Pip install `ultralytics` and [dependencies](https://github.com/ultralytics/ultralytics/blob/main/pyproject.toml) and check software and hardware."
]
},
{
"cell_type": "code",
"metadata": {
"id": "wbvMlHd_QwMG",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "51d15672-e688-4fb8-d9d0-00d1916d3532"
},
"source": [
"%pip install ultralytics\n",
"import ultralytics\n",
"ultralytics.checks()"
],
"execution_count": 1,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Ultralytics YOLOv8.1.23 🚀 Python-3.10.12 torch-2.1.0+cu121 CUDA:0 (Tesla T4, 15102MiB)\n",
"Setup complete ✅ (2 CPUs, 12.7 GB RAM, 26.3/78.2 GB disk)\n"
]
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4JnkELT0cIJg"
},
"source": [
"# 1. Predict\n",
"\n",
"YOLOv8 may be used directly in the Command Line Interface (CLI) with a `yolo` command for a variety of tasks and modes and accepts additional arguments, i.e. `imgsz=640`. See a full list of available `yolo` [arguments](https://docs.ultralytics.com/usage/cfg/) and other details in the [YOLOv8 Predict Docs](https://docs.ultralytics.com/modes/train/).\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "zR9ZbuQCH7FX",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "37738db7-4284-47de-b3ed-b82f2431ed23"
},
"source": [
"# Run inference on an image with YOLOv8n\n",
"!yolo predict model=yolov8n.pt source='https://ultralytics.com/images/zidane.jpg'"
],
"execution_count": 2,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Downloading https://github.com/ultralytics/assets/releases/download/v8.1.0/yolov8n.pt to 'yolov8n.pt'...\n",
"100% 6.23M/6.23M [00:00<00:00, 72.6MB/s]\n",
"Ultralytics YOLOv8.1.23 🚀 Python-3.10.12 torch-2.1.0+cu121 CUDA:0 (Tesla T4, 15102MiB)\n",
"YOLOv8n summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs\n",
"\n",
"Downloading https://ultralytics.com/images/zidane.jpg to 'zidane.jpg'...\n",
"100% 165k/165k [00:00<00:00, 7.05MB/s]\n",
"image 1/1 /content/zidane.jpg: 384x640 2 persons, 1 tie, 162.0ms\n",
"Speed: 13.9ms preprocess, 162.0ms inference, 1259.5ms postprocess per image at shape (1, 3, 384, 640)\n",
"Results saved to \u001b[1mruns/detect/predict\u001b[0m\n",
"💡 Learn more at https://docs.ultralytics.com/modes/predict\n"
]
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "hkAzDWJ7cWTr"
},
"source": [
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n",
"<img align=\"left\" src=\"https://user-images.githubusercontent.com/26833433/212889447-69e5bdf1-5800-4e29-835e-2ed2336dede2.jpg\" width=\"600\">"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0eq1SMWl6Sfn"
},
"source": [
"# 2. Val\n",
"Validate a model's accuracy on the [COCO](https://docs.ultralytics.com/datasets/detect/coco/) dataset's `val` or `test` splits. The latest YOLOv8 [models](https://github.com/ultralytics/ultralytics#models) are downloaded automatically the first time they are used. See [YOLOv8 Val Docs](https://docs.ultralytics.com/modes/val/) for more information."
]
},
{
"cell_type": "code",
"metadata": {
"id": "WQPtK1QYVaD_"
},
"source": [
"# Download COCO val\n",
"import torch\n",
"torch.hub.download_url_to_file('https://ultralytics.com/assets/coco2017val.zip', 'tmp.zip') # download (780M - 5000 images)\n",
"!unzip -q tmp.zip -d datasets && rm tmp.zip # unzip"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "X58w8JLpMnjH",
"outputId": "61001937-ccd2-4157-a373-156a57495231",
"colab": {
"base_uri": "https://localhost:8080/"
}
},
"source": [
"# Validate YOLOv8n on COCO8 val\n",
"!yolo val model=yolov8n.pt data=coco8.yaml"
],
"execution_count": 3,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Ultralytics YOLOv8.1.23 🚀 Python-3.10.12 torch-2.1.0+cu121 CUDA:0 (Tesla T4, 15102MiB)\n",
"YOLOv8n summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs\n",
"\n",
"Dataset 'coco8.yaml' images not found ⚠️, missing path '/content/datasets/coco8/images/val'\n",
"Downloading https://ultralytics.com/assets/coco8.zip to '/content/datasets/coco8.zip'...\n",
"100% 433k/433k [00:00<00:00, 12.5MB/s]\n",
"Unzipping /content/datasets/coco8.zip to /content/datasets/coco8...: 100% 25/25 [00:00<00:00, 4546.38file/s]\n",
"Dataset download success ✅ (0.9s), saved to \u001b[1m/content/datasets\u001b[0m\n",
"\n",
"Downloading https://ultralytics.com/assets/Arial.ttf to '/root/.config/Ultralytics/Arial.ttf'...\n",
"100% 755k/755k [00:00<00:00, 17.8MB/s]\n",
"\u001b[34m\u001b[1mval: \u001b[0mScanning /content/datasets/coco8/labels/val... 4 images, 0 backgrounds, 0 corrupt: 100% 4/4 [00:00<00:00, 275.94it/s]\n",
"\u001b[34m\u001b[1mval: \u001b[0mNew cache created: /content/datasets/coco8/labels/val.cache\n",
" Class Images Instances Box(P R mAP50 mAP50-95): 100% 1/1 [00:02<00:00, 2.23s/it]\n",
" all 4 17 0.621 0.833 0.888 0.63\n",
" person 4 10 0.721 0.5 0.519 0.269\n",
" dog 4 1 0.37 1 0.995 0.597\n",
" horse 4 2 0.751 1 0.995 0.631\n",
" elephant 4 2 0.505 0.5 0.828 0.394\n",
" umbrella 4 1 0.564 1 0.995 0.995\n",
" potted plant 4 1 0.814 1 0.995 0.895\n",
"Speed: 0.3ms preprocess, 56.9ms inference, 0.0ms loss, 222.8ms postprocess per image\n",
"Results saved to \u001b[1mruns/detect/val\u001b[0m\n",
"💡 Learn more at https://docs.ultralytics.com/modes/val\n"
]
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ZY2VXXXu74w5"
},
"source": [
"# 3. Train\n",
"\n",
"<p align=\"\"><a href=\"https://bit.ly/ultralytics_hub\"><img width=\"1000\" src=\"https://github.com/ultralytics/assets/raw/main/yolov8/banner-integrations.png\"/></a></p>\n",
"\n",
"Train YOLOv8 on [Detect](https://docs.ultralytics.com/tasks/detect/), [Segment](https://docs.ultralytics.com/tasks/segment/), [Classify](https://docs.ultralytics.com/tasks/classify/) and [Pose](https://docs.ultralytics.com/tasks/pose/) datasets. See [YOLOv8 Train Docs](https://docs.ultralytics.com/modes/train/) for more information."
]
},
{
"cell_type": "code",
"source": [
"#@title Select YOLOv8 🚀 logger {run: 'auto'}\n",
"logger = 'Comet' #@param ['Comet', 'TensorBoard']\n",
"\n",
"if logger == 'Comet':\n",
" %pip install -q comet_ml\n",
" import comet_ml; comet_ml.init()\n",
"elif logger == 'TensorBoard':\n",
" %load_ext tensorboard\n",
" %tensorboard --logdir ."
],
"metadata": {
"id": "ktegpM42AooT"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "1NcFxRcFdJ_O",
"outputId": "1ec62d53-41eb-444f-e2f7-cef5c18b9a27",
"colab": {
"base_uri": "https://localhost:8080/"
}
},
"source": [
"# Train YOLOv8n on COCO8 for 3 epochs\n",
"!yolo train model=yolov8n.pt data=coco8.yaml epochs=3 imgsz=640"
],
"execution_count": 4,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Ultralytics YOLOv8.1.23 🚀 Python-3.10.12 torch-2.1.0+cu121 CUDA:0 (Tesla T4, 15102MiB)\n",
"\u001b[34m\u001b[1mengine/trainer: \u001b[0mtask=detect, mode=train, model=yolov8n.pt, data=coco8.yaml, epochs=3, time=None, patience=100, batch=16, imgsz=640, save=True, save_period=-1, cache=False, device=None, workers=8, project=None, name=train, exist_ok=False, pretrained=True, optimizer=auto, verbose=True, seed=0, deterministic=True, single_cls=False, rect=False, cos_lr=False, close_mosaic=10, resume=False, amp=True, fraction=1.0, profile=False, freeze=None, multi_scale=False, overlap_mask=True, mask_ratio=4, dropout=0.0, val=True, split=val, save_json=False, save_hybrid=False, conf=None, iou=0.7, max_det=300, half=False, dnn=False, plots=True, source=None, vid_stride=1, stream_buffer=False, visualize=False, augment=False, agnostic_nms=False, classes=None, retina_masks=False, embed=None, show=False, save_frames=False, save_txt=False, save_conf=False, save_crop=False, show_labels=True, show_conf=True, show_boxes=True, line_width=None, format=torchscript, keras=False, optimize=False, int8=False, dynamic=False, simplify=False, opset=None, workspace=4, nms=False, lr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=7.5, cls=0.5, dfl=1.5, pose=12.0, kobj=1.0, label_smoothing=0.0, nbs=64, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, mosaic=1.0, mixup=0.0, copy_paste=0.0, auto_augment=randaugment, erasing=0.4, crop_fraction=1.0, cfg=None, tracker=botsort.yaml, save_dir=runs/detect/train\n",
"\n",
" from n params module arguments \n",
" 0 -1 1 464 ultralytics.nn.modules.conv.Conv [3, 16, 3, 2] \n",
" 1 -1 1 4672 ultralytics.nn.modules.conv.Conv [16, 32, 3, 2] \n",
" 2 -1 1 7360 ultralytics.nn.modules.block.C2f [32, 32, 1, True] \n",
" 3 -1 1 18560 ultralytics.nn.modules.conv.Conv [32, 64, 3, 2] \n",
" 4 -1 2 49664 ultralytics.nn.modules.block.C2f [64, 64, 2, True] \n",
" 5 -1 1 73984 ultralytics.nn.modules.conv.Conv [64, 128, 3, 2] \n",
" 6 -1 2 197632 ultralytics.nn.modules.block.C2f [128, 128, 2, True] \n",
" 7 -1 1 295424 ultralytics.nn.modules.conv.Conv [128, 256, 3, 2] \n",
" 8 -1 1 460288 ultralytics.nn.modules.block.C2f [256, 256, 1, True] \n",
" 9 -1 1 164608 ultralytics.nn.modules.block.SPPF [256, 256, 5] \n",
" 10 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest'] \n",
" 11 [-1, 6] 1 0 ultralytics.nn.modules.conv.Concat [1] \n",
" 12 -1 1 148224 ultralytics.nn.modules.block.C2f [384, 128, 1] \n",
" 13 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest'] \n",
" 14 [-1, 4] 1 0 ultralytics.nn.modules.conv.Concat [1] \n",
" 15 -1 1 37248 ultralytics.nn.modules.block.C2f [192, 64, 1] \n",
" 16 -1 1 36992 ultralytics.nn.modules.conv.Conv [64, 64, 3, 2] \n",
" 17 [-1, 12] 1 0 ultralytics.nn.modules.conv.Concat [1] \n",
" 18 -1 1 123648 ultralytics.nn.modules.block.C2f [192, 128, 1] \n",
" 19 -1 1 147712 ultralytics.nn.modules.conv.Conv [128, 128, 3, 2] \n",
" 20 [-1, 9] 1 0 ultralytics.nn.modules.conv.Concat [1] \n",
" 21 -1 1 493056 ultralytics.nn.modules.block.C2f [384, 256, 1] \n",
" 22 [15, 18, 21] 1 897664 ultralytics.nn.modules.head.Detect [80, [64, 128, 256]] \n",
"Model summary: 225 layers, 3157200 parameters, 3157184 gradients, 8.9 GFLOPs\n",
"\n",
"Transferred 355/355 items from pretrained weights\n",
"\u001b[34m\u001b[1mTensorBoard: \u001b[0mStart with 'tensorboard --logdir runs/detect/train', view at http://localhost:6006/\n",
"Freezing layer 'model.22.dfl.conv.weight'\n",
"\u001b[34m\u001b[1mAMP: \u001b[0mrunning Automatic Mixed Precision (AMP) checks with YOLOv8n...\n",
"\u001b[34m\u001b[1mAMP: \u001b[0mchecks passed ✅\n",
"\u001b[34m\u001b[1mtrain: \u001b[0mScanning /content/datasets/coco8/labels/train... 4 images, 0 backgrounds, 0 corrupt: 100% 4/4 [00:00<00:00, 43351.98it/s]\n",
"\u001b[34m\u001b[1mtrain: \u001b[0mNew cache created: /content/datasets/coco8/labels/train.cache\n",
"\u001b[34m\u001b[1malbumentations: \u001b[0mBlur(p=0.01, blur_limit=(3, 7)), MedianBlur(p=0.01, blur_limit=(3, 7)), ToGray(p=0.01), CLAHE(p=0.01, clip_limit=(1, 4.0), tile_grid_size=(8, 8))\n",
"\u001b[34m\u001b[1mval: \u001b[0mScanning /content/datasets/coco8/labels/val.cache... 4 images, 0 backgrounds, 0 corrupt: 100% 4/4 [00:00<?, ?it/s]\n",
"Plotting labels to runs/detect/train/labels.jpg... \n",
"\u001b[34m\u001b[1moptimizer:\u001b[0m 'optimizer=auto' found, ignoring 'lr0=0.01' and 'momentum=0.937' and determining best 'optimizer', 'lr0' and 'momentum' automatically... \n",
"\u001b[34m\u001b[1moptimizer:\u001b[0m AdamW(lr=0.000119, momentum=0.9) with parameter groups 57 weight(decay=0.0), 64 weight(decay=0.0005), 63 bias(decay=0.0)\n",
"\u001b[34m\u001b[1mTensorBoard: \u001b[0mmodel graph visualization added ✅\n",
"Image sizes 640 train, 640 val\n",
"Using 2 dataloader workers\n",
"Logging results to \u001b[1mruns/detect/train\u001b[0m\n",
"Starting training for 3 epochs...\n",
"\n",
" Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size\n",
" 1/3 0.77G 0.9308 3.155 1.291 32 640: 100% 1/1 [00:01<00:00, 1.70s/it]\n",
" Class Images Instances Box(P R mAP50 mAP50-95): 100% 1/1 [00:00<00:00, 1.90it/s]\n",
" all 4 17 0.858 0.54 0.726 0.51\n",
"\n",
" Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size\n",
" 2/3 0.78G 1.162 3.127 1.518 33 640: 100% 1/1 [00:00<00:00, 8.18it/s]\n",
" Class Images Instances Box(P R mAP50 mAP50-95): 100% 1/1 [00:00<00:00, 3.71it/s]\n",
" all 4 17 0.904 0.526 0.742 0.5\n",
"\n",
" Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size\n",
" 3/3 0.759G 0.925 2.507 1.254 17 640: 100% 1/1 [00:00<00:00, 7.53it/s]\n",
" Class Images Instances Box(P R mAP50 mAP50-95): 100% 1/1 [00:00<00:00, 6.80it/s]\n",
" all 4 17 0.906 0.532 0.741 0.513\n",
"\n",
"3 epochs completed in 0.002 hours.\n",
"Optimizer stripped from runs/detect/train/weights/last.pt, 6.5MB\n",
"Optimizer stripped from runs/detect/train/weights/best.pt, 6.5MB\n",
"\n",
"Validating runs/detect/train/weights/best.pt...\n",
"Ultralytics YOLOv8.1.23 🚀 Python-3.10.12 torch-2.1.0+cu121 CUDA:0 (Tesla T4, 15102MiB)\n",
"Model summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs\n",
" Class Images Instances Box(P R mAP50 mAP50-95): 100% 1/1 [00:00<00:00, 16.31it/s]\n",
" all 4 17 0.906 0.533 0.755 0.515\n",
" person 4 10 0.942 0.3 0.519 0.233\n",
" dog 4 1 1 0 0.332 0.162\n",
" horse 4 2 1 0.9 0.995 0.698\n",
" elephant 4 2 1 0 0.695 0.206\n",
" umbrella 4 1 0.755 1 0.995 0.895\n",
" potted plant 4 1 0.739 1 0.995 0.895\n",
"Speed: 0.3ms preprocess, 6.1ms inference, 0.0ms loss, 2.5ms postprocess per image\n",
"Results saved to \u001b[1mruns/detect/train\u001b[0m\n",
"💡 Learn more at https://docs.ultralytics.com/modes/train\n"
]
}
]
},
{
"cell_type": "markdown",
"source": [
"# 4. Export\n",
"\n",
"Export a YOLOv8 model to any supported format below with the `format` argument, i.e. `format=onnx`. See [YOLOv8 Export Docs](https://docs.ultralytics.com/modes/export/) for more information.\n",
"\n",
"- 💡 ProTip: Export to [ONNX](https://docs.ultralytics.com/integrations/onnx/) or [OpenVINO](https://docs.ultralytics.com/integrations/openvino/) for up to 3x CPU speedup. \n",
"- 💡 ProTip: Export to [TensorRT](https://docs.ultralytics.com/integrations/tensorrt/) for up to 5x GPU speedup.\n",
"\n",
"| Format | `format` Argument | Model | Metadata | Arguments |\n",
"|--------------------------------------------------------------------|-------------------|---------------------------|----------|-----------------------------------------------------|\n",
"| [PyTorch](https://pytorch.org/) | - | `yolov8n.pt` | ✅ | - |\n",
"| [TorchScript](https://pytorch.org/docs/stable/jit.html) | `torchscript` | `yolov8n.torchscript` | ✅ | `imgsz`, `optimize` |\n",
"| [ONNX](https://onnx.ai/) | `onnx` | `yolov8n.onnx` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `opset` |\n",
"| [OpenVINO](https://docs.openvino.ai/) | `openvino` | `yolov8n_openvino_model/` | ✅ | `imgsz`, `half`, `int8` |\n",
"| [TensorRT](https://developer.nvidia.com/tensorrt) | `engine` | `yolov8n.engine` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `workspace` |\n",
"| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n.mlpackage` | ✅ | `imgsz`, `half`, `int8`, `nms` |\n",
"| [TF SavedModel](https://www.tensorflow.org/guide/saved_model) | `saved_model` | `yolov8n_saved_model/` | ✅ | `imgsz`, `keras`, `int8` |\n",
"| [TF GraphDef](https://www.tensorflow.org/api_docs/python/tf/Graph) | `pb` | `yolov8n.pb` | ❌ | `imgsz` |\n",
"| [TF Lite](https://www.tensorflow.org/lite) | `tflite` | `yolov8n.tflite` | ✅ | `imgsz`, `half`, `int8` |\n",
"| [TF Edge TPU](https://coral.ai/docs/edgetpu/models-intro/) | `edgetpu` | `yolov8n_edgetpu.tflite` | ✅ | `imgsz` |\n",
"| [TF.js](https://www.tensorflow.org/js) | `tfjs` | `yolov8n_web_model/` | ✅ | `imgsz`, `half`, `int8` |\n",
"| [PaddlePaddle](https://github.com/PaddlePaddle) | `paddle` | `yolov8n_paddle_model/` | ✅ | `imgsz` |\n",
"| [NCNN](https://github.com/Tencent/ncnn) | `ncnn` | `yolov8n_ncnn_model/` | ✅ | `imgsz`, `half` |\n"
],
"metadata": {
"id": "nPZZeNrLCQG6"
}
},
{
"cell_type": "code",
"source": [
"!yolo export model=yolov8n.pt format=torchscript"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "CYIjW4igCjqD",
"outputId": "f6d45666-07b4-4214-86c0-4e83e70ac096"
},
"execution_count": 5,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Ultralytics YOLOv8.1.23 🚀 Python-3.10.12 torch-2.1.0+cu121 CPU (Intel Xeon 2.30GHz)\n",
"YOLOv8n summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs\n",
"\n",
"\u001b[34m\u001b[1mPyTorch:\u001b[0m starting from 'yolov8n.pt' with input shape (1, 3, 640, 640) BCHW and output shape(s) (1, 84, 8400) (6.2 MB)\n",
"\n",
"\u001b[34m\u001b[1mTorchScript:\u001b[0m starting export with torch 2.1.0+cu121...\n",
"\u001b[34m\u001b[1mTorchScript:\u001b[0m export success ✅ 2.4s, saved as 'yolov8n.torchscript' (12.4 MB)\n",
"\n",
"Export complete (4.5s)\n",
"Results saved to \u001b[1m/content\u001b[0m\n",
"Predict: yolo predict task=detect model=yolov8n.torchscript imgsz=640 \n",
"Validate: yolo val task=detect model=yolov8n.torchscript imgsz=640 data=coco.yaml \n",
"Visualize: https://netron.app\n",
"💡 Learn more at https://docs.ultralytics.com/modes/export\n"
]
}
]
},
{
"cell_type": "markdown",
"source": [
"# 5. Python Usage\n",
"\n",
"YOLOv8 was reimagined using Python-first principles for the most seamless Python YOLO experience yet. YOLOv8 models can be loaded from a trained checkpoint or created from scratch. Then methods are used to train, val, predict, and export the model. See detailed Python usage examples in the [YOLOv8 Python Docs](https://docs.ultralytics.com/usage/python/)."
],
"metadata": {
"id": "kUMOQ0OeDBJG"
}
},
{
"cell_type": "code",
"source": [
"from ultralytics import YOLO\n",
"\n",
"# Load a model\n",
"model = YOLO('yolov8n.yaml') # build a new model from scratch\n",
"model = YOLO('yolov8n.pt') # load a pretrained model (recommended for training)\n",
"\n",
"# Use the model\n",
"results = model.train(data='coco128.yaml', epochs=3) # train the model\n",
"results = model.val() # evaluate model performance on the validation set\n",
"results = model('https://ultralytics.com/images/bus.jpg') # predict on an image\n",
"results = model.export(format='onnx') # export the model to ONNX format"
],
"metadata": {
"id": "bpF9-vS_DAaf"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"# 6. Tasks\n",
"\n",
"YOLOv8 can train, val, predict and export models for the most common tasks in vision AI: [Detect](https://docs.ultralytics.com/tasks/detect/), [Segment](https://docs.ultralytics.com/tasks/segment/), [Classify](https://docs.ultralytics.com/tasks/classify/) and [Pose](https://docs.ultralytics.com/tasks/pose/). See [YOLOv8 Tasks Docs](https://docs.ultralytics.com/tasks/) for more information.\n",
"\n",
"<br><img width=\"1024\" src=\"https://raw.githubusercontent.com/ultralytics/assets/main/im/banner-tasks.png\">\n"
],
"metadata": {
"id": "Phm9ccmOKye5"
}
},
{
"cell_type": "markdown",
"source": [
"## 1. Detection\n",
"\n",
"YOLOv8 _detection_ models have no suffix and are the default YOLOv8 models, i.e. `yolov8n.pt` and are pretrained on COCO. See [Detection Docs](https://docs.ultralytics.com/tasks/detect/) for full details.\n"
],
"metadata": {
"id": "yq26lwpYK1lq"
}
},
{
"cell_type": "code",
"source": [
"# Load YOLOv8n, train it on COCO128 for 3 epochs and predict an image with it\n",
"from ultralytics import YOLO\n",
"\n",
"model = YOLO('yolov8n.pt') # load a pretrained YOLOv8n detection model\n",
"model.train(data='coco128.yaml', epochs=3) # train the model\n",
"model('https://ultralytics.com/images/bus.jpg') # predict on an image"
],
"metadata": {
"id": "8Go5qqS9LbC5"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"## 2. Segmentation\n",
"\n",
"YOLOv8 _segmentation_ models use the `-seg` suffix, i.e. `yolov8n-seg.pt` and are pretrained on COCO. See [Segmentation Docs](https://docs.ultralytics.com/tasks/segment/) for full details.\n"
],
"metadata": {
"id": "7ZW58jUzK66B"
}
},
{
"cell_type": "code",
"source": [
"# Load YOLOv8n-seg, train it on COCO128-seg for 3 epochs and predict an image with it\n",
"from ultralytics import YOLO\n",
"\n",
"model = YOLO('yolov8n-seg.pt') # load a pretrained YOLOv8n segmentation model\n",
"model.train(data='coco128-seg.yaml', epochs=3) # train the model\n",
"model('https://ultralytics.com/images/bus.jpg') # predict on an image"
],
"metadata": {
"id": "WFPJIQl_L5HT"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"## 3. Classification\n",
"\n",
"YOLOv8 _classification_ models use the `-cls` suffix, i.e. `yolov8n-cls.pt` and are pretrained on ImageNet. See [Classification Docs](https://docs.ultralytics.com/tasks/classify/) for full details.\n"
],
"metadata": {
"id": "ax3p94VNK9zR"
}
},
{
"cell_type": "code",
"source": [
"# Load YOLOv8n-cls, train it on mnist160 for 3 epochs and predict an image with it\n",
"from ultralytics import YOLO\n",
"\n",
"model = YOLO('yolov8n-cls.pt') # load a pretrained YOLOv8n classification model\n",
"model.train(data='mnist160', epochs=3) # train the model\n",
"model('https://ultralytics.com/images/bus.jpg') # predict on an image"
],
"metadata": {
"id": "5q9Zu6zlL5rS"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"## 4. Pose\n",
"\n",
"YOLOv8 _pose_ models use the `-pose` suffix, i.e. `yolov8n-pose.pt` and are pretrained on COCO Keypoints. See [Pose Docs](https://docs.ultralytics.com/tasks/pose/) for full details."
],
"metadata": {
"id": "SpIaFLiO11TG"
}
},
{
"cell_type": "code",
"source": [
"# Load YOLOv8n-pose, train it on COCO8-pose for 3 epochs and predict an image with it\n",
"from ultralytics import YOLO\n",
"\n",
"model = YOLO('yolov8n-pose.pt') # load a pretrained YOLOv8n pose model\n",
"model.train(data='coco8-pose.yaml', epochs=3) # train the model\n",
"model('https://ultralytics.com/images/bus.jpg') # predict on an image"
],
"metadata": {
"id": "si4aKFNg19vX"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"## 4. Oriented Bounding Boxes (OBB)\n",
"\n",
"YOLOv8 _OBB_ models use the `-obb` suffix, i.e. `yolov8n-obb.pt` and are pretrained on the DOTA dataset. See [OBB Docs](https://docs.ultralytics.com/tasks/obb/) for full details."
],
"metadata": {
"id": "cf5j_T9-B5F0"
}
},
{
"cell_type": "code",
"source": [
"# Load YOLOv8n-obb, train it on DOTA8 for 3 epochs and predict an image with it\n",
"from ultralytics import YOLO\n",
"\n",
"model = YOLO('yolov8n-obb.pt') # load a pretrained YOLOv8n OBB model\n",
"model.train(data='coco8-dota.yaml', epochs=3) # train the model\n",
"model('https://ultralytics.com/images/bus.jpg') # predict on an image"
],
"metadata": {
"id": "IJNKClOOB5YS"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "IEijrePND_2I"
},
"source": [
"# Appendix\n",
"\n",
"Additional content below."
]
},
{
"cell_type": "code",
"source": [
"# Pip install from source\n",
"!pip install git+https://github.com/ultralytics/ultralytics@main"
],
"metadata": {
"id": "pIdE6i8C3LYp"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# Git clone and run tests on updates branch\n",
"!git clone https://github.com/ultralytics/ultralytics -b main\n",
"%pip install -qe ultralytics"
],
"metadata": {
"id": "uRKlwxSJdhd1"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# Run tests (Git clone only)\n",
"!pytest ultralytics/tests"
],
"metadata": {
"id": "GtPlh7mcCGZX"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# Validate multiple models\n",
"for x in 'nsmlx':\n",
" !yolo val model=yolov8{x}.pt data=coco.yaml"
],
"metadata": {
"id": "Wdc6t_bfzDDk"
},
"execution_count": null,
"outputs": []
}
]
}
from ultralytics import YOLOv10
model = YOLOv10('yolov10n.pt')
# or
# model = YOLOv10.from_pretrained('yolov10s.pt')
model.export('yolov10s.onnx')
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="460.8pt" height="345.6pt" viewBox="0 0 460.8 345.6" xmlns="http://www.w3.org/2000/svg" version="1.1">
<metadata>
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<cc:Work>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:date>2024-05-23T18:13:19.661727</dc:date>
<dc:format>image/svg+xml</dc:format>
<dc:creator>
<cc:Agent>
<dc:title>Matplotlib v3.6.0, https://matplotlib.org/</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
</rdf:RDF>
</metadata>
<defs>
<style type="text/css">*{stroke-linejoin: round; stroke-linecap: butt}</style>
</defs>
<g id="figure_1">
<g id="patch_1">
<path d="M 0 345.6
L 460.8 345.6
L 460.8 0
L 0 0
z
" style="fill: #ffffff"/>
</g>
<g id="axes_1">
<g id="patch_2">
<path d="M 64.28 294.9325
L 450 294.9325
L 450 12.446069
L 64.28 12.446069
z
" style="fill: #ffffff"/>
</g>
<g id="matplotlib.axis_1">
<g id="xtick_1">
<g id="line2d_1">
<defs>
<path id="m4140d279f7" d="M 0 0
L 0 3.5
" style="stroke: #000000; stroke-width: 0.8"/>
</defs>
<g>
<use xlink:href="#m4140d279f7" x="93.711545" y="294.9325" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_1">
<!-- 2.5 -->
<g transform="translate(83.711545 313.0425) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-32" d="M 2934 816
L 2638 0
L 138 0
L 138 116
Q 1241 1122 1691 1759
Q 2141 2397 2141 2925
Q 2141 3328 1894 3587
Q 1647 3847 1303 3847
Q 991 3847 742 3664
Q 494 3481 375 3128
L 259 3128
Q 338 3706 661 4015
Q 984 4325 1469 4325
Q 1984 4325 2329 3994
Q 2675 3663 2675 3213
Q 2675 2891 2525 2569
Q 2294 2063 1775 1497
Q 997 647 803 472
L 1909 472
Q 2247 472 2383 497
Q 2519 522 2628 598
Q 2738 675 2819 816
L 2934 816
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-2e" d="M 800 606
Q 947 606 1047 504
Q 1147 403 1147 259
Q 1147 116 1045 14
Q 944 -88 800 -88
Q 656 -88 554 14
Q 453 116 453 259
Q 453 406 554 506
Q 656 606 800 606
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-35" d="M 2778 4238
L 2534 3706
L 1259 3706
L 981 3138
Q 1809 3016 2294 2522
Q 2709 2097 2709 1522
Q 2709 1188 2573 903
Q 2438 619 2231 419
Q 2025 219 1772 97
Q 1413 -75 1034 -75
Q 653 -75 479 54
Q 306 184 306 341
Q 306 428 378 495
Q 450 563 559 563
Q 641 563 702 538
Q 763 513 909 409
Q 1144 247 1384 247
Q 1750 247 2026 523
Q 2303 800 2303 1197
Q 2303 1581 2056 1914
Q 1809 2247 1375 2428
Q 1034 2569 447 2591
L 1259 4238
L 2778 4238
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-32"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="75"/>
</g>
</g>
</g>
<g id="xtick_2">
<g id="line2d_2">
<g>
<use xlink:href="#m4140d279f7" x="138.782823" y="294.9325" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_2">
<!-- 5.0 -->
<g transform="translate(128.782823 313.0425) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-30" d="M 231 2094
Q 231 2819 450 3342
Q 669 3866 1031 4122
Q 1313 4325 1613 4325
Q 2100 4325 2488 3828
Q 2972 3213 2972 2159
Q 2972 1422 2759 906
Q 2547 391 2217 158
Q 1888 -75 1581 -75
Q 975 -75 572 641
Q 231 1244 231 2094
z
M 844 2016
Q 844 1141 1059 588
Q 1238 122 1591 122
Q 1759 122 1940 273
Q 2122 425 2216 781
Q 2359 1319 2359 2297
Q 2359 3022 2209 3506
Q 2097 3866 1919 4016
Q 1791 4119 1609 4119
Q 1397 4119 1231 3928
Q 1006 3669 925 3112
Q 844 2556 844 2016
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-35"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="75"/>
</g>
</g>
</g>
<g id="xtick_3">
<g id="line2d_3">
<g>
<use xlink:href="#m4140d279f7" x="183.854101" y="294.9325" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_3">
<!-- 7.5 -->
<g transform="translate(173.854101 313.0425) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-37" d="M 644 4238
L 2916 4238
L 2916 4119
L 1503 -88
L 1153 -88
L 2419 3728
L 1253 3728
Q 900 3728 750 3644
Q 488 3500 328 3200
L 238 3234
L 644 4238
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-37"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="75"/>
</g>
</g>
</g>
<g id="xtick_4">
<g id="line2d_4">
<g>
<use xlink:href="#m4140d279f7" x="228.92538" y="294.9325" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_4">
<!-- 10.0 -->
<g transform="translate(214.92538 313.0425) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-31" d="M 750 3822
L 1781 4325
L 1884 4325
L 1884 747
Q 1884 391 1914 303
Q 1944 216 2037 169
Q 2131 122 2419 116
L 2419 0
L 825 0
L 825 116
Q 1125 122 1212 167
Q 1300 213 1334 289
Q 1369 366 1369 747
L 1369 3034
Q 1369 3497 1338 3628
Q 1316 3728 1258 3775
Q 1200 3822 1119 3822
Q 1003 3822 797 3725
L 750 3822
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-31"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="125"/>
</g>
</g>
</g>
<g id="xtick_5">
<g id="line2d_5">
<g>
<use xlink:href="#m4140d279f7" x="273.996658" y="294.9325" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_5">
<!-- 12.5 -->
<g transform="translate(259.996658 313.0425) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-31"/>
<use xlink:href="#TimesNewRomanPSMT-32" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="125"/>
</g>
</g>
</g>
<g id="xtick_6">
<g id="line2d_6">
<g>
<use xlink:href="#m4140d279f7" x="319.067936" y="294.9325" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_6">
<!-- 15.0 -->
<g transform="translate(305.067936 313.0425) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-31"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="125"/>
</g>
</g>
</g>
<g id="xtick_7">
<g id="line2d_7">
<g>
<use xlink:href="#m4140d279f7" x="364.139215" y="294.9325" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_7">
<!-- 17.5 -->
<g transform="translate(350.139215 313.0425) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-31"/>
<use xlink:href="#TimesNewRomanPSMT-37" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="125"/>
</g>
</g>
</g>
<g id="xtick_8">
<g id="line2d_8">
<g>
<use xlink:href="#m4140d279f7" x="409.210493" y="294.9325" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_8">
<!-- 20.0 -->
<g transform="translate(395.210493 313.0425) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-32"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="125"/>
</g>
</g>
</g>
<g id="text_9">
<!-- Latency (ms) -->
<g transform="translate(214.71375 331.575) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-4c" d="M 3669 1172
L 3772 1150
L 3409 0
L 128 0
L 128 116
L 288 116
Q 556 116 672 291
Q 738 391 738 753
L 738 3488
Q 738 3884 650 3984
Q 528 4122 288 4122
L 128 4122
L 128 4238
L 2047 4238
L 2047 4122
Q 1709 4125 1573 4059
Q 1438 3994 1388 3894
Q 1338 3794 1338 3416
L 1338 753
Q 1338 494 1388 397
Q 1425 331 1503 300
Q 1581 269 1991 269
L 2300 269
Q 2788 269 2984 341
Q 3181 413 3343 595
Q 3506 778 3669 1172
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-61" d="M 1822 413
Q 1381 72 1269 19
Q 1100 -59 909 -59
Q 613 -59 420 144
Q 228 347 228 678
Q 228 888 322 1041
Q 450 1253 767 1440
Q 1084 1628 1822 1897
L 1822 2009
Q 1822 2438 1686 2597
Q 1550 2756 1291 2756
Q 1094 2756 978 2650
Q 859 2544 859 2406
L 866 2225
Q 866 2081 792 2003
Q 719 1925 600 1925
Q 484 1925 411 2006
Q 338 2088 338 2228
Q 338 2497 613 2722
Q 888 2947 1384 2947
Q 1766 2947 2009 2819
Q 2194 2722 2281 2516
Q 2338 2381 2338 1966
L 2338 994
Q 2338 584 2353 492
Q 2369 400 2405 369
Q 2441 338 2488 338
Q 2538 338 2575 359
Q 2641 400 2828 588
L 2828 413
Q 2478 -56 2159 -56
Q 2006 -56 1915 50
Q 1825 156 1822 413
z
M 1822 616
L 1822 1706
Q 1350 1519 1213 1441
Q 966 1303 859 1153
Q 753 1003 753 825
Q 753 600 887 451
Q 1022 303 1197 303
Q 1434 303 1822 616
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-74" d="M 1031 3803
L 1031 2863
L 1700 2863
L 1700 2644
L 1031 2644
L 1031 788
Q 1031 509 1111 412
Q 1191 316 1316 316
Q 1419 316 1516 380
Q 1613 444 1666 569
L 1788 569
Q 1678 263 1478 108
Q 1278 -47 1066 -47
Q 922 -47 784 33
Q 647 113 581 261
Q 516 409 516 719
L 516 2644
L 63 2644
L 63 2747
Q 234 2816 414 2980
Q 594 3144 734 3369
Q 806 3488 934 3803
L 1031 3803
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-65" d="M 681 1784
Q 678 1147 991 784
Q 1303 422 1725 422
Q 2006 422 2214 576
Q 2422 731 2563 1106
L 2659 1044
Q 2594 616 2278 264
Q 1963 -88 1488 -88
Q 972 -88 605 314
Q 238 716 238 1394
Q 238 2128 614 2539
Q 991 2950 1559 2950
Q 2041 2950 2350 2633
Q 2659 2316 2659 1784
L 681 1784
z
M 681 1966
L 2006 1966
Q 1991 2241 1941 2353
Q 1863 2528 1708 2628
Q 1553 2728 1384 2728
Q 1125 2728 920 2526
Q 716 2325 681 1966
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-6e" d="M 1034 2341
Q 1538 2947 1994 2947
Q 2228 2947 2397 2830
Q 2566 2713 2666 2444
Q 2734 2256 2734 1869
L 2734 647
Q 2734 375 2778 278
Q 2813 200 2889 156
Q 2966 113 3172 113
L 3172 0
L 1756 0
L 1756 113
L 1816 113
Q 2016 113 2095 173
Q 2175 234 2206 353
Q 2219 400 2219 647
L 2219 1819
Q 2219 2209 2117 2386
Q 2016 2563 1775 2563
Q 1403 2563 1034 2156
L 1034 647
Q 1034 356 1069 288
Q 1113 197 1189 155
Q 1266 113 1500 113
L 1500 0
L 84 0
L 84 113
L 147 113
Q 366 113 442 223
Q 519 334 519 647
L 519 1709
Q 519 2225 495 2337
Q 472 2450 423 2490
Q 375 2531 294 2531
Q 206 2531 84 2484
L 38 2597
L 900 2947
L 1034 2947
L 1034 2341
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-63" d="M 2631 1088
Q 2516 522 2178 217
Q 1841 -88 1431 -88
Q 944 -88 581 321
Q 219 731 219 1428
Q 219 2103 620 2525
Q 1022 2947 1584 2947
Q 2006 2947 2278 2723
Q 2550 2500 2550 2259
Q 2550 2141 2473 2067
Q 2397 1994 2259 1994
Q 2075 1994 1981 2113
Q 1928 2178 1911 2362
Q 1894 2547 1784 2644
Q 1675 2738 1481 2738
Q 1169 2738 978 2506
Q 725 2200 725 1697
Q 725 1184 976 792
Q 1228 400 1656 400
Q 1963 400 2206 609
Q 2378 753 2541 1131
L 2631 1088
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-79" d="M 38 2863
L 1372 2863
L 1372 2747
L 1306 2747
Q 1166 2747 1095 2686
Q 1025 2625 1025 2534
Q 1025 2413 1128 2197
L 1825 753
L 2466 2334
Q 2519 2463 2519 2588
Q 2519 2644 2497 2672
Q 2472 2706 2419 2726
Q 2366 2747 2231 2747
L 2231 2863
L 3163 2863
L 3163 2747
Q 3047 2734 2984 2696
Q 2922 2659 2847 2556
Q 2819 2513 2741 2316
L 1575 -541
Q 1406 -956 1132 -1168
Q 859 -1381 606 -1381
Q 422 -1381 303 -1275
Q 184 -1169 184 -1031
Q 184 -900 270 -820
Q 356 -741 506 -741
Q 609 -741 788 -809
Q 913 -856 944 -856
Q 1038 -856 1148 -759
Q 1259 -663 1372 -384
L 1575 113
L 547 2272
Q 500 2369 397 2513
Q 319 2622 269 2659
Q 197 2709 38 2747
L 38 2863
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-20" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-28" d="M 1988 -1253
L 1988 -1369
Q 1516 -1131 1200 -813
Q 750 -359 506 256
Q 263 872 263 1534
Q 263 2503 741 3301
Q 1219 4100 1988 4444
L 1988 4313
Q 1603 4100 1356 3731
Q 1109 3363 987 2797
Q 866 2231 866 1616
Q 866 947 969 400
Q 1050 -31 1165 -292
Q 1281 -553 1476 -793
Q 1672 -1034 1988 -1253
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-6d" d="M 1050 2338
Q 1363 2650 1419 2697
Q 1559 2816 1721 2881
Q 1884 2947 2044 2947
Q 2313 2947 2506 2790
Q 2700 2634 2766 2338
Q 3088 2713 3309 2830
Q 3531 2947 3766 2947
Q 3994 2947 4170 2830
Q 4347 2713 4450 2447
Q 4519 2266 4519 1878
L 4519 647
Q 4519 378 4559 278
Q 4591 209 4675 161
Q 4759 113 4950 113
L 4950 0
L 3538 0
L 3538 113
L 3597 113
Q 3781 113 3884 184
Q 3956 234 3988 344
Q 4000 397 4000 647
L 4000 1878
Q 4000 2228 3916 2372
Q 3794 2572 3525 2572
Q 3359 2572 3192 2489
Q 3025 2406 2788 2181
L 2781 2147
L 2788 2013
L 2788 647
Q 2788 353 2820 281
Q 2853 209 2943 161
Q 3034 113 3253 113
L 3253 0
L 1806 0
L 1806 113
Q 2044 113 2133 169
Q 2222 225 2256 338
Q 2272 391 2272 647
L 2272 1878
Q 2272 2228 2169 2381
Q 2031 2581 1784 2581
Q 1616 2581 1450 2491
Q 1191 2353 1050 2181
L 1050 647
Q 1050 366 1089 281
Q 1128 197 1204 155
Q 1281 113 1516 113
L 1516 0
L 100 0
L 100 113
Q 297 113 375 155
Q 453 197 493 289
Q 534 381 534 647
L 534 1741
Q 534 2213 506 2350
Q 484 2453 437 2492
Q 391 2531 309 2531
Q 222 2531 100 2484
L 53 2597
L 916 2947
L 1050 2947
L 1050 2338
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-73" d="M 2050 2947
L 2050 1972
L 1947 1972
Q 1828 2431 1642 2597
Q 1456 2763 1169 2763
Q 950 2763 815 2647
Q 681 2531 681 2391
Q 681 2216 781 2091
Q 878 1963 1175 1819
L 1631 1597
Q 2266 1288 2266 781
Q 2266 391 1970 151
Q 1675 -88 1309 -88
Q 1047 -88 709 6
Q 606 38 541 38
Q 469 38 428 -44
L 325 -44
L 325 978
L 428 978
Q 516 541 762 319
Q 1009 97 1316 97
Q 1531 97 1667 223
Q 1803 350 1803 528
Q 1803 744 1651 891
Q 1500 1038 1047 1263
Q 594 1488 453 1669
Q 313 1847 313 2119
Q 313 2472 555 2709
Q 797 2947 1181 2947
Q 1350 2947 1591 2875
Q 1750 2828 1803 2828
Q 1853 2828 1881 2850
Q 1909 2872 1947 2947
L 2050 2947
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-29" d="M 144 4313
L 144 4444
Q 619 4209 934 3891
Q 1381 3434 1625 2820
Q 1869 2206 1869 1541
Q 1869 572 1392 -226
Q 916 -1025 144 -1369
L 144 -1253
Q 528 -1038 776 -670
Q 1025 -303 1145 264
Q 1266 831 1266 1447
Q 1266 2113 1163 2663
Q 1084 3094 967 3353
Q 850 3613 656 3853
Q 463 4094 144 4313
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-4c"/>
<use xlink:href="#TimesNewRomanPSMT-61" x="61.083984"/>
<use xlink:href="#TimesNewRomanPSMT-74" x="105.46875"/>
<use xlink:href="#TimesNewRomanPSMT-65" x="133.251953"/>
<use xlink:href="#TimesNewRomanPSMT-6e" x="177.636719"/>
<use xlink:href="#TimesNewRomanPSMT-63" x="227.636719"/>
<use xlink:href="#TimesNewRomanPSMT-79" x="272.021484"/>
<use xlink:href="#TimesNewRomanPSMT-20" x="322.021484"/>
<use xlink:href="#TimesNewRomanPSMT-28" x="347.021484"/>
<use xlink:href="#TimesNewRomanPSMT-6d" x="380.322266"/>
<use xlink:href="#TimesNewRomanPSMT-73" x="458.105469"/>
<use xlink:href="#TimesNewRomanPSMT-29" x="497.021484"/>
</g>
</g>
</g>
<g id="matplotlib.axis_2">
<g id="ytick_1">
<g id="line2d_9">
<defs>
<path id="mc64356ad97" d="M 0 0
L -3.5 0
" style="stroke: #000000; stroke-width: 0.8"/>
</defs>
<g>
<use xlink:href="#mc64356ad97" x="64.28" y="274.712729" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_10">
<!-- 37.5 -->
<g transform="translate(29.28 280.267729) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-33" d="M 325 3431
Q 506 3859 782 4092
Q 1059 4325 1472 4325
Q 1981 4325 2253 3994
Q 2459 3747 2459 3466
Q 2459 3003 1878 2509
Q 2269 2356 2469 2072
Q 2669 1788 2669 1403
Q 2669 853 2319 450
Q 1863 -75 997 -75
Q 569 -75 414 31
Q 259 138 259 259
Q 259 350 332 419
Q 406 488 509 488
Q 588 488 669 463
Q 722 447 909 348
Q 1097 250 1169 231
Q 1284 197 1416 197
Q 1734 197 1970 444
Q 2206 691 2206 1028
Q 2206 1275 2097 1509
Q 2016 1684 1919 1775
Q 1784 1900 1550 2001
Q 1316 2103 1072 2103
L 972 2103
L 972 2197
Q 1219 2228 1467 2375
Q 1716 2522 1828 2728
Q 1941 2934 1941 3181
Q 1941 3503 1739 3701
Q 1538 3900 1238 3900
Q 753 3900 428 3381
L 325 3431
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-33"/>
<use xlink:href="#TimesNewRomanPSMT-37" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="125"/>
</g>
</g>
</g>
<g id="ytick_2">
<g id="line2d_10">
<g>
<use xlink:href="#mc64356ad97" x="64.28" y="237.815338" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_11">
<!-- 40.0 -->
<g transform="translate(29.28 243.370338) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-34" d="M 2978 1563
L 2978 1119
L 2409 1119
L 2409 0
L 1894 0
L 1894 1119
L 100 1119
L 100 1519
L 2066 4325
L 2409 4325
L 2409 1563
L 2978 1563
z
M 1894 1563
L 1894 3666
L 406 1563
L 1894 1563
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-34"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="125"/>
</g>
</g>
</g>
<g id="ytick_3">
<g id="line2d_11">
<g>
<use xlink:href="#mc64356ad97" x="64.28" y="200.917946" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_12">
<!-- 42.5 -->
<g transform="translate(29.28 206.472946) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-34"/>
<use xlink:href="#TimesNewRomanPSMT-32" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="125"/>
</g>
</g>
</g>
<g id="ytick_4">
<g id="line2d_12">
<g>
<use xlink:href="#mc64356ad97" x="64.28" y="164.020554" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_13">
<!-- 45.0 -->
<g transform="translate(29.28 169.575554) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-34"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="125"/>
</g>
</g>
</g>
<g id="ytick_5">
<g id="line2d_13">
<g>
<use xlink:href="#mc64356ad97" x="64.28" y="127.123162" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_14">
<!-- 47.5 -->
<g transform="translate(29.28 132.678162) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-34"/>
<use xlink:href="#TimesNewRomanPSMT-37" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="125"/>
</g>
</g>
</g>
<g id="ytick_6">
<g id="line2d_14">
<g>
<use xlink:href="#mc64356ad97" x="64.28" y="90.225771" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_15">
<!-- 50.0 -->
<g transform="translate(29.28 95.780771) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-35"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="125"/>
</g>
</g>
</g>
<g id="ytick_7">
<g id="line2d_15">
<g>
<use xlink:href="#mc64356ad97" x="64.28" y="53.328379" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_16">
<!-- 52.5 -->
<g transform="translate(29.28 58.883379) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-35"/>
<use xlink:href="#TimesNewRomanPSMT-32" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="125"/>
</g>
</g>
</g>
<g id="ytick_8">
<g id="line2d_16">
<g>
<use xlink:href="#mc64356ad97" x="64.28" y="16.430987" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_17">
<!-- 55.0 -->
<g transform="translate(29.28 21.985987) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-35"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="125"/>
</g>
</g>
</g>
<g id="text_18">
<!-- COCO AP (%) -->
<g transform="translate(21.8575 201.394284) rotate(-90) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-43" d="M 3853 4334
L 3950 2894
L 3853 2894
Q 3659 3541 3300 3825
Q 2941 4109 2438 4109
Q 2016 4109 1675 3895
Q 1334 3681 1139 3212
Q 944 2744 944 2047
Q 944 1472 1128 1050
Q 1313 628 1683 403
Q 2053 178 2528 178
Q 2941 178 3256 354
Q 3572 531 3950 1056
L 4047 994
Q 3728 428 3303 165
Q 2878 -97 2294 -97
Q 1241 -97 663 684
Q 231 1266 231 2053
Q 231 2688 515 3219
Q 800 3750 1298 4042
Q 1797 4334 2388 4334
Q 2847 4334 3294 4109
Q 3425 4041 3481 4041
Q 3566 4041 3628 4100
Q 3709 4184 3744 4334
L 3853 4334
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-4f" d="M 2341 4334
Q 3166 4334 3770 3707
Q 4375 3081 4375 2144
Q 4375 1178 3765 540
Q 3156 -97 2291 -97
Q 1416 -97 820 525
Q 225 1147 225 2134
Q 225 3144 913 3781
Q 1509 4334 2341 4334
z
M 2281 4106
Q 1713 4106 1369 3684
Q 941 3159 941 2147
Q 941 1109 1384 550
Q 1725 125 2284 125
Q 2881 125 3270 590
Q 3659 1056 3659 2059
Q 3659 3147 3231 3681
Q 2888 4106 2281 4106
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-41" d="M 2928 1419
L 1288 1419
L 1000 750
Q 894 503 894 381
Q 894 284 986 211
Q 1078 138 1384 116
L 1384 0
L 50 0
L 50 116
Q 316 163 394 238
Q 553 388 747 847
L 2238 4334
L 2347 4334
L 3822 809
Q 4000 384 4145 257
Q 4291 131 4550 116
L 4550 0
L 2878 0
L 2878 116
Q 3131 128 3220 200
Q 3309 272 3309 375
Q 3309 513 3184 809
L 2928 1419
z
M 2841 1650
L 2122 3363
L 1384 1650
L 2841 1650
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-50" d="M 1313 1984
L 1313 750
Q 1313 350 1400 253
Q 1519 116 1759 116
L 1922 116
L 1922 0
L 106 0
L 106 116
L 266 116
Q 534 116 650 291
Q 713 388 713 750
L 713 3488
Q 713 3888 628 3984
Q 506 4122 266 4122
L 106 4122
L 106 4238
L 1659 4238
Q 2228 4238 2556 4120
Q 2884 4003 3109 3725
Q 3334 3447 3334 3066
Q 3334 2547 2992 2222
Q 2650 1897 2025 1897
Q 1872 1897 1694 1919
Q 1516 1941 1313 1984
z
M 1313 2163
Q 1478 2131 1606 2115
Q 1734 2100 1825 2100
Q 2150 2100 2386 2351
Q 2622 2603 2622 3003
Q 2622 3278 2509 3514
Q 2397 3750 2190 3867
Q 1984 3984 1722 3984
Q 1563 3984 1313 3925
L 1313 2163
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-25" d="M 4350 4334
L 1263 -175
L 984 -175
L 4072 4334
L 4350 4334
z
M 1138 4334
Q 1559 4334 1792 3984
Q 2025 3634 2025 3181
Q 2025 2638 1762 2341
Q 1500 2044 1131 2044
Q 884 2044 678 2180
Q 472 2316 348 2584
Q 225 2853 225 3181
Q 225 3509 350 3786
Q 475 4063 692 4198
Q 909 4334 1138 4334
z
M 1128 4159
Q 969 4159 845 3971
Q 722 3784 722 3184
Q 722 2750 791 2522
Q 844 2350 956 2256
Q 1022 2200 1119 2200
Q 1269 2200 1375 2363
Q 1531 2603 1531 3166
Q 1531 3759 1378 4000
Q 1278 4159 1128 4159
z
M 4206 2103
Q 4428 2103 4648 1962
Q 4869 1822 4989 1553
Q 5109 1284 5109 963
Q 5109 409 4843 117
Q 4578 -175 4216 -175
Q 3988 -175 3773 -34
Q 3559 106 3436 367
Q 3313 628 3313 963
Q 3313 1291 3436 1562
Q 3559 1834 3773 1968
Q 3988 2103 4206 2103
z
M 4209 1938
Q 4059 1938 3950 1769
Q 3809 1550 3809 941
Q 3809 381 3953 159
Q 4059 0 4209 0
Q 4353 0 4466 172
Q 4616 400 4616 956
Q 4616 1544 4466 1778
Q 4363 1938 4209 1938
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-43"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="66.699219"/>
<use xlink:href="#TimesNewRomanPSMT-43" x="138.916016"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.615234"/>
<use xlink:href="#TimesNewRomanPSMT-20" x="277.832031"/>
<use xlink:href="#TimesNewRomanPSMT-41" x="297.332031"/>
<use xlink:href="#TimesNewRomanPSMT-50" x="369.548828"/>
<use xlink:href="#TimesNewRomanPSMT-20" x="421.414062"/>
<use xlink:href="#TimesNewRomanPSMT-28" x="446.414062"/>
<use xlink:href="#TimesNewRomanPSMT-25" x="479.714844"/>
<use xlink:href="#TimesNewRomanPSMT-29" x="563.015625"/>
</g>
</g>
</g>
<g id="line2d_17">
<path d="M 97.136962 282.092208
L 110.297775 174.351824
L 150.140785 103.508832
L 211.257439 63.659649
" clip-path="url(#p7d6da97f45)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #1f77b4; stroke-width: 1.5"/>
<defs>
<path id="m85ee0838a4" d="M 0 -2
L -0.449028 -0.618034
L -1.902113 -0.618034
L -0.726543 0.236068
L -1.175571 1.618034
L -0 0.763932
L 1.175571 1.618034
L 0.726543 0.236068
L 1.902113 -0.618034
L 0.449028 -0.618034
z
" style="stroke: #1f77b4; stroke-linejoin: bevel"/>
</defs>
<g clip-path="url(#p7d6da97f45)">
<use xlink:href="#m85ee0838a4" x="97.136962" y="282.092208" style="fill: #1f77b4; stroke: #1f77b4; stroke-linejoin: bevel"/>
<use xlink:href="#m85ee0838a4" x="110.297775" y="174.351824" style="fill: #1f77b4; stroke: #1f77b4; stroke-linejoin: bevel"/>
<use xlink:href="#m85ee0838a4" x="150.140785" y="103.508832" style="fill: #1f77b4; stroke: #1f77b4; stroke-linejoin: bevel"/>
<use xlink:href="#m85ee0838a4" x="211.257439" y="63.659649" style="fill: #1f77b4; stroke: #1f77b4; stroke-linejoin: bevel"/>
</g>
</g>
<g id="line2d_18">
<path d="M 289.140608 276.188625
L 355.665814 72.515023
L 432.106703 47.424796
" clip-path="url(#p7d6da97f45)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #ff7f0e; stroke-width: 1.5"/>
<defs>
<path id="m89073d6e76" d="M -2 0
L 2 0
M 0 2
L 0 -2
" style="stroke: #ff7f0e"/>
</defs>
<g clip-path="url(#p7d6da97f45)">
<use xlink:href="#m89073d6e76" x="289.140608" y="276.188625" style="fill: #ff7f0e; stroke: #ff7f0e"/>
<use xlink:href="#m89073d6e76" x="355.665814" y="72.515023" style="fill: #ff7f0e; stroke: #ff7f0e"/>
<use xlink:href="#m89073d6e76" x="432.106703" y="47.424796" style="fill: #ff7f0e; stroke: #ff7f0e"/>
</g>
</g>
<g id="line2d_19">
<path d="M 159.695896 277.664521
L 176.101842 165.49645
L 219.911124 81.370397
L 272.013522 47.424796
L 352.600968 32.66584
" clip-path="url(#p7d6da97f45)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #2ca02c; stroke-width: 1.5"/>
<defs>
<path id="m3d8e52d378" d="M -2 2
L 2 -2
M -2 -2
L 2 2
" style="stroke: #2ca02c"/>
</defs>
<g clip-path="url(#p7d6da97f45)">
<use xlink:href="#m3d8e52d378" x="159.695896" y="277.664521" style="fill: #2ca02c; stroke: #2ca02c"/>
<use xlink:href="#m3d8e52d378" x="176.101842" y="165.49645" style="fill: #2ca02c; stroke: #2ca02c"/>
<use xlink:href="#m3d8e52d378" x="219.911124" y="81.370397" style="fill: #2ca02c; stroke: #2ca02c"/>
<use xlink:href="#m3d8e52d378" x="272.013522" y="47.424796" style="fill: #2ca02c; stroke: #2ca02c"/>
<use xlink:href="#m3d8e52d378" x="352.600968" y="32.66584" style="fill: #2ca02c; stroke: #2ca02c"/>
</g>
</g>
<g id="line2d_20">
<path d="M 239.201631 53.328379
" clip-path="url(#p7d6da97f45)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #d62728; stroke-width: 1.5"/>
<defs>
<path id="m8e31553885" d="M -0 2
L 2 -2
L -2 -2
z
" style="stroke: #d62728; stroke-linejoin: miter"/>
</defs>
<g clip-path="url(#p7d6da97f45)">
<use xlink:href="#m8e31553885" x="239.201631" y="53.328379" style="fill: #d62728; stroke: #d62728; stroke-linejoin: miter"/>
</g>
</g>
<g id="line2d_21">
<path d="M 126.34315 192.062572
L 167.628441 106.460623
L 211.978579 69.563231
L 316.00309 57.756066
" clip-path="url(#p7d6da97f45)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #9467bd; stroke-width: 1.5"/>
<defs>
<path id="ma72cfb9b52" d="M 0 -2
L -2 2
L 2 2
z
" style="stroke: #9467bd; stroke-linejoin: miter"/>
</defs>
<g clip-path="url(#p7d6da97f45)">
<use xlink:href="#ma72cfb9b52" x="126.34315" y="192.062572" style="fill: #9467bd; stroke: #9467bd; stroke-linejoin: miter"/>
<use xlink:href="#ma72cfb9b52" x="167.628441" y="106.460623" style="fill: #9467bd; stroke: #9467bd; stroke-linejoin: miter"/>
<use xlink:href="#ma72cfb9b52" x="211.978579" y="69.563231" style="fill: #9467bd; stroke: #9467bd; stroke-linejoin: miter"/>
<use xlink:href="#ma72cfb9b52" x="316.00309" y="57.756066" style="fill: #9467bd; stroke: #9467bd; stroke-linejoin: miter"/>
</g>
</g>
<g id="line2d_22">
<path d="M 184.394957 221.580485
L 191.966932 169.924137
L 234.694503 99.081145
L 301.58028 68.087336
L 432.467273 48.900692
" clip-path="url(#p7d6da97f45)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #8c564b; stroke-width: 1.5"/>
<defs>
<path id="ma60677f893" d="M -2 -0
L 2 2
L 2 -2
z
" style="stroke: #8c564b; stroke-linejoin: miter"/>
</defs>
<g clip-path="url(#p7d6da97f45)">
<use xlink:href="#ma60677f893" x="184.394957" y="221.580485" style="fill: #8c564b; stroke: #8c564b; stroke-linejoin: miter"/>
<use xlink:href="#ma60677f893" x="191.966932" y="169.924137" style="fill: #8c564b; stroke: #8c564b; stroke-linejoin: miter"/>
<use xlink:href="#ma60677f893" x="234.694503" y="99.081145" style="fill: #8c564b; stroke: #8c564b; stroke-linejoin: miter"/>
<use xlink:href="#ma60677f893" x="301.58028" y="68.087336" style="fill: #8c564b; stroke: #8c564b; stroke-linejoin: miter"/>
<use xlink:href="#ma60677f893" x="432.467273" y="48.900692" style="fill: #8c564b; stroke: #8c564b; stroke-linejoin: miter"/>
</g>
</g>
<g id="line2d_23">
<path d="M 197.014915 187.634885
L 231.088801 146.309806
L 272.374092 75.466814
" clip-path="url(#p7d6da97f45)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #e377c2; stroke-width: 1.5"/>
<defs>
<path id="m495f1a21d2" d="M 2 0
L -2 -2
L -2 2
z
" style="stroke: #e377c2; stroke-linejoin: miter"/>
</defs>
<g clip-path="url(#p7d6da97f45)">
<use xlink:href="#m495f1a21d2" x="197.014915" y="187.634885" style="fill: #e377c2; stroke: #e377c2; stroke-linejoin: miter"/>
<use xlink:href="#m495f1a21d2" x="231.088801" y="146.309806" style="fill: #e377c2; stroke: #e377c2; stroke-linejoin: miter"/>
<use xlink:href="#m495f1a21d2" x="272.374092" y="75.466814" style="fill: #e377c2; stroke: #e377c2; stroke-linejoin: miter"/>
</g>
</g>
<g id="line2d_24">
<path d="M 101.28352 243.71892
L 117.50918 158.116971
L 163.662169 93.177562
L 240.643912 63.659649
" clip-path="url(#p7d6da97f45)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #7f7f7f; stroke-width: 1.5"/>
<defs>
<path id="mdb70240228" d="M 0 -2
L -1.902113 -0.618034
L -1.175571 1.618034
L 1.175571 1.618034
L 1.902113 -0.618034
z
" style="stroke: #7f7f7f; stroke-linejoin: miter"/>
</defs>
<g clip-path="url(#p7d6da97f45)">
<use xlink:href="#mdb70240228" x="101.28352" y="243.71892" style="fill: #7f7f7f; stroke: #7f7f7f; stroke-linejoin: miter"/>
<use xlink:href="#mdb70240228" x="117.50918" y="158.116971" style="fill: #7f7f7f; stroke: #7f7f7f; stroke-linejoin: miter"/>
<use xlink:href="#mdb70240228" x="163.662169" y="93.177562" style="fill: #7f7f7f; stroke: #7f7f7f; stroke-linejoin: miter"/>
<use xlink:href="#mdb70240228" x="240.643912" y="63.659649" style="fill: #7f7f7f; stroke: #7f7f7f; stroke-linejoin: miter"/>
</g>
</g>
<g id="line2d_25">
<path d="M 131.210848 141.882119
L 162.580458 106.460623
L 173.036995 71.039127
L 214.502571 44.473005
L 295.811157 26.762257
" clip-path="url(#p7d6da97f45)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #bcbd22; stroke-width: 1.5"/>
<defs>
<path id="m62d0d67ab0" d="M 0 -2
L -1.732051 -1
L -1.732051 1
L -0 2
L 1.732051 1
L 1.732051 -1
z
" style="stroke: #bcbd22; stroke-linejoin: miter"/>
</defs>
<g clip-path="url(#p7d6da97f45)">
<use xlink:href="#m62d0d67ab0" x="131.210848" y="141.882119" style="fill: #bcbd22; stroke: #bcbd22; stroke-linejoin: miter"/>
<use xlink:href="#m62d0d67ab0" x="162.580458" y="106.460623" style="fill: #bcbd22; stroke: #bcbd22; stroke-linejoin: miter"/>
<use xlink:href="#m62d0d67ab0" x="173.036995" y="71.039127" style="fill: #bcbd22; stroke: #bcbd22; stroke-linejoin: miter"/>
<use xlink:href="#m62d0d67ab0" x="214.502571" y="44.473005" style="fill: #bcbd22; stroke: #bcbd22; stroke-linejoin: miter"/>
<use xlink:href="#m62d0d67ab0" x="295.811157" y="26.762257" style="fill: #bcbd22; stroke: #bcbd22; stroke-linejoin: miter"/>
</g>
</g>
<g id="line2d_26">
<path d="M 81.812727 259.953773
L 93.53126 144.83391
L 134.09541 73.990918
L 152.123921 53.328379
L 179.887829 42.997109
L 241.545338 25.286361
" clip-path="url(#p7d6da97f45)" style="fill: none; stroke: #ff0000; stroke-width: 3; stroke-linecap: square"/>
<defs>
<path id="m095d5157fe" d="M 0 3
C 0.795609 3 1.55874 2.683901 2.12132 2.12132
C 2.683901 1.55874 3 0.795609 3 0
C 3 -0.795609 2.683901 -1.55874 2.12132 -2.12132
C 1.55874 -2.683901 0.795609 -3 0 -3
C -0.795609 -3 -1.55874 -2.683901 -2.12132 -2.12132
C -2.683901 -1.55874 -3 -0.795609 -3 0
C -3 0.795609 -2.683901 1.55874 -2.12132 2.12132
C -1.55874 2.683901 -0.795609 3 0 3
z
" style="stroke: #ff0000"/>
</defs>
<g clip-path="url(#p7d6da97f45)">
<use xlink:href="#m095d5157fe" x="81.812727" y="259.953773" style="fill: #ff0000; stroke: #ff0000"/>
<use xlink:href="#m095d5157fe" x="93.53126" y="144.83391" style="fill: #ff0000; stroke: #ff0000"/>
<use xlink:href="#m095d5157fe" x="134.09541" y="73.990918" style="fill: #ff0000; stroke: #ff0000"/>
<use xlink:href="#m095d5157fe" x="152.123921" y="53.328379" style="fill: #ff0000; stroke: #ff0000"/>
<use xlink:href="#m095d5157fe" x="179.887829" y="42.997109" style="fill: #ff0000; stroke: #ff0000"/>
<use xlink:href="#m095d5157fe" x="241.545338" y="25.286361" style="fill: #ff0000; stroke: #ff0000"/>
</g>
</g>
<g id="patch_3">
<path d="M 64.28 294.9325
L 64.28 12.446069
" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/>
</g>
<g id="patch_4">
<path d="M 450 294.9325
L 450 12.446069
" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/>
</g>
<g id="patch_5">
<path d="M 64.28 294.9325
L 450 294.9325
" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/>
</g>
<g id="patch_6">
<path d="M 64.28 12.446069
L 450 12.446069
" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/>
</g>
<g id="legend_1">
<g id="patch_7">
<path d="M 295.472812 287.9325
L 440.2 287.9325
Q 443 287.9325 443 285.1325
L 443 88.585625
Q 443 85.785625 440.2 85.785625
L 295.472812 85.785625
Q 292.672812 85.785625 292.672812 88.585625
L 292.672812 285.1325
Q 292.672812 287.9325 295.472812 287.9325
z
" style="fill: #ffffff; opacity: 0.8; stroke: #cccccc; stroke-linejoin: miter"/>
</g>
<g id="line2d_27">
<path d="M 298.272812 96.285625
L 312.272812 96.285625
L 326.272812 96.285625
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #1f77b4; stroke-width: 1.5"/>
<g>
<use xlink:href="#m85ee0838a4" x="312.272812" y="96.285625" style="fill: #1f77b4; stroke: #1f77b4; stroke-linejoin: bevel"/>
</g>
</g>
<g id="text_19">
<!-- YOLOv6-v3.0 -->
<g transform="translate(337.472812 101.185625) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-59" d="M 3050 4238
L 4528 4238
L 4528 4122
L 4447 4122
Q 4366 4122 4209 4050
Q 4053 3978 3925 3843
Q 3797 3709 3609 3406
L 2588 1797
L 2588 734
Q 2588 344 2675 247
Q 2794 116 3050 116
L 3188 116
L 3188 0
L 1388 0
L 1388 116
L 1538 116
Q 1806 116 1919 278
Q 1988 378 1988 734
L 1988 1738
L 825 3513
Q 619 3825 545 3903
Q 472 3981 241 4091
Q 178 4122 59 4122
L 59 4238
L 1872 4238
L 1872 4122
L 1778 4122
Q 1631 4122 1507 4053
Q 1384 3984 1384 3847
Q 1384 3734 1575 3441
L 2459 2075
L 3291 3381
Q 3478 3675 3478 3819
Q 3478 3906 3433 3975
Q 3388 4044 3303 4083
Q 3219 4122 3050 4122
L 3050 4238
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-76" d="M 53 2863
L 1400 2863
L 1400 2747
L 1313 2747
Q 1191 2747 1127 2687
Q 1063 2628 1063 2528
Q 1063 2419 1128 2269
L 1794 688
L 2463 2328
Q 2534 2503 2534 2594
Q 2534 2638 2509 2666
Q 2475 2713 2422 2730
Q 2369 2747 2206 2747
L 2206 2863
L 3141 2863
L 3141 2747
Q 2978 2734 2916 2681
Q 2806 2588 2719 2369
L 1703 -88
L 1575 -88
L 553 2328
Q 484 2497 421 2570
Q 359 2644 263 2694
Q 209 2722 53 2747
L 53 2863
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-36" d="M 2869 4325
L 2869 4209
Q 2456 4169 2195 4045
Q 1934 3922 1679 3669
Q 1425 3416 1258 3105
Q 1091 2794 978 2366
Q 1428 2675 1881 2675
Q 2316 2675 2634 2325
Q 2953 1975 2953 1425
Q 2953 894 2631 456
Q 2244 -75 1606 -75
Q 1172 -75 869 213
Q 275 772 275 1663
Q 275 2231 503 2743
Q 731 3256 1154 3653
Q 1578 4050 1965 4187
Q 2353 4325 2688 4325
L 2869 4325
z
M 925 2138
Q 869 1716 869 1456
Q 869 1156 980 804
Q 1091 453 1309 247
Q 1469 100 1697 100
Q 1969 100 2183 356
Q 2397 613 2397 1088
Q 2397 1622 2184 2012
Q 1972 2403 1581 2403
Q 1463 2403 1327 2353
Q 1191 2303 925 2138
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-2d" d="M 259 1672
L 1875 1672
L 1875 1200
L 259 1200
L 259 1672
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-59"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="144.433594"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.517578"/>
<use xlink:href="#TimesNewRomanPSMT-76" x="277.734375"/>
<use xlink:href="#TimesNewRomanPSMT-36" x="327.734375"/>
<use xlink:href="#TimesNewRomanPSMT-2d" x="377.734375"/>
<use xlink:href="#TimesNewRomanPSMT-76" x="411.035156"/>
<use xlink:href="#TimesNewRomanPSMT-33" x="461.035156"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="511.035156"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="536.035156"/>
</g>
</g>
<g id="line2d_28">
<path d="M 298.272812 116.080312
L 312.272812 116.080312
L 326.272812 116.080312
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #ff7f0e; stroke-width: 1.5"/>
<g>
<use xlink:href="#m89073d6e76" x="312.272812" y="116.080312" style="fill: #ff7f0e; stroke: #ff7f0e"/>
</g>
</g>
<g id="text_20">
<!-- YOLOv7 -->
<g transform="translate(337.472812 120.980312) scale(0.14 -0.14)">
<use xlink:href="#TimesNewRomanPSMT-59"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="144.433594"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.517578"/>
<use xlink:href="#TimesNewRomanPSMT-76" x="277.734375"/>
<use xlink:href="#TimesNewRomanPSMT-37" x="327.734375"/>
</g>
</g>
<g id="line2d_29">
<path d="M 298.272812 135.875
L 312.272812 135.875
L 326.272812 135.875
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #2ca02c; stroke-width: 1.5"/>
<g>
<use xlink:href="#m3d8e52d378" x="312.272812" y="135.875" style="fill: #2ca02c; stroke: #2ca02c"/>
</g>
</g>
<g id="text_21">
<!-- YOLOv8 -->
<g transform="translate(337.472812 140.775) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-38" d="M 1228 2134
Q 725 2547 579 2797
Q 434 3047 434 3316
Q 434 3728 753 4026
Q 1072 4325 1600 4325
Q 2113 4325 2425 4047
Q 2738 3769 2738 3413
Q 2738 3175 2569 2928
Q 2400 2681 1866 2347
Q 2416 1922 2594 1678
Q 2831 1359 2831 1006
Q 2831 559 2490 242
Q 2150 -75 1597 -75
Q 994 -75 656 303
Q 388 606 388 966
Q 388 1247 577 1523
Q 766 1800 1228 2134
z
M 1719 2469
Q 2094 2806 2194 3001
Q 2294 3197 2294 3444
Q 2294 3772 2109 3958
Q 1925 4144 1606 4144
Q 1288 4144 1088 3959
Q 888 3775 888 3528
Q 888 3366 970 3203
Q 1053 3041 1206 2894
L 1719 2469
z
M 1375 2016
Q 1116 1797 991 1539
Q 866 1281 866 981
Q 866 578 1086 336
Q 1306 94 1647 94
Q 1984 94 2187 284
Q 2391 475 2391 747
Q 2391 972 2272 1150
Q 2050 1481 1375 2016
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-59"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="144.433594"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.517578"/>
<use xlink:href="#TimesNewRomanPSMT-76" x="277.734375"/>
<use xlink:href="#TimesNewRomanPSMT-38" x="327.734375"/>
</g>
</g>
<g id="line2d_30">
<path d="M 298.272812 155.669687
L 312.272812 155.669687
L 326.272812 155.669687
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #d62728; stroke-width: 1.5"/>
<g>
<use xlink:href="#m8e31553885" x="312.272812" y="155.669687" style="fill: #d62728; stroke: #d62728; stroke-linejoin: miter"/>
</g>
</g>
<g id="text_22">
<!-- YOLOv9 -->
<g transform="translate(337.472812 160.569687) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-39" d="M 338 -88
L 338 28
Q 744 34 1094 217
Q 1444 400 1770 856
Q 2097 1313 2225 1859
Q 1734 1544 1338 1544
Q 891 1544 572 1889
Q 253 2234 253 2806
Q 253 3363 572 3797
Q 956 4325 1575 4325
Q 2097 4325 2469 3894
Q 2925 3359 2925 2575
Q 2925 1869 2578 1258
Q 2231 647 1613 244
Q 1109 -88 516 -88
L 338 -88
z
M 2275 2091
Q 2331 2497 2331 2741
Q 2331 3044 2228 3395
Q 2125 3747 1936 3934
Q 1747 4122 1506 4122
Q 1228 4122 1018 3872
Q 809 3622 809 3128
Q 809 2469 1088 2097
Q 1291 1828 1588 1828
Q 1731 1828 1928 1897
Q 2125 1966 2275 2091
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-59"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="144.433594"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.517578"/>
<use xlink:href="#TimesNewRomanPSMT-76" x="277.734375"/>
<use xlink:href="#TimesNewRomanPSMT-39" x="327.734375"/>
</g>
</g>
<g id="line2d_31">
<path d="M 298.272812 175.464375
L 312.272812 175.464375
L 326.272812 175.464375
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #9467bd; stroke-width: 1.5"/>
<g>
<use xlink:href="#ma72cfb9b52" x="312.272812" y="175.464375" style="fill: #9467bd; stroke: #9467bd; stroke-linejoin: miter"/>
</g>
</g>
<g id="text_23">
<!-- PPYOLOE -->
<g transform="translate(337.472812 180.364375) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-45" d="M 1338 4006
L 1338 2331
L 2269 2331
Q 2631 2331 2753 2441
Q 2916 2584 2934 2947
L 3050 2947
L 3050 1472
L 2934 1472
Q 2891 1781 2847 1869
Q 2791 1978 2662 2040
Q 2534 2103 2269 2103
L 1338 2103
L 1338 706
Q 1338 425 1363 364
Q 1388 303 1450 267
Q 1513 231 1688 231
L 2406 231
Q 2766 231 2928 281
Q 3091 331 3241 478
Q 3434 672 3638 1063
L 3763 1063
L 3397 0
L 131 0
L 131 116
L 281 116
Q 431 116 566 188
Q 666 238 702 338
Q 738 438 738 747
L 738 3500
Q 738 3903 656 3997
Q 544 4122 281 4122
L 131 4122
L 131 4238
L 3397 4238
L 3444 3309
L 3322 3309
Q 3256 3644 3176 3769
Q 3097 3894 2941 3959
Q 2816 4006 2500 4006
L 1338 4006
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-50"/>
<use xlink:href="#TimesNewRomanPSMT-50" x="55.615234"/>
<use xlink:href="#TimesNewRomanPSMT-59" x="111.230469"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="183.447266"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="255.664062"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="316.748047"/>
<use xlink:href="#TimesNewRomanPSMT-45" x="388.964844"/>
</g>
</g>
<g id="line2d_32">
<path d="M 298.272812 195.259062
L 312.272812 195.259062
L 326.272812 195.259062
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #8c564b; stroke-width: 1.5"/>
<g>
<use xlink:href="#ma60677f893" x="312.272812" y="195.259062" style="fill: #8c564b; stroke: #8c564b; stroke-linejoin: miter"/>
</g>
</g>
<g id="text_24">
<!-- RTMDet -->
<g transform="translate(337.472812 200.159062) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-52" d="M 4325 0
L 3194 0
L 1759 1981
Q 1600 1975 1500 1975
Q 1459 1975 1412 1976
Q 1366 1978 1316 1981
L 1316 750
Q 1316 350 1403 253
Q 1522 116 1759 116
L 1925 116
L 1925 0
L 109 0
L 109 116
L 269 116
Q 538 116 653 291
Q 719 388 719 750
L 719 3488
Q 719 3888 631 3984
Q 509 4122 269 4122
L 109 4122
L 109 4238
L 1653 4238
Q 2328 4238 2648 4139
Q 2969 4041 3192 3777
Q 3416 3513 3416 3147
Q 3416 2756 3161 2468
Q 2906 2181 2372 2063
L 3247 847
Q 3547 428 3762 290
Q 3978 153 4325 116
L 4325 0
z
M 1316 2178
Q 1375 2178 1419 2176
Q 1463 2175 1491 2175
Q 2097 2175 2405 2437
Q 2713 2700 2713 3106
Q 2713 3503 2464 3751
Q 2216 4000 1806 4000
Q 1625 4000 1316 3941
L 1316 2178
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-54" d="M 3703 4238
L 3750 3244
L 3631 3244
Q 3597 3506 3538 3619
Q 3441 3800 3280 3886
Q 3119 3972 2856 3972
L 2259 3972
L 2259 734
Q 2259 344 2344 247
Q 2463 116 2709 116
L 2856 116
L 2856 0
L 1059 0
L 1059 116
L 1209 116
Q 1478 116 1591 278
Q 1659 378 1659 734
L 1659 3972
L 1150 3972
Q 853 3972 728 3928
Q 566 3869 450 3700
Q 334 3531 313 3244
L 194 3244
L 244 4238
L 3703 4238
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-4d" d="M 2619 0
L 981 3566
L 981 734
Q 981 344 1066 247
Q 1181 116 1431 116
L 1581 116
L 1581 0
L 106 0
L 106 116
L 256 116
Q 525 116 638 278
Q 706 378 706 734
L 706 3503
Q 706 3784 644 3909
Q 600 4000 483 4061
Q 366 4122 106 4122
L 106 4238
L 1306 4238
L 2844 922
L 4356 4238
L 5556 4238
L 5556 4122
L 5409 4122
Q 5138 4122 5025 3959
Q 4956 3859 4956 3503
L 4956 734
Q 4956 344 5044 247
Q 5159 116 5409 116
L 5556 116
L 5556 0
L 3756 0
L 3756 116
L 3906 116
Q 4178 116 4288 278
Q 4356 378 4356 734
L 4356 3566
L 2722 0
L 2619 0
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-44" d="M 109 0
L 109 116
L 269 116
Q 538 116 650 288
Q 719 391 719 750
L 719 3488
Q 719 3884 631 3984
Q 509 4122 269 4122
L 109 4122
L 109 4238
L 1834 4238
Q 2784 4238 3279 4022
Q 3775 3806 4076 3303
Q 4378 2800 4378 2141
Q 4378 1256 3841 663
Q 3238 0 2003 0
L 109 0
z
M 1319 306
Q 1716 219 1984 219
Q 2709 219 3187 728
Q 3666 1238 3666 2109
Q 3666 2988 3187 3494
Q 2709 4000 1959 4000
Q 1678 4000 1319 3909
L 1319 306
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-52"/>
<use xlink:href="#TimesNewRomanPSMT-54" x="60.699219"/>
<use xlink:href="#TimesNewRomanPSMT-4d" x="121.783203"/>
<use xlink:href="#TimesNewRomanPSMT-44" x="210.699219"/>
<use xlink:href="#TimesNewRomanPSMT-65" x="282.916016"/>
<use xlink:href="#TimesNewRomanPSMT-74" x="327.300781"/>
</g>
</g>
<g id="line2d_33">
<path d="M 298.272812 215.05375
L 312.272812 215.05375
L 326.272812 215.05375
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #e377c2; stroke-width: 1.5"/>
<g>
<use xlink:href="#m495f1a21d2" x="312.272812" y="215.05375" style="fill: #e377c2; stroke: #e377c2; stroke-linejoin: miter"/>
</g>
</g>
<g id="text_25">
<!-- YOLO-MS -->
<g transform="translate(337.472812 219.95375) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-53" d="M 2934 4334
L 2934 2869
L 2819 2869
Q 2763 3291 2617 3541
Q 2472 3791 2203 3937
Q 1934 4084 1647 4084
Q 1322 4084 1109 3886
Q 897 3688 897 3434
Q 897 3241 1031 3081
Q 1225 2847 1953 2456
Q 2547 2138 2764 1967
Q 2981 1797 3098 1565
Q 3216 1334 3216 1081
Q 3216 600 2842 251
Q 2469 -97 1881 -97
Q 1697 -97 1534 -69
Q 1438 -53 1133 45
Q 828 144 747 144
Q 669 144 623 97
Q 578 50 556 -97
L 441 -97
L 441 1356
L 556 1356
Q 638 900 775 673
Q 913 447 1195 297
Q 1478 147 1816 147
Q 2206 147 2432 353
Q 2659 559 2659 841
Q 2659 997 2573 1156
Q 2488 1316 2306 1453
Q 2184 1547 1640 1851
Q 1097 2156 867 2337
Q 638 2519 519 2737
Q 400 2956 400 3219
Q 400 3675 750 4004
Q 1100 4334 1641 4334
Q 1978 4334 2356 4169
Q 2531 4091 2603 4091
Q 2684 4091 2736 4139
Q 2788 4188 2819 4334
L 2934 4334
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-59"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="144.433594"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.517578"/>
<use xlink:href="#TimesNewRomanPSMT-2d" x="277.734375"/>
<use xlink:href="#TimesNewRomanPSMT-4d" x="311.035156"/>
<use xlink:href="#TimesNewRomanPSMT-53" x="399.951172"/>
</g>
</g>
<g id="line2d_34">
<path d="M 298.272812 234.848437
L 312.272812 234.848437
L 326.272812 234.848437
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #7f7f7f; stroke-width: 1.5"/>
<g>
<use xlink:href="#mdb70240228" x="312.272812" y="234.848437" style="fill: #7f7f7f; stroke: #7f7f7f; stroke-linejoin: miter"/>
</g>
</g>
<g id="text_26">
<!-- Gold-YOLO -->
<g transform="translate(337.472812 239.748437) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-47" d="M 3928 4334
L 4038 2997
L 3928 2997
Q 3763 3497 3500 3750
Q 3122 4116 2528 4116
Q 1719 4116 1297 3475
Q 944 2934 944 2188
Q 944 1581 1178 1081
Q 1413 581 1792 348
Q 2172 116 2572 116
Q 2806 116 3025 175
Q 3244 234 3447 350
L 3447 1575
Q 3447 1894 3398 1992
Q 3350 2091 3248 2142
Q 3147 2194 2891 2194
L 2891 2313
L 4531 2313
L 4531 2194
L 4453 2194
Q 4209 2194 4119 2031
Q 4056 1916 4056 1575
L 4056 278
Q 3697 84 3347 -6
Q 2997 -97 2569 -97
Q 1341 -97 703 691
Q 225 1281 225 2053
Q 225 2613 494 3125
Q 813 3734 1369 4063
Q 1834 4334 2469 4334
Q 2700 4334 2889 4296
Q 3078 4259 3425 4131
Q 3600 4066 3659 4066
Q 3719 4066 3761 4120
Q 3803 4175 3813 4334
L 3928 4334
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-6f" d="M 1600 2947
Q 2250 2947 2644 2453
Q 2978 2031 2978 1484
Q 2978 1100 2793 706
Q 2609 313 2286 112
Q 1963 -88 1566 -88
Q 919 -88 538 428
Q 216 863 216 1403
Q 216 1797 411 2186
Q 606 2575 925 2761
Q 1244 2947 1600 2947
z
M 1503 2744
Q 1338 2744 1170 2645
Q 1003 2547 900 2300
Q 797 2053 797 1666
Q 797 1041 1045 587
Q 1294 134 1700 134
Q 2003 134 2200 384
Q 2397 634 2397 1244
Q 2397 2006 2069 2444
Q 1847 2744 1503 2744
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-6c" d="M 1184 4444
L 1184 647
Q 1184 378 1223 290
Q 1263 203 1344 158
Q 1425 113 1647 113
L 1647 0
L 244 0
L 244 113
Q 441 113 512 153
Q 584 194 625 287
Q 666 381 666 647
L 666 3247
Q 666 3731 644 3842
Q 622 3953 573 3993
Q 525 4034 450 4034
Q 369 4034 244 3984
L 191 4094
L 1044 4444
L 1184 4444
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-64" d="M 2222 322
Q 2013 103 1813 7
Q 1613 -88 1381 -88
Q 913 -88 563 304
Q 213 697 213 1313
Q 213 1928 600 2439
Q 988 2950 1597 2950
Q 1975 2950 2222 2709
L 2222 3238
Q 2222 3728 2198 3840
Q 2175 3953 2125 3993
Q 2075 4034 2000 4034
Q 1919 4034 1784 3984
L 1744 4094
L 2597 4444
L 2738 4444
L 2738 1134
Q 2738 631 2761 520
Q 2784 409 2836 365
Q 2888 322 2956 322
Q 3041 322 3181 375
L 3216 266
L 2366 -88
L 2222 -88
L 2222 322
z
M 2222 541
L 2222 2016
Q 2203 2228 2109 2403
Q 2016 2578 1861 2667
Q 1706 2756 1559 2756
Q 1284 2756 1069 2509
Q 784 2184 784 1559
Q 784 928 1059 592
Q 1334 256 1672 256
Q 1956 256 2222 541
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-47"/>
<use xlink:href="#TimesNewRomanPSMT-6f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-6c" x="122.216797"/>
<use xlink:href="#TimesNewRomanPSMT-64" x="150"/>
<use xlink:href="#TimesNewRomanPSMT-2d" x="200"/>
<use xlink:href="#TimesNewRomanPSMT-59" x="233.300781"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="305.517578"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="377.734375"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="438.818359"/>
</g>
</g>
<g id="line2d_35">
<path d="M 298.272812 254.643125
L 312.272812 254.643125
L 326.272812 254.643125
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #bcbd22; stroke-width: 1.5"/>
<g>
<use xlink:href="#m62d0d67ab0" x="312.272812" y="254.643125" style="fill: #bcbd22; stroke: #bcbd22; stroke-linejoin: miter"/>
</g>
</g>
<g id="text_27">
<!-- RT-DETR -->
<g transform="translate(337.472812 259.543125) scale(0.14 -0.14)">
<use xlink:href="#TimesNewRomanPSMT-52"/>
<use xlink:href="#TimesNewRomanPSMT-54" x="60.699219"/>
<use xlink:href="#TimesNewRomanPSMT-2d" x="112.658203"/>
<use xlink:href="#TimesNewRomanPSMT-44" x="145.958984"/>
<use xlink:href="#TimesNewRomanPSMT-45" x="218.175781"/>
<use xlink:href="#TimesNewRomanPSMT-54" x="279.259766"/>
<use xlink:href="#TimesNewRomanPSMT-52" x="340.34375"/>
</g>
</g>
<g id="line2d_36">
<path d="M 298.272812 274.437812
L 312.272812 274.437812
L 326.272812 274.437812
" style="fill: none; stroke: #ff0000; stroke-width: 3; stroke-linecap: square"/>
<g>
<use xlink:href="#m095d5157fe" x="312.272812" y="274.437812" style="fill: #ff0000; stroke: #ff0000"/>
</g>
</g>
<g id="text_28">
<!-- YOLOv10 (Ours) -->
<g transform="translate(337.472812 279.337812) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-75" d="M 2709 2863
L 2709 1128
Q 2709 631 2732 520
Q 2756 409 2807 365
Q 2859 322 2928 322
Q 3025 322 3147 375
L 3191 266
L 2334 -88
L 2194 -88
L 2194 519
Q 1825 119 1631 15
Q 1438 -88 1222 -88
Q 981 -88 804 51
Q 628 191 559 409
Q 491 628 491 1028
L 491 2306
Q 491 2509 447 2587
Q 403 2666 317 2708
Q 231 2750 6 2747
L 6 2863
L 1009 2863
L 1009 947
Q 1009 547 1148 422
Q 1288 297 1484 297
Q 1619 297 1789 381
Q 1959 466 2194 703
L 2194 2325
Q 2194 2569 2105 2655
Q 2016 2741 1734 2747
L 1734 2863
L 2709 2863
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-72" d="M 1038 2947
L 1038 2303
Q 1397 2947 1775 2947
Q 1947 2947 2059 2842
Q 2172 2738 2172 2600
Q 2172 2478 2090 2393
Q 2009 2309 1897 2309
Q 1788 2309 1652 2417
Q 1516 2525 1450 2525
Q 1394 2525 1328 2463
Q 1188 2334 1038 2041
L 1038 669
Q 1038 431 1097 309
Q 1138 225 1241 169
Q 1344 113 1538 113
L 1538 0
L 72 0
L 72 113
Q 291 113 397 181
Q 475 231 506 341
Q 522 394 522 644
L 522 1753
Q 522 2253 501 2348
Q 481 2444 426 2487
Q 372 2531 291 2531
Q 194 2531 72 2484
L 41 2597
L 906 2947
L 1038 2947
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-59"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="144.433594"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.517578"/>
<use xlink:href="#TimesNewRomanPSMT-76" x="277.734375"/>
<use xlink:href="#TimesNewRomanPSMT-31" x="327.734375"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="377.734375"/>
<use xlink:href="#TimesNewRomanPSMT-20" x="427.734375"/>
<use xlink:href="#TimesNewRomanPSMT-28" x="452.734375"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="486.035156"/>
<use xlink:href="#TimesNewRomanPSMT-75" x="558.251953"/>
<use xlink:href="#TimesNewRomanPSMT-72" x="608.251953"/>
<use xlink:href="#TimesNewRomanPSMT-73" x="641.552734"/>
<use xlink:href="#TimesNewRomanPSMT-29" x="680.46875"/>
</g>
</g>
</g>
</g>
</g>
<defs>
<clipPath id="p7d6da97f45">
<rect x="64.28" y="12.446069" width="385.72" height="282.486431"/>
</clipPath>
</defs>
</svg>
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="460.8pt" height="345.6pt" viewBox="0 0 460.8 345.6" xmlns="http://www.w3.org/2000/svg" version="1.1">
<metadata>
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<cc:Work>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:date>2024-05-23T18:13:26.684127</dc:date>
<dc:format>image/svg+xml</dc:format>
<dc:creator>
<cc:Agent>
<dc:title>Matplotlib v3.6.0, https://matplotlib.org/</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
</rdf:RDF>
</metadata>
<defs>
<style type="text/css">*{stroke-linejoin: round; stroke-linecap: butt}</style>
</defs>
<g id="figure_1">
<g id="patch_1">
<path d="M 0 345.6
L 460.8 345.6
L 460.8 0
L 0 0
z
" style="fill: #ffffff"/>
</g>
<g id="axes_1">
<g id="patch_2">
<path d="M 64.28 295
L 447.522888 295
L 447.522888 12.446069
L 64.28 12.446069
z
" style="fill: #ffffff"/>
</g>
<g id="matplotlib.axis_1">
<g id="xtick_1">
<g id="line2d_1">
<defs>
<path id="m00d865e5fb" d="M 0 0
L 0 3.5
" style="stroke: #000000; stroke-width: 0.8"/>
</defs>
<g>
<use xlink:href="#m00d865e5fb" x="73.326818" y="295" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_1">
<!-- 0 -->
<g transform="translate(69.326818 313.11) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-30" d="M 231 2094
Q 231 2819 450 3342
Q 669 3866 1031 4122
Q 1313 4325 1613 4325
Q 2100 4325 2488 3828
Q 2972 3213 2972 2159
Q 2972 1422 2759 906
Q 2547 391 2217 158
Q 1888 -75 1581 -75
Q 975 -75 572 641
Q 231 1244 231 2094
z
M 844 2016
Q 844 1141 1059 588
Q 1238 122 1591 122
Q 1759 122 1940 273
Q 2122 425 2216 781
Q 2359 1319 2359 2297
Q 2359 3022 2209 3506
Q 2097 3866 1919 4016
Q 1791 4119 1609 4119
Q 1397 4119 1231 3928
Q 1006 3669 925 3112
Q 844 2556 844 2016
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-30"/>
</g>
</g>
</g>
<g id="xtick_2">
<g id="line2d_2">
<g>
<use xlink:href="#m00d865e5fb" x="146.138234" y="295" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_2">
<!-- 20 -->
<g transform="translate(138.138234 313.11) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-32" d="M 2934 816
L 2638 0
L 138 0
L 138 116
Q 1241 1122 1691 1759
Q 2141 2397 2141 2925
Q 2141 3328 1894 3587
Q 1647 3847 1303 3847
Q 991 3847 742 3664
Q 494 3481 375 3128
L 259 3128
Q 338 3706 661 4015
Q 984 4325 1469 4325
Q 1984 4325 2329 3994
Q 2675 3663 2675 3213
Q 2675 2891 2525 2569
Q 2294 2063 1775 1497
Q 997 647 803 472
L 1909 472
Q 2247 472 2383 497
Q 2519 522 2628 598
Q 2738 675 2819 816
L 2934 816
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-32"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="50"/>
</g>
</g>
</g>
<g id="xtick_3">
<g id="line2d_3">
<g>
<use xlink:href="#m00d865e5fb" x="218.949651" y="295" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_3">
<!-- 40 -->
<g transform="translate(210.949651 313.11) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-34" d="M 2978 1563
L 2978 1119
L 2409 1119
L 2409 0
L 1894 0
L 1894 1119
L 100 1119
L 100 1519
L 2066 4325
L 2409 4325
L 2409 1563
L 2978 1563
z
M 1894 1563
L 1894 3666
L 406 1563
L 1894 1563
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-34"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="50"/>
</g>
</g>
</g>
<g id="xtick_4">
<g id="line2d_4">
<g>
<use xlink:href="#m00d865e5fb" x="291.761067" y="295" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_4">
<!-- 60 -->
<g transform="translate(283.761067 313.11) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-36" d="M 2869 4325
L 2869 4209
Q 2456 4169 2195 4045
Q 1934 3922 1679 3669
Q 1425 3416 1258 3105
Q 1091 2794 978 2366
Q 1428 2675 1881 2675
Q 2316 2675 2634 2325
Q 2953 1975 2953 1425
Q 2953 894 2631 456
Q 2244 -75 1606 -75
Q 1172 -75 869 213
Q 275 772 275 1663
Q 275 2231 503 2743
Q 731 3256 1154 3653
Q 1578 4050 1965 4187
Q 2353 4325 2688 4325
L 2869 4325
z
M 925 2138
Q 869 1716 869 1456
Q 869 1156 980 804
Q 1091 453 1309 247
Q 1469 100 1697 100
Q 1969 100 2183 356
Q 2397 613 2397 1088
Q 2397 1622 2184 2012
Q 1972 2403 1581 2403
Q 1463 2403 1327 2353
Q 1191 2303 925 2138
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-36"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="50"/>
</g>
</g>
</g>
<g id="xtick_5">
<g id="line2d_5">
<g>
<use xlink:href="#m00d865e5fb" x="364.572483" y="295" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_5">
<!-- 80 -->
<g transform="translate(356.572483 313.11) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-38" d="M 1228 2134
Q 725 2547 579 2797
Q 434 3047 434 3316
Q 434 3728 753 4026
Q 1072 4325 1600 4325
Q 2113 4325 2425 4047
Q 2738 3769 2738 3413
Q 2738 3175 2569 2928
Q 2400 2681 1866 2347
Q 2416 1922 2594 1678
Q 2831 1359 2831 1006
Q 2831 559 2490 242
Q 2150 -75 1597 -75
Q 994 -75 656 303
Q 388 606 388 966
Q 388 1247 577 1523
Q 766 1800 1228 2134
z
M 1719 2469
Q 2094 2806 2194 3001
Q 2294 3197 2294 3444
Q 2294 3772 2109 3958
Q 1925 4144 1606 4144
Q 1288 4144 1088 3959
Q 888 3775 888 3528
Q 888 3366 970 3203
Q 1053 3041 1206 2894
L 1719 2469
z
M 1375 2016
Q 1116 1797 991 1539
Q 866 1281 866 981
Q 866 578 1086 336
Q 1306 94 1647 94
Q 1984 94 2187 284
Q 2391 475 2391 747
Q 2391 972 2272 1150
Q 2050 1481 1375 2016
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-38"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="50"/>
</g>
</g>
</g>
<g id="xtick_6">
<g id="line2d_6">
<g>
<use xlink:href="#m00d865e5fb" x="437.383899" y="295" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_6">
<!-- 100 -->
<g transform="translate(425.383899 313.11) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-31" d="M 750 3822
L 1781 4325
L 1884 4325
L 1884 747
Q 1884 391 1914 303
Q 1944 216 2037 169
Q 2131 122 2419 116
L 2419 0
L 825 0
L 825 116
Q 1125 122 1212 167
Q 1300 213 1334 289
Q 1369 366 1369 747
L 1369 3034
Q 1369 3497 1338 3628
Q 1316 3728 1258 3775
Q 1200 3822 1119 3822
Q 1003 3822 797 3725
L 750 3822
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-31"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="100"/>
</g>
</g>
</g>
<g id="text_7">
<!-- Number of Parameters (M) -->
<g transform="translate(169.041444 331.6425) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-4e" d="M -84 4238
L 1066 4238
L 3656 1059
L 3656 3503
Q 3656 3894 3569 3991
Q 3453 4122 3203 4122
L 3056 4122
L 3056 4238
L 4531 4238
L 4531 4122
L 4381 4122
Q 4113 4122 4000 3959
Q 3931 3859 3931 3503
L 3931 -69
L 3819 -69
L 1025 3344
L 1025 734
Q 1025 344 1109 247
Q 1228 116 1475 116
L 1625 116
L 1625 0
L 150 0
L 150 116
L 297 116
Q 569 116 681 278
Q 750 378 750 734
L 750 3681
Q 566 3897 470 3965
Q 375 4034 191 4094
Q 100 4122 -84 4122
L -84 4238
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-75" d="M 2709 2863
L 2709 1128
Q 2709 631 2732 520
Q 2756 409 2807 365
Q 2859 322 2928 322
Q 3025 322 3147 375
L 3191 266
L 2334 -88
L 2194 -88
L 2194 519
Q 1825 119 1631 15
Q 1438 -88 1222 -88
Q 981 -88 804 51
Q 628 191 559 409
Q 491 628 491 1028
L 491 2306
Q 491 2509 447 2587
Q 403 2666 317 2708
Q 231 2750 6 2747
L 6 2863
L 1009 2863
L 1009 947
Q 1009 547 1148 422
Q 1288 297 1484 297
Q 1619 297 1789 381
Q 1959 466 2194 703
L 2194 2325
Q 2194 2569 2105 2655
Q 2016 2741 1734 2747
L 1734 2863
L 2709 2863
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-6d" d="M 1050 2338
Q 1363 2650 1419 2697
Q 1559 2816 1721 2881
Q 1884 2947 2044 2947
Q 2313 2947 2506 2790
Q 2700 2634 2766 2338
Q 3088 2713 3309 2830
Q 3531 2947 3766 2947
Q 3994 2947 4170 2830
Q 4347 2713 4450 2447
Q 4519 2266 4519 1878
L 4519 647
Q 4519 378 4559 278
Q 4591 209 4675 161
Q 4759 113 4950 113
L 4950 0
L 3538 0
L 3538 113
L 3597 113
Q 3781 113 3884 184
Q 3956 234 3988 344
Q 4000 397 4000 647
L 4000 1878
Q 4000 2228 3916 2372
Q 3794 2572 3525 2572
Q 3359 2572 3192 2489
Q 3025 2406 2788 2181
L 2781 2147
L 2788 2013
L 2788 647
Q 2788 353 2820 281
Q 2853 209 2943 161
Q 3034 113 3253 113
L 3253 0
L 1806 0
L 1806 113
Q 2044 113 2133 169
Q 2222 225 2256 338
Q 2272 391 2272 647
L 2272 1878
Q 2272 2228 2169 2381
Q 2031 2581 1784 2581
Q 1616 2581 1450 2491
Q 1191 2353 1050 2181
L 1050 647
Q 1050 366 1089 281
Q 1128 197 1204 155
Q 1281 113 1516 113
L 1516 0
L 100 0
L 100 113
Q 297 113 375 155
Q 453 197 493 289
Q 534 381 534 647
L 534 1741
Q 534 2213 506 2350
Q 484 2453 437 2492
Q 391 2531 309 2531
Q 222 2531 100 2484
L 53 2597
L 916 2947
L 1050 2947
L 1050 2338
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-62" d="M 984 2369
Q 1400 2947 1881 2947
Q 2322 2947 2650 2570
Q 2978 2194 2978 1541
Q 2978 778 2472 313
Q 2038 -88 1503 -88
Q 1253 -88 995 3
Q 738 94 469 275
L 469 3241
Q 469 3728 445 3840
Q 422 3953 372 3993
Q 322 4034 247 4034
Q 159 4034 28 3984
L -16 4094
L 844 4444
L 984 4444
L 984 2369
z
M 984 2169
L 984 456
Q 1144 300 1314 220
Q 1484 141 1663 141
Q 1947 141 2192 453
Q 2438 766 2438 1363
Q 2438 1913 2192 2208
Q 1947 2503 1634 2503
Q 1469 2503 1303 2419
Q 1178 2356 984 2169
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-65" d="M 681 1784
Q 678 1147 991 784
Q 1303 422 1725 422
Q 2006 422 2214 576
Q 2422 731 2563 1106
L 2659 1044
Q 2594 616 2278 264
Q 1963 -88 1488 -88
Q 972 -88 605 314
Q 238 716 238 1394
Q 238 2128 614 2539
Q 991 2950 1559 2950
Q 2041 2950 2350 2633
Q 2659 2316 2659 1784
L 681 1784
z
M 681 1966
L 2006 1966
Q 1991 2241 1941 2353
Q 1863 2528 1708 2628
Q 1553 2728 1384 2728
Q 1125 2728 920 2526
Q 716 2325 681 1966
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-72" d="M 1038 2947
L 1038 2303
Q 1397 2947 1775 2947
Q 1947 2947 2059 2842
Q 2172 2738 2172 2600
Q 2172 2478 2090 2393
Q 2009 2309 1897 2309
Q 1788 2309 1652 2417
Q 1516 2525 1450 2525
Q 1394 2525 1328 2463
Q 1188 2334 1038 2041
L 1038 669
Q 1038 431 1097 309
Q 1138 225 1241 169
Q 1344 113 1538 113
L 1538 0
L 72 0
L 72 113
Q 291 113 397 181
Q 475 231 506 341
Q 522 394 522 644
L 522 1753
Q 522 2253 501 2348
Q 481 2444 426 2487
Q 372 2531 291 2531
Q 194 2531 72 2484
L 41 2597
L 906 2947
L 1038 2947
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-20" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-6f" d="M 1600 2947
Q 2250 2947 2644 2453
Q 2978 2031 2978 1484
Q 2978 1100 2793 706
Q 2609 313 2286 112
Q 1963 -88 1566 -88
Q 919 -88 538 428
Q 216 863 216 1403
Q 216 1797 411 2186
Q 606 2575 925 2761
Q 1244 2947 1600 2947
z
M 1503 2744
Q 1338 2744 1170 2645
Q 1003 2547 900 2300
Q 797 2053 797 1666
Q 797 1041 1045 587
Q 1294 134 1700 134
Q 2003 134 2200 384
Q 2397 634 2397 1244
Q 2397 2006 2069 2444
Q 1847 2744 1503 2744
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-66" d="M 1319 2638
L 1319 756
Q 1319 356 1406 250
Q 1522 113 1716 113
L 1975 113
L 1975 0
L 266 0
L 266 113
L 394 113
Q 519 113 622 175
Q 725 238 764 344
Q 803 450 803 756
L 803 2638
L 247 2638
L 247 2863
L 803 2863
L 803 3050
Q 803 3478 940 3775
Q 1078 4072 1361 4255
Q 1644 4438 1997 4438
Q 2325 4438 2600 4225
Q 2781 4084 2781 3909
Q 2781 3816 2700 3733
Q 2619 3650 2525 3650
Q 2453 3650 2373 3701
Q 2294 3753 2178 3923
Q 2063 4094 1966 4153
Q 1869 4213 1750 4213
Q 1606 4213 1506 4136
Q 1406 4059 1362 3898
Q 1319 3738 1319 3069
L 1319 2863
L 2056 2863
L 2056 2638
L 1319 2638
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-50" d="M 1313 1984
L 1313 750
Q 1313 350 1400 253
Q 1519 116 1759 116
L 1922 116
L 1922 0
L 106 0
L 106 116
L 266 116
Q 534 116 650 291
Q 713 388 713 750
L 713 3488
Q 713 3888 628 3984
Q 506 4122 266 4122
L 106 4122
L 106 4238
L 1659 4238
Q 2228 4238 2556 4120
Q 2884 4003 3109 3725
Q 3334 3447 3334 3066
Q 3334 2547 2992 2222
Q 2650 1897 2025 1897
Q 1872 1897 1694 1919
Q 1516 1941 1313 1984
z
M 1313 2163
Q 1478 2131 1606 2115
Q 1734 2100 1825 2100
Q 2150 2100 2386 2351
Q 2622 2603 2622 3003
Q 2622 3278 2509 3514
Q 2397 3750 2190 3867
Q 1984 3984 1722 3984
Q 1563 3984 1313 3925
L 1313 2163
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-61" d="M 1822 413
Q 1381 72 1269 19
Q 1100 -59 909 -59
Q 613 -59 420 144
Q 228 347 228 678
Q 228 888 322 1041
Q 450 1253 767 1440
Q 1084 1628 1822 1897
L 1822 2009
Q 1822 2438 1686 2597
Q 1550 2756 1291 2756
Q 1094 2756 978 2650
Q 859 2544 859 2406
L 866 2225
Q 866 2081 792 2003
Q 719 1925 600 1925
Q 484 1925 411 2006
Q 338 2088 338 2228
Q 338 2497 613 2722
Q 888 2947 1384 2947
Q 1766 2947 2009 2819
Q 2194 2722 2281 2516
Q 2338 2381 2338 1966
L 2338 994
Q 2338 584 2353 492
Q 2369 400 2405 369
Q 2441 338 2488 338
Q 2538 338 2575 359
Q 2641 400 2828 588
L 2828 413
Q 2478 -56 2159 -56
Q 2006 -56 1915 50
Q 1825 156 1822 413
z
M 1822 616
L 1822 1706
Q 1350 1519 1213 1441
Q 966 1303 859 1153
Q 753 1003 753 825
Q 753 600 887 451
Q 1022 303 1197 303
Q 1434 303 1822 616
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-74" d="M 1031 3803
L 1031 2863
L 1700 2863
L 1700 2644
L 1031 2644
L 1031 788
Q 1031 509 1111 412
Q 1191 316 1316 316
Q 1419 316 1516 380
Q 1613 444 1666 569
L 1788 569
Q 1678 263 1478 108
Q 1278 -47 1066 -47
Q 922 -47 784 33
Q 647 113 581 261
Q 516 409 516 719
L 516 2644
L 63 2644
L 63 2747
Q 234 2816 414 2980
Q 594 3144 734 3369
Q 806 3488 934 3803
L 1031 3803
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-73" d="M 2050 2947
L 2050 1972
L 1947 1972
Q 1828 2431 1642 2597
Q 1456 2763 1169 2763
Q 950 2763 815 2647
Q 681 2531 681 2391
Q 681 2216 781 2091
Q 878 1963 1175 1819
L 1631 1597
Q 2266 1288 2266 781
Q 2266 391 1970 151
Q 1675 -88 1309 -88
Q 1047 -88 709 6
Q 606 38 541 38
Q 469 38 428 -44
L 325 -44
L 325 978
L 428 978
Q 516 541 762 319
Q 1009 97 1316 97
Q 1531 97 1667 223
Q 1803 350 1803 528
Q 1803 744 1651 891
Q 1500 1038 1047 1263
Q 594 1488 453 1669
Q 313 1847 313 2119
Q 313 2472 555 2709
Q 797 2947 1181 2947
Q 1350 2947 1591 2875
Q 1750 2828 1803 2828
Q 1853 2828 1881 2850
Q 1909 2872 1947 2947
L 2050 2947
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-28" d="M 1988 -1253
L 1988 -1369
Q 1516 -1131 1200 -813
Q 750 -359 506 256
Q 263 872 263 1534
Q 263 2503 741 3301
Q 1219 4100 1988 4444
L 1988 4313
Q 1603 4100 1356 3731
Q 1109 3363 987 2797
Q 866 2231 866 1616
Q 866 947 969 400
Q 1050 -31 1165 -292
Q 1281 -553 1476 -793
Q 1672 -1034 1988 -1253
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-4d" d="M 2619 0
L 981 3566
L 981 734
Q 981 344 1066 247
Q 1181 116 1431 116
L 1581 116
L 1581 0
L 106 0
L 106 116
L 256 116
Q 525 116 638 278
Q 706 378 706 734
L 706 3503
Q 706 3784 644 3909
Q 600 4000 483 4061
Q 366 4122 106 4122
L 106 4238
L 1306 4238
L 2844 922
L 4356 4238
L 5556 4238
L 5556 4122
L 5409 4122
Q 5138 4122 5025 3959
Q 4956 3859 4956 3503
L 4956 734
Q 4956 344 5044 247
Q 5159 116 5409 116
L 5556 116
L 5556 0
L 3756 0
L 3756 116
L 3906 116
Q 4178 116 4288 278
Q 4356 378 4356 734
L 4356 3566
L 2722 0
L 2619 0
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-29" d="M 144 4313
L 144 4444
Q 619 4209 934 3891
Q 1381 3434 1625 2820
Q 1869 2206 1869 1541
Q 1869 572 1392 -226
Q 916 -1025 144 -1369
L 144 -1253
Q 528 -1038 776 -670
Q 1025 -303 1145 264
Q 1266 831 1266 1447
Q 1266 2113 1163 2663
Q 1084 3094 967 3353
Q 850 3613 656 3853
Q 463 4094 144 4313
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-4e"/>
<use xlink:href="#TimesNewRomanPSMT-75" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-6d" x="122.216797"/>
<use xlink:href="#TimesNewRomanPSMT-62" x="200"/>
<use xlink:href="#TimesNewRomanPSMT-65" x="250"/>
<use xlink:href="#TimesNewRomanPSMT-72" x="294.384766"/>
<use xlink:href="#TimesNewRomanPSMT-20" x="327.685547"/>
<use xlink:href="#TimesNewRomanPSMT-6f" x="352.685547"/>
<use xlink:href="#TimesNewRomanPSMT-66" x="402.685547"/>
<use xlink:href="#TimesNewRomanPSMT-20" x="435.986328"/>
<use xlink:href="#TimesNewRomanPSMT-50" x="460.986328"/>
<use xlink:href="#TimesNewRomanPSMT-61" x="516.601562"/>
<use xlink:href="#TimesNewRomanPSMT-72" x="560.986328"/>
<use xlink:href="#TimesNewRomanPSMT-61" x="594.287109"/>
<use xlink:href="#TimesNewRomanPSMT-6d" x="638.671875"/>
<use xlink:href="#TimesNewRomanPSMT-65" x="716.455078"/>
<use xlink:href="#TimesNewRomanPSMT-74" x="760.839844"/>
<use xlink:href="#TimesNewRomanPSMT-65" x="788.623047"/>
<use xlink:href="#TimesNewRomanPSMT-72" x="833.007812"/>
<use xlink:href="#TimesNewRomanPSMT-73" x="866.308594"/>
<use xlink:href="#TimesNewRomanPSMT-20" x="905.224609"/>
<use xlink:href="#TimesNewRomanPSMT-28" x="930.224609"/>
<use xlink:href="#TimesNewRomanPSMT-4d" x="963.525391"/>
<use xlink:href="#TimesNewRomanPSMT-29" x="1052.441406"/>
</g>
</g>
</g>
<g id="matplotlib.axis_2">
<g id="ytick_1">
<g id="line2d_7">
<defs>
<path id="m106efacff5" d="M 0 0
L -3.5 0
" style="stroke: #000000; stroke-width: 0.8"/>
</defs>
<g>
<use xlink:href="#m106efacff5" x="64.28" y="274.775398" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_8">
<!-- 37.5 -->
<g transform="translate(29.28 280.330398) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-33" d="M 325 3431
Q 506 3859 782 4092
Q 1059 4325 1472 4325
Q 1981 4325 2253 3994
Q 2459 3747 2459 3466
Q 2459 3003 1878 2509
Q 2269 2356 2469 2072
Q 2669 1788 2669 1403
Q 2669 853 2319 450
Q 1863 -75 997 -75
Q 569 -75 414 31
Q 259 138 259 259
Q 259 350 332 419
Q 406 488 509 488
Q 588 488 669 463
Q 722 447 909 348
Q 1097 250 1169 231
Q 1284 197 1416 197
Q 1734 197 1970 444
Q 2206 691 2206 1028
Q 2206 1275 2097 1509
Q 2016 1684 1919 1775
Q 1784 1900 1550 2001
Q 1316 2103 1072 2103
L 972 2103
L 972 2197
Q 1219 2228 1467 2375
Q 1716 2522 1828 2728
Q 1941 2934 1941 3181
Q 1941 3503 1739 3701
Q 1538 3900 1238 3900
Q 753 3900 428 3381
L 325 3431
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-37" d="M 644 4238
L 2916 4238
L 2916 4119
L 1503 -88
L 1153 -88
L 2419 3728
L 1253 3728
Q 900 3728 750 3644
Q 488 3500 328 3200
L 238 3234
L 644 4238
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-2e" d="M 800 606
Q 947 606 1047 504
Q 1147 403 1147 259
Q 1147 116 1045 14
Q 944 -88 800 -88
Q 656 -88 554 14
Q 453 116 453 259
Q 453 406 554 506
Q 656 606 800 606
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-35" d="M 2778 4238
L 2534 3706
L 1259 3706
L 981 3138
Q 1809 3016 2294 2522
Q 2709 2097 2709 1522
Q 2709 1188 2573 903
Q 2438 619 2231 419
Q 2025 219 1772 97
Q 1413 -75 1034 -75
Q 653 -75 479 54
Q 306 184 306 341
Q 306 428 378 495
Q 450 563 559 563
Q 641 563 702 538
Q 763 513 909 409
Q 1144 247 1384 247
Q 1750 247 2026 523
Q 2303 800 2303 1197
Q 2303 1581 2056 1914
Q 1809 2247 1375 2428
Q 1034 2569 447 2591
L 1259 4238
L 2778 4238
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-33"/>
<use xlink:href="#TimesNewRomanPSMT-37" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="125"/>
</g>
</g>
</g>
<g id="ytick_2">
<g id="line2d_8">
<g>
<use xlink:href="#m106efacff5" x="64.28" y="237.869189" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_9">
<!-- 40.0 -->
<g transform="translate(29.28 243.424189) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-34"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="125"/>
</g>
</g>
</g>
<g id="ytick_3">
<g id="line2d_9">
<g>
<use xlink:href="#m106efacff5" x="64.28" y="200.962981" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_10">
<!-- 42.5 -->
<g transform="translate(29.28 206.517981) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-34"/>
<use xlink:href="#TimesNewRomanPSMT-32" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="125"/>
</g>
</g>
</g>
<g id="ytick_4">
<g id="line2d_10">
<g>
<use xlink:href="#m106efacff5" x="64.28" y="164.056773" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_11">
<!-- 45.0 -->
<g transform="translate(29.28 169.611773) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-34"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="125"/>
</g>
</g>
</g>
<g id="ytick_5">
<g id="line2d_11">
<g>
<use xlink:href="#m106efacff5" x="64.28" y="127.150564" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_12">
<!-- 47.5 -->
<g transform="translate(29.28 132.705564) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-34"/>
<use xlink:href="#TimesNewRomanPSMT-37" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="125"/>
</g>
</g>
</g>
<g id="ytick_6">
<g id="line2d_12">
<g>
<use xlink:href="#m106efacff5" x="64.28" y="90.244356" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_13">
<!-- 50.0 -->
<g transform="translate(29.28 95.799356) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-35"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="125"/>
</g>
</g>
</g>
<g id="ytick_7">
<g id="line2d_13">
<g>
<use xlink:href="#m106efacff5" x="64.28" y="53.338148" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_14">
<!-- 52.5 -->
<g transform="translate(29.28 58.893148) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-35"/>
<use xlink:href="#TimesNewRomanPSMT-32" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="125"/>
</g>
</g>
</g>
<g id="ytick_8">
<g id="line2d_14">
<g>
<use xlink:href="#m106efacff5" x="64.28" y="16.431939" style="stroke: #000000; stroke-width: 0.8"/>
</g>
</g>
<g id="text_15">
<!-- 55.0 -->
<g transform="translate(29.28 21.986939) scale(0.16 -0.16)">
<use xlink:href="#TimesNewRomanPSMT-35"/>
<use xlink:href="#TimesNewRomanPSMT-35" x="50"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="100"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="125"/>
</g>
</g>
</g>
<g id="text_16">
<!-- COCO AP (%) -->
<g transform="translate(21.8575 201.428034) rotate(-90) scale(0.16 -0.16)">
<defs>
<path id="TimesNewRomanPSMT-43" d="M 3853 4334
L 3950 2894
L 3853 2894
Q 3659 3541 3300 3825
Q 2941 4109 2438 4109
Q 2016 4109 1675 3895
Q 1334 3681 1139 3212
Q 944 2744 944 2047
Q 944 1472 1128 1050
Q 1313 628 1683 403
Q 2053 178 2528 178
Q 2941 178 3256 354
Q 3572 531 3950 1056
L 4047 994
Q 3728 428 3303 165
Q 2878 -97 2294 -97
Q 1241 -97 663 684
Q 231 1266 231 2053
Q 231 2688 515 3219
Q 800 3750 1298 4042
Q 1797 4334 2388 4334
Q 2847 4334 3294 4109
Q 3425 4041 3481 4041
Q 3566 4041 3628 4100
Q 3709 4184 3744 4334
L 3853 4334
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-4f" d="M 2341 4334
Q 3166 4334 3770 3707
Q 4375 3081 4375 2144
Q 4375 1178 3765 540
Q 3156 -97 2291 -97
Q 1416 -97 820 525
Q 225 1147 225 2134
Q 225 3144 913 3781
Q 1509 4334 2341 4334
z
M 2281 4106
Q 1713 4106 1369 3684
Q 941 3159 941 2147
Q 941 1109 1384 550
Q 1725 125 2284 125
Q 2881 125 3270 590
Q 3659 1056 3659 2059
Q 3659 3147 3231 3681
Q 2888 4106 2281 4106
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-41" d="M 2928 1419
L 1288 1419
L 1000 750
Q 894 503 894 381
Q 894 284 986 211
Q 1078 138 1384 116
L 1384 0
L 50 0
L 50 116
Q 316 163 394 238
Q 553 388 747 847
L 2238 4334
L 2347 4334
L 3822 809
Q 4000 384 4145 257
Q 4291 131 4550 116
L 4550 0
L 2878 0
L 2878 116
Q 3131 128 3220 200
Q 3309 272 3309 375
Q 3309 513 3184 809
L 2928 1419
z
M 2841 1650
L 2122 3363
L 1384 1650
L 2841 1650
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-25" d="M 4350 4334
L 1263 -175
L 984 -175
L 4072 4334
L 4350 4334
z
M 1138 4334
Q 1559 4334 1792 3984
Q 2025 3634 2025 3181
Q 2025 2638 1762 2341
Q 1500 2044 1131 2044
Q 884 2044 678 2180
Q 472 2316 348 2584
Q 225 2853 225 3181
Q 225 3509 350 3786
Q 475 4063 692 4198
Q 909 4334 1138 4334
z
M 1128 4159
Q 969 4159 845 3971
Q 722 3784 722 3184
Q 722 2750 791 2522
Q 844 2350 956 2256
Q 1022 2200 1119 2200
Q 1269 2200 1375 2363
Q 1531 2603 1531 3166
Q 1531 3759 1378 4000
Q 1278 4159 1128 4159
z
M 4206 2103
Q 4428 2103 4648 1962
Q 4869 1822 4989 1553
Q 5109 1284 5109 963
Q 5109 409 4843 117
Q 4578 -175 4216 -175
Q 3988 -175 3773 -34
Q 3559 106 3436 367
Q 3313 628 3313 963
Q 3313 1291 3436 1562
Q 3559 1834 3773 1968
Q 3988 2103 4206 2103
z
M 4209 1938
Q 4059 1938 3950 1769
Q 3809 1550 3809 941
Q 3809 381 3953 159
Q 4059 0 4209 0
Q 4353 0 4466 172
Q 4616 400 4616 956
Q 4616 1544 4466 1778
Q 4363 1938 4209 1938
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-43"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="66.699219"/>
<use xlink:href="#TimesNewRomanPSMT-43" x="138.916016"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.615234"/>
<use xlink:href="#TimesNewRomanPSMT-20" x="277.832031"/>
<use xlink:href="#TimesNewRomanPSMT-41" x="297.332031"/>
<use xlink:href="#TimesNewRomanPSMT-50" x="369.548828"/>
<use xlink:href="#TimesNewRomanPSMT-20" x="421.414062"/>
<use xlink:href="#TimesNewRomanPSMT-28" x="446.414062"/>
<use xlink:href="#TimesNewRomanPSMT-25" x="479.714844"/>
<use xlink:href="#TimesNewRomanPSMT-29" x="563.015625"/>
</g>
</g>
</g>
<g id="line2d_15">
<path d="M 90.437501 282.156639
L 140.677378 174.390511
L 200.382739 103.530591
L 290.304838 63.671886
" clip-path="url(#pec2f9990ec)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #1f77b4; stroke-width: 1.5"/>
<defs>
<path id="m25ac481e9c" d="M 0 -2
L -0.449028 -0.618034
L -1.902113 -0.618034
L -0.726543 0.236068
L -1.175571 1.618034
L -0 0.763932
L 1.175571 1.618034
L 0.726543 0.236068
L 1.902113 -0.618034
L 0.449028 -0.618034
z
" style="stroke: #1f77b4; stroke-linejoin: bevel"/>
</defs>
<g clip-path="url(#pec2f9990ec)">
<use xlink:href="#m25ac481e9c" x="90.437501" y="282.156639" style="fill: #1f77b4; stroke: #1f77b4; stroke-linejoin: bevel"/>
<use xlink:href="#m25ac481e9c" x="140.677378" y="174.390511" style="fill: #1f77b4; stroke: #1f77b4; stroke-linejoin: bevel"/>
<use xlink:href="#m25ac481e9c" x="200.382739" y="103.530591" style="fill: #1f77b4; stroke: #1f77b4; stroke-linejoin: bevel"/>
<use xlink:href="#m25ac481e9c" x="290.304838" y="63.671886" style="fill: #1f77b4; stroke: #1f77b4; stroke-linejoin: bevel"/>
</g>
</g>
<g id="line2d_16">
<path d="M 95.898357 276.251646
L 207.663881 72.529376
L 332.899517 47.433154
" clip-path="url(#pec2f9990ec)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #ff7f0e; stroke-width: 1.5"/>
<defs>
<path id="m0ebbb9ee98" d="M -2 0
L 2 0
M 0 2
L 0 -2
" style="stroke: #ff7f0e"/>
</defs>
<g clip-path="url(#pec2f9990ec)">
<use xlink:href="#m0ebbb9ee98" x="95.898357" y="276.251646" style="fill: #ff7f0e; stroke: #ff7f0e"/>
<use xlink:href="#m0ebbb9ee98" x="207.663881" y="72.529376" style="fill: #ff7f0e; stroke: #ff7f0e"/>
<use xlink:href="#m0ebbb9ee98" x="332.899517" y="47.433154" style="fill: #ff7f0e; stroke: #ff7f0e"/>
</g>
</g>
<g id="line2d_17">
<path d="M 84.976645 277.727894
L 114.101211 165.533021
L 167.617602 81.386866
L 232.419762 47.433154
L 321.613747 32.670671
" clip-path="url(#pec2f9990ec)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #2ca02c; stroke-width: 1.5"/>
<defs>
<path id="m1addbb2f50" d="M -2 2
L 2 -2
M -2 -2
L 2 2
" style="stroke: #2ca02c"/>
</defs>
<g clip-path="url(#pec2f9990ec)">
<use xlink:href="#m1addbb2f50" x="84.976645" y="277.727894" style="fill: #2ca02c; stroke: #2ca02c"/>
<use xlink:href="#m1addbb2f50" x="114.101211" y="165.533021" style="fill: #2ca02c; stroke: #2ca02c"/>
<use xlink:href="#m1addbb2f50" x="167.617602" y="81.386866" style="fill: #2ca02c; stroke: #2ca02c"/>
<use xlink:href="#m1addbb2f50" x="232.419762" y="47.433154" style="fill: #2ca02c; stroke: #2ca02c"/>
<use xlink:href="#m1addbb2f50" x="321.613747" y="32.670671" style="fill: #2ca02c; stroke: #2ca02c"/>
</g>
</g>
<g id="line2d_18">
<path d="M 99.174871 138.960551
L 146.138234 74.005624
L 165.43326 53.338148
" clip-path="url(#pec2f9990ec)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #d62728; stroke-width: 1.5"/>
<defs>
<path id="m20ef095d3f" d="M -0 2
L 2 -2
L -2 -2
z
" style="stroke: #d62728; stroke-linejoin: miter"/>
</defs>
<g clip-path="url(#pec2f9990ec)">
<use xlink:href="#m20ef095d3f" x="99.174871" y="138.960551" style="fill: #d62728; stroke: #d62728; stroke-linejoin: miter"/>
<use xlink:href="#m20ef095d3f" x="146.138234" y="74.005624" style="fill: #d62728; stroke: #d62728; stroke-linejoin: miter"/>
<use xlink:href="#m20ef095d3f" x="165.43326" y="53.338148" style="fill: #d62728; stroke: #d62728; stroke-linejoin: miter"/>
</g>
</g>
<g id="line2d_19">
<path d="M 158.516175 106.483088
L 263.364614 69.576879
L 430.102757 57.766893
" clip-path="url(#pec2f9990ec)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #9467bd; stroke-width: 1.5"/>
<defs>
<path id="m188839fe94" d="M 0 -2
L -2 2
L 2 2
z
" style="stroke: #9467bd; stroke-linejoin: miter"/>
</defs>
<g clip-path="url(#pec2f9990ec)">
<use xlink:href="#m188839fe94" x="158.516175" y="106.483088" style="fill: #9467bd; stroke: #9467bd; stroke-linejoin: miter"/>
<use xlink:href="#m188839fe94" x="263.364614" y="69.576879" style="fill: #9467bd; stroke: #9467bd; stroke-linejoin: miter"/>
<use xlink:href="#m188839fe94" x="430.102757" y="57.766893" style="fill: #9467bd; stroke: #9467bd; stroke-linejoin: miter"/>
</g>
</g>
<g id="line2d_20">
<path d="M 90.801558 221.630458
L 106.05555 169.961766
L 163.248917 99.101846
L 263.728671 68.100631
L 418.816988 48.909403
" clip-path="url(#pec2f9990ec)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #8c564b; stroke-width: 1.5"/>
<defs>
<path id="m444fa26bd7" d="M -2 -0
L 2 2
L 2 -2
z
" style="stroke: #8c564b; stroke-linejoin: miter"/>
</defs>
<g clip-path="url(#pec2f9990ec)">
<use xlink:href="#m444fa26bd7" x="90.801558" y="221.630458" style="fill: #8c564b; stroke: #8c564b; stroke-linejoin: miter"/>
<use xlink:href="#m444fa26bd7" x="106.05555" y="169.961766" style="fill: #8c564b; stroke: #8c564b; stroke-linejoin: miter"/>
<use xlink:href="#m444fa26bd7" x="163.248917" y="99.101846" style="fill: #8c564b; stroke: #8c564b; stroke-linejoin: miter"/>
<use xlink:href="#m444fa26bd7" x="263.728671" y="68.100631" style="fill: #8c564b; stroke: #8c564b; stroke-linejoin: miter"/>
<use xlink:href="#m444fa26bd7" x="418.816988" y="48.909403" style="fill: #8c564b; stroke: #8c564b; stroke-linejoin: miter"/>
</g>
</g>
<g id="line2d_21">
<path d="M 89.709387 187.676746
L 102.815442 146.341793
L 154.14749 75.481873
" clip-path="url(#pec2f9990ec)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #e377c2; stroke-width: 1.5"/>
<defs>
<path id="ma742850c5b" d="M 2 0
L -2 -2
L -2 2
z
" style="stroke: #e377c2; stroke-linejoin: miter"/>
</defs>
<g clip-path="url(#pec2f9990ec)">
<use xlink:href="#ma742850c5b" x="89.709387" y="187.676746" style="fill: #e377c2; stroke: #e377c2; stroke-linejoin: miter"/>
<use xlink:href="#ma742850c5b" x="102.815442" y="146.341793" style="fill: #e377c2; stroke: #e377c2; stroke-linejoin: miter"/>
<use xlink:href="#ma742850c5b" x="154.14749" y="75.481873" style="fill: #e377c2; stroke: #e377c2; stroke-linejoin: miter"/>
</g>
</g>
<g id="line2d_22">
<path d="M 93.714015 243.774183
L 151.599091 158.151779
L 223.682393 93.196853
L 346.733686 63.671886
" clip-path="url(#pec2f9990ec)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #7f7f7f; stroke-width: 1.5"/>
<defs>
<path id="m7f8f30e89b" d="M 0 -2
L -1.902113 -0.618034
L -1.175571 1.618034
L 1.175571 1.618034
L 1.902113 -0.618034
z
" style="stroke: #7f7f7f; stroke-linejoin: miter"/>
</defs>
<g clip-path="url(#pec2f9990ec)">
<use xlink:href="#m7f8f30e89b" x="93.714015" y="243.774183" style="fill: #7f7f7f; stroke: #7f7f7f; stroke-linejoin: miter"/>
<use xlink:href="#m7f8f30e89b" x="151.599091" y="158.151779" style="fill: #7f7f7f; stroke: #7f7f7f; stroke-linejoin: miter"/>
<use xlink:href="#m7f8f30e89b" x="223.682393" y="93.196853" style="fill: #7f7f7f; stroke: #7f7f7f; stroke-linejoin: miter"/>
<use xlink:href="#m7f8f30e89b" x="346.733686" y="63.671886" style="fill: #7f7f7f; stroke: #7f7f7f; stroke-linejoin: miter"/>
</g>
</g>
<g id="line2d_23">
<path d="M 146.138234 141.913048
L 186.184513 106.483088
L 204.387367 71.053128
L 226.230792 44.480658
L 350.010199 26.765678
" clip-path="url(#pec2f9990ec)" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #bcbd22; stroke-width: 1.5"/>
<defs>
<path id="mceb5dd67df" d="M 0 -2
L -1.732051 -1
L -1.732051 1
L -0 2
L 1.732051 1
L 1.732051 -1
z
" style="stroke: #bcbd22; stroke-linejoin: miter"/>
</defs>
<g clip-path="url(#pec2f9990ec)">
<use xlink:href="#mceb5dd67df" x="146.138234" y="141.913048" style="fill: #bcbd22; stroke: #bcbd22; stroke-linejoin: miter"/>
<use xlink:href="#mceb5dd67df" x="186.184513" y="106.483088" style="fill: #bcbd22; stroke: #bcbd22; stroke-linejoin: miter"/>
<use xlink:href="#mceb5dd67df" x="204.387367" y="71.053128" style="fill: #bcbd22; stroke: #bcbd22; stroke-linejoin: miter"/>
<use xlink:href="#mceb5dd67df" x="226.230792" y="44.480658" style="fill: #bcbd22; stroke: #bcbd22; stroke-linejoin: miter"/>
<use xlink:href="#mceb5dd67df" x="350.010199" y="26.765678" style="fill: #bcbd22; stroke: #bcbd22; stroke-linejoin: miter"/>
</g>
</g>
<g id="line2d_24">
<path d="M 81.700131 260.012914
L 99.538928 144.865544
L 129.391609 74.005624
L 142.861721 53.338148
L 162.156746 43.004409
L 180.723657 25.289429
" clip-path="url(#pec2f9990ec)" style="fill: none; stroke: #ff0000; stroke-width: 3; stroke-linecap: square"/>
<defs>
<path id="m3148e191ee" d="M 0 3
C 0.795609 3 1.55874 2.683901 2.12132 2.12132
C 2.683901 1.55874 3 0.795609 3 0
C 3 -0.795609 2.683901 -1.55874 2.12132 -2.12132
C 1.55874 -2.683901 0.795609 -3 0 -3
C -0.795609 -3 -1.55874 -2.683901 -2.12132 -2.12132
C -2.683901 -1.55874 -3 -0.795609 -3 0
C -3 0.795609 -2.683901 1.55874 -2.12132 2.12132
C -1.55874 2.683901 -0.795609 3 0 3
z
" style="stroke: #ff0000"/>
</defs>
<g clip-path="url(#pec2f9990ec)">
<use xlink:href="#m3148e191ee" x="81.700131" y="260.012914" style="fill: #ff0000; stroke: #ff0000"/>
<use xlink:href="#m3148e191ee" x="99.538928" y="144.865544" style="fill: #ff0000; stroke: #ff0000"/>
<use xlink:href="#m3148e191ee" x="129.391609" y="74.005624" style="fill: #ff0000; stroke: #ff0000"/>
<use xlink:href="#m3148e191ee" x="142.861721" y="53.338148" style="fill: #ff0000; stroke: #ff0000"/>
<use xlink:href="#m3148e191ee" x="162.156746" y="43.004409" style="fill: #ff0000; stroke: #ff0000"/>
<use xlink:href="#m3148e191ee" x="180.723657" y="25.289429" style="fill: #ff0000; stroke: #ff0000"/>
</g>
</g>
<g id="patch_3">
<path d="M 64.28 295
L 64.28 12.446069
" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/>
</g>
<g id="patch_4">
<path d="M 447.522888 295
L 447.522888 12.446069
" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/>
</g>
<g id="patch_5">
<path d="M 64.28 295
L 447.522888 295
" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/>
</g>
<g id="patch_6">
<path d="M 64.28 12.446069
L 447.522888 12.446069
" style="fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square"/>
</g>
<g id="legend_1">
<g id="patch_7">
<path d="M 292.995701 288
L 437.722888 288
Q 440.522888 288 440.522888 285.2
L 440.522888 88.653125
Q 440.522888 85.853125 437.722888 85.853125
L 292.995701 85.853125
Q 290.195701 85.853125 290.195701 88.653125
L 290.195701 285.2
Q 290.195701 288 292.995701 288
z
" style="fill: #ffffff; opacity: 0.8; stroke: #cccccc; stroke-linejoin: miter"/>
</g>
<g id="line2d_25">
<path d="M 295.795701 96.353125
L 309.795701 96.353125
L 323.795701 96.353125
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #1f77b4; stroke-width: 1.5"/>
<g>
<use xlink:href="#m25ac481e9c" x="309.795701" y="96.353125" style="fill: #1f77b4; stroke: #1f77b4; stroke-linejoin: bevel"/>
</g>
</g>
<g id="text_17">
<!-- YOLOv6-v3.0 -->
<g transform="translate(334.995701 101.253125) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-59" d="M 3050 4238
L 4528 4238
L 4528 4122
L 4447 4122
Q 4366 4122 4209 4050
Q 4053 3978 3925 3843
Q 3797 3709 3609 3406
L 2588 1797
L 2588 734
Q 2588 344 2675 247
Q 2794 116 3050 116
L 3188 116
L 3188 0
L 1388 0
L 1388 116
L 1538 116
Q 1806 116 1919 278
Q 1988 378 1988 734
L 1988 1738
L 825 3513
Q 619 3825 545 3903
Q 472 3981 241 4091
Q 178 4122 59 4122
L 59 4238
L 1872 4238
L 1872 4122
L 1778 4122
Q 1631 4122 1507 4053
Q 1384 3984 1384 3847
Q 1384 3734 1575 3441
L 2459 2075
L 3291 3381
Q 3478 3675 3478 3819
Q 3478 3906 3433 3975
Q 3388 4044 3303 4083
Q 3219 4122 3050 4122
L 3050 4238
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-4c" d="M 3669 1172
L 3772 1150
L 3409 0
L 128 0
L 128 116
L 288 116
Q 556 116 672 291
Q 738 391 738 753
L 738 3488
Q 738 3884 650 3984
Q 528 4122 288 4122
L 128 4122
L 128 4238
L 2047 4238
L 2047 4122
Q 1709 4125 1573 4059
Q 1438 3994 1388 3894
Q 1338 3794 1338 3416
L 1338 753
Q 1338 494 1388 397
Q 1425 331 1503 300
Q 1581 269 1991 269
L 2300 269
Q 2788 269 2984 341
Q 3181 413 3343 595
Q 3506 778 3669 1172
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-76" d="M 53 2863
L 1400 2863
L 1400 2747
L 1313 2747
Q 1191 2747 1127 2687
Q 1063 2628 1063 2528
Q 1063 2419 1128 2269
L 1794 688
L 2463 2328
Q 2534 2503 2534 2594
Q 2534 2638 2509 2666
Q 2475 2713 2422 2730
Q 2369 2747 2206 2747
L 2206 2863
L 3141 2863
L 3141 2747
Q 2978 2734 2916 2681
Q 2806 2588 2719 2369
L 1703 -88
L 1575 -88
L 553 2328
Q 484 2497 421 2570
Q 359 2644 263 2694
Q 209 2722 53 2747
L 53 2863
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-2d" d="M 259 1672
L 1875 1672
L 1875 1200
L 259 1200
L 259 1672
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-59"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="144.433594"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.517578"/>
<use xlink:href="#TimesNewRomanPSMT-76" x="277.734375"/>
<use xlink:href="#TimesNewRomanPSMT-36" x="327.734375"/>
<use xlink:href="#TimesNewRomanPSMT-2d" x="377.734375"/>
<use xlink:href="#TimesNewRomanPSMT-76" x="411.035156"/>
<use xlink:href="#TimesNewRomanPSMT-33" x="461.035156"/>
<use xlink:href="#TimesNewRomanPSMT-2e" x="511.035156"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="536.035156"/>
</g>
</g>
<g id="line2d_26">
<path d="M 295.795701 116.147812
L 309.795701 116.147812
L 323.795701 116.147812
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #ff7f0e; stroke-width: 1.5"/>
<g>
<use xlink:href="#m0ebbb9ee98" x="309.795701" y="116.147812" style="fill: #ff7f0e; stroke: #ff7f0e"/>
</g>
</g>
<g id="text_18">
<!-- YOLOv7 -->
<g transform="translate(334.995701 121.047812) scale(0.14 -0.14)">
<use xlink:href="#TimesNewRomanPSMT-59"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="144.433594"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.517578"/>
<use xlink:href="#TimesNewRomanPSMT-76" x="277.734375"/>
<use xlink:href="#TimesNewRomanPSMT-37" x="327.734375"/>
</g>
</g>
<g id="line2d_27">
<path d="M 295.795701 135.9425
L 309.795701 135.9425
L 323.795701 135.9425
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #2ca02c; stroke-width: 1.5"/>
<g>
<use xlink:href="#m1addbb2f50" x="309.795701" y="135.9425" style="fill: #2ca02c; stroke: #2ca02c"/>
</g>
</g>
<g id="text_19">
<!-- YOLOv8 -->
<g transform="translate(334.995701 140.8425) scale(0.14 -0.14)">
<use xlink:href="#TimesNewRomanPSMT-59"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="144.433594"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.517578"/>
<use xlink:href="#TimesNewRomanPSMT-76" x="277.734375"/>
<use xlink:href="#TimesNewRomanPSMT-38" x="327.734375"/>
</g>
</g>
<g id="line2d_28">
<path d="M 295.795701 155.737187
L 309.795701 155.737187
L 323.795701 155.737187
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #d62728; stroke-width: 1.5"/>
<g>
<use xlink:href="#m20ef095d3f" x="309.795701" y="155.737187" style="fill: #d62728; stroke: #d62728; stroke-linejoin: miter"/>
</g>
</g>
<g id="text_20">
<!-- YOLOv9 -->
<g transform="translate(334.995701 160.637187) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-39" d="M 338 -88
L 338 28
Q 744 34 1094 217
Q 1444 400 1770 856
Q 2097 1313 2225 1859
Q 1734 1544 1338 1544
Q 891 1544 572 1889
Q 253 2234 253 2806
Q 253 3363 572 3797
Q 956 4325 1575 4325
Q 2097 4325 2469 3894
Q 2925 3359 2925 2575
Q 2925 1869 2578 1258
Q 2231 647 1613 244
Q 1109 -88 516 -88
L 338 -88
z
M 2275 2091
Q 2331 2497 2331 2741
Q 2331 3044 2228 3395
Q 2125 3747 1936 3934
Q 1747 4122 1506 4122
Q 1228 4122 1018 3872
Q 809 3622 809 3128
Q 809 2469 1088 2097
Q 1291 1828 1588 1828
Q 1731 1828 1928 1897
Q 2125 1966 2275 2091
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-59"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="144.433594"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.517578"/>
<use xlink:href="#TimesNewRomanPSMT-76" x="277.734375"/>
<use xlink:href="#TimesNewRomanPSMT-39" x="327.734375"/>
</g>
</g>
<g id="line2d_29">
<path d="M 295.795701 175.531875
L 309.795701 175.531875
L 323.795701 175.531875
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #9467bd; stroke-width: 1.5"/>
<g>
<use xlink:href="#m188839fe94" x="309.795701" y="175.531875" style="fill: #9467bd; stroke: #9467bd; stroke-linejoin: miter"/>
</g>
</g>
<g id="text_21">
<!-- PPYOLOE -->
<g transform="translate(334.995701 180.431875) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-45" d="M 1338 4006
L 1338 2331
L 2269 2331
Q 2631 2331 2753 2441
Q 2916 2584 2934 2947
L 3050 2947
L 3050 1472
L 2934 1472
Q 2891 1781 2847 1869
Q 2791 1978 2662 2040
Q 2534 2103 2269 2103
L 1338 2103
L 1338 706
Q 1338 425 1363 364
Q 1388 303 1450 267
Q 1513 231 1688 231
L 2406 231
Q 2766 231 2928 281
Q 3091 331 3241 478
Q 3434 672 3638 1063
L 3763 1063
L 3397 0
L 131 0
L 131 116
L 281 116
Q 431 116 566 188
Q 666 238 702 338
Q 738 438 738 747
L 738 3500
Q 738 3903 656 3997
Q 544 4122 281 4122
L 131 4122
L 131 4238
L 3397 4238
L 3444 3309
L 3322 3309
Q 3256 3644 3176 3769
Q 3097 3894 2941 3959
Q 2816 4006 2500 4006
L 1338 4006
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-50"/>
<use xlink:href="#TimesNewRomanPSMT-50" x="55.615234"/>
<use xlink:href="#TimesNewRomanPSMT-59" x="111.230469"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="183.447266"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="255.664062"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="316.748047"/>
<use xlink:href="#TimesNewRomanPSMT-45" x="388.964844"/>
</g>
</g>
<g id="line2d_30">
<path d="M 295.795701 195.326562
L 309.795701 195.326562
L 323.795701 195.326562
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #8c564b; stroke-width: 1.5"/>
<g>
<use xlink:href="#m444fa26bd7" x="309.795701" y="195.326562" style="fill: #8c564b; stroke: #8c564b; stroke-linejoin: miter"/>
</g>
</g>
<g id="text_22">
<!-- RTMDet -->
<g transform="translate(334.995701 200.226562) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-52" d="M 4325 0
L 3194 0
L 1759 1981
Q 1600 1975 1500 1975
Q 1459 1975 1412 1976
Q 1366 1978 1316 1981
L 1316 750
Q 1316 350 1403 253
Q 1522 116 1759 116
L 1925 116
L 1925 0
L 109 0
L 109 116
L 269 116
Q 538 116 653 291
Q 719 388 719 750
L 719 3488
Q 719 3888 631 3984
Q 509 4122 269 4122
L 109 4122
L 109 4238
L 1653 4238
Q 2328 4238 2648 4139
Q 2969 4041 3192 3777
Q 3416 3513 3416 3147
Q 3416 2756 3161 2468
Q 2906 2181 2372 2063
L 3247 847
Q 3547 428 3762 290
Q 3978 153 4325 116
L 4325 0
z
M 1316 2178
Q 1375 2178 1419 2176
Q 1463 2175 1491 2175
Q 2097 2175 2405 2437
Q 2713 2700 2713 3106
Q 2713 3503 2464 3751
Q 2216 4000 1806 4000
Q 1625 4000 1316 3941
L 1316 2178
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-54" d="M 3703 4238
L 3750 3244
L 3631 3244
Q 3597 3506 3538 3619
Q 3441 3800 3280 3886
Q 3119 3972 2856 3972
L 2259 3972
L 2259 734
Q 2259 344 2344 247
Q 2463 116 2709 116
L 2856 116
L 2856 0
L 1059 0
L 1059 116
L 1209 116
Q 1478 116 1591 278
Q 1659 378 1659 734
L 1659 3972
L 1150 3972
Q 853 3972 728 3928
Q 566 3869 450 3700
Q 334 3531 313 3244
L 194 3244
L 244 4238
L 3703 4238
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-44" d="M 109 0
L 109 116
L 269 116
Q 538 116 650 288
Q 719 391 719 750
L 719 3488
Q 719 3884 631 3984
Q 509 4122 269 4122
L 109 4122
L 109 4238
L 1834 4238
Q 2784 4238 3279 4022
Q 3775 3806 4076 3303
Q 4378 2800 4378 2141
Q 4378 1256 3841 663
Q 3238 0 2003 0
L 109 0
z
M 1319 306
Q 1716 219 1984 219
Q 2709 219 3187 728
Q 3666 1238 3666 2109
Q 3666 2988 3187 3494
Q 2709 4000 1959 4000
Q 1678 4000 1319 3909
L 1319 306
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-52"/>
<use xlink:href="#TimesNewRomanPSMT-54" x="60.699219"/>
<use xlink:href="#TimesNewRomanPSMT-4d" x="121.783203"/>
<use xlink:href="#TimesNewRomanPSMT-44" x="210.699219"/>
<use xlink:href="#TimesNewRomanPSMT-65" x="282.916016"/>
<use xlink:href="#TimesNewRomanPSMT-74" x="327.300781"/>
</g>
</g>
<g id="line2d_31">
<path d="M 295.795701 215.12125
L 309.795701 215.12125
L 323.795701 215.12125
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #e377c2; stroke-width: 1.5"/>
<g>
<use xlink:href="#ma742850c5b" x="309.795701" y="215.12125" style="fill: #e377c2; stroke: #e377c2; stroke-linejoin: miter"/>
</g>
</g>
<g id="text_23">
<!-- YOLO-MS -->
<g transform="translate(334.995701 220.02125) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-53" d="M 2934 4334
L 2934 2869
L 2819 2869
Q 2763 3291 2617 3541
Q 2472 3791 2203 3937
Q 1934 4084 1647 4084
Q 1322 4084 1109 3886
Q 897 3688 897 3434
Q 897 3241 1031 3081
Q 1225 2847 1953 2456
Q 2547 2138 2764 1967
Q 2981 1797 3098 1565
Q 3216 1334 3216 1081
Q 3216 600 2842 251
Q 2469 -97 1881 -97
Q 1697 -97 1534 -69
Q 1438 -53 1133 45
Q 828 144 747 144
Q 669 144 623 97
Q 578 50 556 -97
L 441 -97
L 441 1356
L 556 1356
Q 638 900 775 673
Q 913 447 1195 297
Q 1478 147 1816 147
Q 2206 147 2432 353
Q 2659 559 2659 841
Q 2659 997 2573 1156
Q 2488 1316 2306 1453
Q 2184 1547 1640 1851
Q 1097 2156 867 2337
Q 638 2519 519 2737
Q 400 2956 400 3219
Q 400 3675 750 4004
Q 1100 4334 1641 4334
Q 1978 4334 2356 4169
Q 2531 4091 2603 4091
Q 2684 4091 2736 4139
Q 2788 4188 2819 4334
L 2934 4334
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-59"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="144.433594"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.517578"/>
<use xlink:href="#TimesNewRomanPSMT-2d" x="277.734375"/>
<use xlink:href="#TimesNewRomanPSMT-4d" x="311.035156"/>
<use xlink:href="#TimesNewRomanPSMT-53" x="399.951172"/>
</g>
</g>
<g id="line2d_32">
<path d="M 295.795701 234.915937
L 309.795701 234.915937
L 323.795701 234.915937
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #7f7f7f; stroke-width: 1.5"/>
<g>
<use xlink:href="#m7f8f30e89b" x="309.795701" y="234.915937" style="fill: #7f7f7f; stroke: #7f7f7f; stroke-linejoin: miter"/>
</g>
</g>
<g id="text_24">
<!-- Gold-YOLO -->
<g transform="translate(334.995701 239.815937) scale(0.14 -0.14)">
<defs>
<path id="TimesNewRomanPSMT-47" d="M 3928 4334
L 4038 2997
L 3928 2997
Q 3763 3497 3500 3750
Q 3122 4116 2528 4116
Q 1719 4116 1297 3475
Q 944 2934 944 2188
Q 944 1581 1178 1081
Q 1413 581 1792 348
Q 2172 116 2572 116
Q 2806 116 3025 175
Q 3244 234 3447 350
L 3447 1575
Q 3447 1894 3398 1992
Q 3350 2091 3248 2142
Q 3147 2194 2891 2194
L 2891 2313
L 4531 2313
L 4531 2194
L 4453 2194
Q 4209 2194 4119 2031
Q 4056 1916 4056 1575
L 4056 278
Q 3697 84 3347 -6
Q 2997 -97 2569 -97
Q 1341 -97 703 691
Q 225 1281 225 2053
Q 225 2613 494 3125
Q 813 3734 1369 4063
Q 1834 4334 2469 4334
Q 2700 4334 2889 4296
Q 3078 4259 3425 4131
Q 3600 4066 3659 4066
Q 3719 4066 3761 4120
Q 3803 4175 3813 4334
L 3928 4334
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-6c" d="M 1184 4444
L 1184 647
Q 1184 378 1223 290
Q 1263 203 1344 158
Q 1425 113 1647 113
L 1647 0
L 244 0
L 244 113
Q 441 113 512 153
Q 584 194 625 287
Q 666 381 666 647
L 666 3247
Q 666 3731 644 3842
Q 622 3953 573 3993
Q 525 4034 450 4034
Q 369 4034 244 3984
L 191 4094
L 1044 4444
L 1184 4444
z
" transform="scale(0.015625)"/>
<path id="TimesNewRomanPSMT-64" d="M 2222 322
Q 2013 103 1813 7
Q 1613 -88 1381 -88
Q 913 -88 563 304
Q 213 697 213 1313
Q 213 1928 600 2439
Q 988 2950 1597 2950
Q 1975 2950 2222 2709
L 2222 3238
Q 2222 3728 2198 3840
Q 2175 3953 2125 3993
Q 2075 4034 2000 4034
Q 1919 4034 1784 3984
L 1744 4094
L 2597 4444
L 2738 4444
L 2738 1134
Q 2738 631 2761 520
Q 2784 409 2836 365
Q 2888 322 2956 322
Q 3041 322 3181 375
L 3216 266
L 2366 -88
L 2222 -88
L 2222 322
z
M 2222 541
L 2222 2016
Q 2203 2228 2109 2403
Q 2016 2578 1861 2667
Q 1706 2756 1559 2756
Q 1284 2756 1069 2509
Q 784 2184 784 1559
Q 784 928 1059 592
Q 1334 256 1672 256
Q 1956 256 2222 541
z
" transform="scale(0.015625)"/>
</defs>
<use xlink:href="#TimesNewRomanPSMT-47"/>
<use xlink:href="#TimesNewRomanPSMT-6f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-6c" x="122.216797"/>
<use xlink:href="#TimesNewRomanPSMT-64" x="150"/>
<use xlink:href="#TimesNewRomanPSMT-2d" x="200"/>
<use xlink:href="#TimesNewRomanPSMT-59" x="233.300781"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="305.517578"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="377.734375"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="438.818359"/>
</g>
</g>
<g id="line2d_33">
<path d="M 295.795701 254.710625
L 309.795701 254.710625
L 323.795701 254.710625
" style="fill: none; stroke-dasharray: 5.55,2.4; stroke-dashoffset: 0; stroke: #bcbd22; stroke-width: 1.5"/>
<g>
<use xlink:href="#mceb5dd67df" x="309.795701" y="254.710625" style="fill: #bcbd22; stroke: #bcbd22; stroke-linejoin: miter"/>
</g>
</g>
<g id="text_25">
<!-- RT-DETR -->
<g transform="translate(334.995701 259.610625) scale(0.14 -0.14)">
<use xlink:href="#TimesNewRomanPSMT-52"/>
<use xlink:href="#TimesNewRomanPSMT-54" x="60.699219"/>
<use xlink:href="#TimesNewRomanPSMT-2d" x="112.658203"/>
<use xlink:href="#TimesNewRomanPSMT-44" x="145.958984"/>
<use xlink:href="#TimesNewRomanPSMT-45" x="218.175781"/>
<use xlink:href="#TimesNewRomanPSMT-54" x="279.259766"/>
<use xlink:href="#TimesNewRomanPSMT-52" x="340.34375"/>
</g>
</g>
<g id="line2d_34">
<path d="M 295.795701 274.505312
L 309.795701 274.505312
L 323.795701 274.505312
" style="fill: none; stroke: #ff0000; stroke-width: 3; stroke-linecap: square"/>
<g>
<use xlink:href="#m3148e191ee" x="309.795701" y="274.505312" style="fill: #ff0000; stroke: #ff0000"/>
</g>
</g>
<g id="text_26">
<!-- YOLOv10 (Ours) -->
<g transform="translate(334.995701 279.405312) scale(0.14 -0.14)">
<use xlink:href="#TimesNewRomanPSMT-59"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="72.216797"/>
<use xlink:href="#TimesNewRomanPSMT-4c" x="144.433594"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="205.517578"/>
<use xlink:href="#TimesNewRomanPSMT-76" x="277.734375"/>
<use xlink:href="#TimesNewRomanPSMT-31" x="327.734375"/>
<use xlink:href="#TimesNewRomanPSMT-30" x="377.734375"/>
<use xlink:href="#TimesNewRomanPSMT-20" x="427.734375"/>
<use xlink:href="#TimesNewRomanPSMT-28" x="452.734375"/>
<use xlink:href="#TimesNewRomanPSMT-4f" x="486.035156"/>
<use xlink:href="#TimesNewRomanPSMT-75" x="558.251953"/>
<use xlink:href="#TimesNewRomanPSMT-72" x="608.251953"/>
<use xlink:href="#TimesNewRomanPSMT-73" x="641.552734"/>
<use xlink:href="#TimesNewRomanPSMT-29" x="680.46875"/>
</g>
</g>
</g>
</g>
</g>
<defs>
<clipPath id="pec2f9990ec">
<rect x="64.28" y="12.446069" width="383.242888" height="282.553931"/>
</clipPath>
</defs>
</svg>
img.png

4.17 KB

This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment