Bỏ để qua phần nội dung

Tiện ích đơn giản

Mã với phối cảnh

Các ultralytics Gói đi kèm với vô số tiện ích có thể hỗ trợ, nâng cao và tăng tốc quy trình làm việc của bạn. Có nhiều hơn nữa có sẵn, nhưng đây là một số sẽ hữu ích cho hầu hết các nhà phát triển. Chúng cũng là một điểm tham khảo tuyệt vời để sử dụng khi học lập trình.



Xem: Ultralytics Tiện ích | Chú thích tự động, API Explorer và Chuyển đổi tập dữ liệu

Dữ liệu

YOLO Trình khám phá dữ liệu

YOLO Explorer đã được thêm vào trong 8.1.0 Cập nhật kỷ niệm và là một công cụ mạnh mẽ mà bạn có thể sử dụng để hiểu rõ hơn về tập dữ liệu của mình. Một trong những chức năng chính mà YOLO Explorer cung cấp, là khả năng sử dụng các truy vấn văn bản để tìm các trường hợp đối tượng trong tập dữ liệu của bạn.

Tự động dán nhãn / Chú thích

Chú thích tập dữ liệu là một quá trình rất tốn tài nguyên và thời gian. Nếu bạn có một YOLO Mô hình phát hiện đối tượng được đào tạo trên một lượng dữ liệu hợp lý, bạn có thể sử dụng nó và SAM để tự động chú thích dữ liệu bổ sung (định dạng phân đoạn).

from ultralytics.data.annotator import auto_annotate

auto_annotate(  # (1)!
    data="path/to/new/data",
    det_model="yolov8n.pt",
    sam_model="mobile_sam.pt",
    device="cuda",
    output_dir="path/to/save_labels",
)
  1. Không có gì trả về từ hàm này

  2. Xem phần tham khảo cho annotator.auto_annotate để hiểu rõ hơn về cách chức năng hoạt động.

  3. Sử dụng kết hợp với chức năng segments2boxes để tạo các hộp giới hạn phát hiện đối tượng là tốt

Chuyển đổi COCO thành YOLO Định dạng

Sử dụng để chuyển đổi chú thích COCO JSON thành thích hợp YOLO định dạng. Đối với bộ dữ liệu phát hiện đối tượng (hộp giới hạn), use_segmentsuse_keypoints nên là cả hai False

from ultralytics.data.converter import convert_coco

convert_coco(  # (1)!
    "../datasets/coco/annotations/",
    use_segments=False,
    use_keypoints=False,
    cls91to80=True,
)
  1. Không có gì trả về từ hàm này

Để biết thêm thông tin về convert_coco chức năng Truy cập trang tham khảo

Nhận kích thước hộp giới hạn

from ultralytics.utils.plotting import Annotator
from ultralytics import YOLO
import cv2

model = YOLO('yolov8n.pt')  # Load pretrain or fine-tune model

# Process the image
source = cv2.imread('path/to/image.jpg')
results = model(source)

# Extract results
annotator = Annotator(source, example=model.names)

for box in results[0].boxes.xyxy.cpu():
    width, height, area = annotator.get_bbox_dimension(box)
    print("Bounding Box Width {}, Height {}, Area {}".format(
        width.item(), height.item(), area.item()))

Chuyển đổi các hộp giới hạn thành các phân đoạn

Với hiện có x y w h Giới hạn dữ liệu hộp, chuyển đổi thành phân đoạn bằng cách sử dụng yolo_bbox2segment chức năng. Các tệp cho hình ảnh và chú thích cần được sắp xếp như sau:

data
|__ images
    ├─ 001.jpg
    ├─ 002.jpg
    ├─ ..
    └─ NNN.jpg
|__ labels
    ├─ 001.txt
    ├─ 002.txt
    ├─ ..
    └─ NNN.txt
from ultralytics.data.converter import yolo_bbox2segment

yolo_bbox2segment(  # (1)!
    im_dir="path/to/images",
    save_dir=None,  # saved to "labels-segment" in images directory
    sam_model="sam_b.pt",
)
  1. Không có gì trả về từ hàm này

Ghé thăm yolo_bbox2segment Trang tham khảo để biết thêm thông tin về chức năng.

Chuyển đổi phân đoạn thành hộp giới hạn

Nếu bạn có tập dữ liệu sử dụng Định dạng tập dữ liệu phân đoạn Bạn có thể dễ dàng chuyển đổi chúng thành các hộp giới hạn bên phải (hoặc ngang) (x y w h định dạng) với chức năng này.

import numpy as np

from ultralytics.utils.ops import segments2boxes

segments = np.array(
    [
        [805, 392, 797, 400, ..., 808, 714, 808, 392],
        [115, 398, 113, 400, ..., 150, 400, 149, 298],
        [267, 412, 265, 413, ..., 300, 413, 299, 412],
    ]
)

segments2boxes([s.reshape(-1, 2) for s in segments])
# >>> array([[ 741.66, 631.12, 133.31, 479.25],
#           [ 146.81, 649.69, 185.62, 502.88],
#           [ 281.81, 636.19, 118.12, 448.88]],
#           dtype=float32) # xywh bounding boxes

Để hiểu cách thức hoạt động của chức năng này, hãy truy cập trang tham khảo

Tiện ích

Nén hình ảnh

Nén một tệp hình ảnh duy nhất để giảm kích thước trong khi vẫn giữ nguyên tỷ lệ khung hình và chất lượng của nó. Nếu hình ảnh đầu vào nhỏ hơn kích thước tối đa, nó sẽ không được thay đổi kích thước.

from pathlib import Path

from ultralytics.data.utils import compress_one_image

for f in Path("path/to/dataset").rglob("*.jpg"):
    compress_one_image(f)  # (1)!
  1. Không có gì trả về từ hàm này

Tự động tách tập dữ liệu

Tự động chia tập dữ liệu thành train/val/test tách và lưu các phần tách kết quả vào autosplit_*.txt Tập tin. Chức năng này sẽ sử dụng lấy mẫu ngẫu nhiên, không được bao gồm khi sử dụng fraction Lập luận cho đào tạo.

from ultralytics.data.utils import autosplit

autosplit(  # (1)!
    path="path/to/images",
    weights=(0.9, 0.1, 0.0),  # (train, validation, test) fractional splits
    annotated_only=False,  # split only images with annotation file when True
)
  1. Không có gì trả về từ hàm này

Xem trang Tham khảo để biết thêm chi tiết về chức năng này.

Segment-polygon to Binary Mask

Chuyển đổi một đa giác duy nhất (như danh sách) thành mặt nạ nhị phân có kích thước hình ảnh được chỉ định. Đa giác ở dạng [N, 2] với N như số lượng (x, y) các điểm xác định đường viền đa giác.

Cảnh báo

N phải luôn luôn được đồng đều.

import numpy as np

from ultralytics.data.utils import polygon2mask

imgsz = (1080, 810)
polygon = np.array([805, 392, 797, 400, ..., 808, 714, 808, 392])  # (238, 2)

mask = polygon2mask(
    imgsz,  # tuple
    [polygon],  # input as list
    color=255,  # 8-bit binary
    downsample_ratio=1,
)

Hộp giới hạn

Phiên bản Bounding Box (ngang)

Để quản lý dữ liệu hộp giới hạn, biểu tượng Bboxes Lớp sẽ giúp chuyển đổi giữa định dạng tọa độ hộp, kích thước hộp tỷ lệ, tính toán diện tích, bao gồm độ lệch và hơn thế nữa!

import numpy as np

from ultralytics.utils.instance import Bboxes

boxes = Bboxes(
    bboxes=np.array(
        [
            [22.878, 231.27, 804.98, 756.83],
            [48.552, 398.56, 245.35, 902.71],
            [669.47, 392.19, 809.72, 877.04],
            [221.52, 405.8, 344.98, 857.54],
            [0, 550.53, 63.01, 873.44],
            [0.0584, 254.46, 32.561, 324.87],
        ]
    ),
    format="xyxy",
)

boxes.areas()
# >>> array([ 4.1104e+05,       99216,       68000,       55772,       20347,      2288.5])

boxes.convert("xywh")
print(boxes.bboxes)
# >>> array(
#     [[ 413.93, 494.05,  782.1, 525.56],
#      [ 146.95, 650.63,  196.8, 504.15],
#      [  739.6, 634.62, 140.25, 484.85],
#      [ 283.25, 631.67, 123.46, 451.74],
#      [ 31.505, 711.99,  63.01, 322.91],
#      [  16.31, 289.67, 32.503,  70.41]]
# )

Xem Bboxes Phần tham khảo để biết thêm các thuộc tính và phương pháp có sẵn.

Mẹo

Nhiều chức năng sau (và hơn thế nữa) có thể được truy cập bằng cách sử dụng Bboxes lớp Nhưng nếu bạn muốn làm việc trực tiếp với các hàm, hãy xem các phần phụ tiếp theo về cách nhập các hàm này một cách độc lập.

Hộp chia tỷ lệ

Khi chia tỷ lệ và hình ảnh lên hoặc xuống, tọa độ hộp giới hạn tương ứng có thể được chia tỷ lệ thích hợp để phù hợp bằng cách sử dụng ultralytics.utils.ops.scale_boxes.

import cv2 as cv
import numpy as np

from ultralytics.utils.ops import scale_boxes

image = cv.imread("ultralytics/assets/bus.jpg")
h, w, c = image.shape
resized = cv.resize(image, None, (), fx=1.2, fy=1.2)
new_h, new_w, _ = resized.shape

xyxy_boxes = np.array(
    [
        [22.878, 231.27, 804.98, 756.83],
        [48.552, 398.56, 245.35, 902.71],
        [669.47, 392.19, 809.72, 877.04],
        [221.52, 405.8, 344.98, 857.54],
        [0, 550.53, 63.01, 873.44],
        [0.0584, 254.46, 32.561, 324.87],
    ]
)

new_boxes = scale_boxes(
    img1_shape=(h, w),  # original image dimensions
    boxes=xyxy_boxes,  # boxes from original image
    img0_shape=(new_h, new_w),  # resized image dimensions (scale to)
    ratio_pad=None,
    padding=False,
    xywh=False,
)

print(new_boxes)  # (1)!
# >>> array(
#     [[  27.454,  277.52,  965.98,   908.2],
#     [   58.262,  478.27,  294.42,  1083.3],
#     [   803.36,  470.63,  971.66,  1052.4],
#     [   265.82,  486.96,  413.98,    1029],
#     [        0,  660.64,  75.612,  1048.1],
#     [   0.0701,  305.35,  39.073,  389.84]]
# )
  1. Các hộp giới hạn được thu nhỏ cho kích thước hình ảnh mới

Chuyển đổi định dạng hộp giới hạn

XYXY → XYWH

Chuyển đổi tọa độ hộp giới hạn từ định dạng (x1, y1, x2, y2) sang định dạng (x, y, chiều rộng, chiều cao) trong đó (x1, y1) là góc trên cùng bên trái và (x2, y2) là góc dưới cùng bên phải.

import numpy as np

from ultralytics.utils.ops import xyxy2xywh

xyxy_boxes = np.array(
    [
        [22.878, 231.27, 804.98, 756.83],
        [48.552, 398.56, 245.35, 902.71],
        [669.47, 392.19, 809.72, 877.04],
        [221.52, 405.8, 344.98, 857.54],
        [0, 550.53, 63.01, 873.44],
        [0.0584, 254.46, 32.561, 324.87],
    ]
)
xywh = xyxy2xywh(xyxy_boxes)

print(xywh)
# >>> array(
#     [[ 413.93,  494.05,   782.1, 525.56],
#     [  146.95,  650.63,   196.8, 504.15],
#     [   739.6,  634.62,  140.25, 484.85],
#     [  283.25,  631.67,  123.46, 451.74],
#     [  31.505,  711.99,   63.01, 322.91],
#     [   16.31,  289.67,  32.503,  70.41]]
# )

Tất cả các chuyển đổi Bounding Box

from ultralytics.utils.ops import (
    ltwh2xywh,
    ltwh2xyxy,
    xywh2ltwh,  # xywh → top-left corner, w, h
    xywh2xyxy,
    xywhn2xyxy,  # normalized → pixel
    xyxy2ltwh,  # xyxy → top-left corner, w, h
    xyxy2xywhn,  # pixel → normalized
)

for func in (ltwh2xywh, ltwh2xyxy, xywh2ltwh, xywh2xyxy, xywhn2xyxy, xyxy2ltwh, xyxy2xywhn):
    print(help(func))  # print function docstrings

Xem docstring cho từng hàm hoặc truy cập ultralytics.utils.ops Trang tham khảo để đọc thêm về từng chức năng.

Vẽ

Vẽ chú thích

Ultralytics bao gồm một lớp Annotator có thể được sử dụng để chú thích bất kỳ loại dữ liệu nào. Nó dễ sử dụng nhất với các hộp giới hạn phát hiện đối tượng, các điểm chính đặt racác hộp giới hạn định hướng.

Hộp giới hạn ngang

import cv2 as cv
import numpy as np

from ultralytics.utils.plotting import Annotator, colors

names = {  # (1)!
    0: "person",
    5: "bus",
    11: "stop sign",
}

image = cv.imread("ultralytics/assets/bus.jpg")
ann = Annotator(
    image,
    line_width=None,  # default auto-size
    font_size=None,  # default auto-size
    font="Arial.ttf",  # must be ImageFont compatible
    pil=False,  # use PIL, otherwise uses OpenCV
)

xyxy_boxes = np.array(
    [
        [5, 22.878, 231.27, 804.98, 756.83],  # class-idx x1 y1 x2 y2
        [0, 48.552, 398.56, 245.35, 902.71],
        [0, 669.47, 392.19, 809.72, 877.04],
        [0, 221.52, 405.8, 344.98, 857.54],
        [0, 0, 550.53, 63.01, 873.44],
        [11, 0.0584, 254.46, 32.561, 324.87],
    ]
)

for nb, box in enumerate(xyxy_boxes):
    c_idx, *box = box
    label = f"{str(nb).zfill(2)}:{names.get(int(c_idx))}"
    ann.box_label(box, label, color=colors(c_idx, bgr=True))

image_with_bboxes = ann.result()
  1. Tên có thể được sử dụng từ model.names Khi Làm việc với kết quả phát hiện

Hộp giới hạn định hướng (OBB)

import cv2 as cv
import numpy as np

from ultralytics.utils.plotting import Annotator, colors

obb_names = {10: "small vehicle"}
obb_image = cv.imread("datasets/dota8/images/train/P1142__1024__0___824.jpg")
obb_boxes = np.array(
    [
        [0, 635, 560, 919, 719, 1087, 420, 803, 261],  # class-idx x1 y1 x2 y2 x3 y2 x4 y4
        [0, 331, 19, 493, 260, 776, 70, 613, -171],
        [9, 869, 161, 886, 147, 851, 101, 833, 115],
    ]
)
ann = Annotator(
    obb_image,
    line_width=None,  # default auto-size
    font_size=None,  # default auto-size
    font="Arial.ttf",  # must be ImageFont compatible
    pil=False,  # use PIL, otherwise uses OpenCV
)
for obb in obb_boxes:
    c_idx, *obb = obb
    obb = np.array(obb).reshape(-1, 4, 2).squeeze()
    label = f"{obb_names.get(int(c_idx))}"
    ann.box_label(
        obb,
        label,
        color=colors(c_idx, True),
        rotated=True,
    )

image_with_obb = ann.result()

Bounding Boxes Circle Annotation (Circle Label)

import cv2

from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator, colors

model = YOLO("yolov8s.pt")
cap = cv2.VideoCapture("path/to/video/file.mp4")

w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
writer = cv2.VideoWriter("Ultralytics circle annotation.avi", cv2.VideoWriter_fourcc(*"MJPG"), fps, (w, h))

while True:
    ret, im0 = cap.read()
    if not ret:
        break

    annotator = Annotator(im0, line_width=2)

    results = model.predict(im0)
    boxes = results[0].boxes.xyxy.cpu()
    clss = results[0].boxes.cls.cpu().tolist()

    for box, cls in zip(boxes, clss):
        x1, y1 = int((box[0] + box[2]) // 2), int((box[1] + box[3]) // 2)
        annotator.circle_label(box, label=model.names[int(cls)], color=colors(int(cls), True))

    writer.write(im0)
    cv2.imshow("Ultralytics circle annotation", im0)

    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

writer.release()
cap.release()
cv2.destroyAllWindows()

Bounding Boxes Text Annotation (Text Label)

import cv2

from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator, colors

model = YOLO("yolov8s.pt")
cap = cv2.VideoCapture("path/to/video/file.mp4")

w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
writer = cv2.VideoWriter("Ultralytics text annotation.avi", cv2.VideoWriter_fourcc(*"MJPG"), fps, (w, h))

while True:
    ret, im0 = cap.read()
    if not ret:
        break

    annotator = Annotator(im0, line_width=2)

    results = model.predict(im0)
    boxes = results[0].boxes.xyxy.cpu()
    clss = results[0].boxes.cls.cpu().tolist()

    for box, cls in zip(boxes, clss):
        x1, y1 = int((box[0] + box[2]) // 2), int((box[1] + box[3]) // 2)
        annotator.text_label(box, label=model.names[int(cls)], color=colors(int(cls), True))

    writer.write(im0)
    cv2.imshow("Ultralytics text annotation", im0)

    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

writer.release()
cap.release()
cv2.destroyAllWindows()

Xem Annotator Trang tham khảo để có thêm thông tin chi tiết.

Linh tinh

Hồ sơ mã

Kiểm tra thời lượng để mã chạy/xử lý bằng cách sử dụng with hoặc như một người trang trí.

from ultralytics.utils.ops import Profile

with Profile(device="cuda:0") as dt:
    pass  # operation to measure

print(dt)
# >>> "Elapsed time is 9.5367431640625e-07 s"

Ultralytics Các định dạng được hỗ trợ

Muốn hoặc cần sử dụng các định dạng của hình ảnh hoặc loại video được hỗ trợ bởi Ultralytics Lập trình? Sử dụng các hằng số này nếu bạn cần.

from ultralytics.data.utils import IMG_FORMATS, VID_FORMATS

print(IMG_FORMATS)
# {'tiff', 'pfm', 'bmp', 'mpo', 'dng', 'jpeg', 'png', 'webp', 'tif', 'jpg'}

print(VID_FORMATS)
# {'avi', 'mpg', 'wmv', 'mpeg', 'm4v', 'mov', 'mp4', 'asf', 'mkv', 'ts', 'gif', 'webm'}

Làm cho chia hết

Tính số nguyên gần nhất với x để chia hết đều khi chia cho y.

from ultralytics.utils.ops import make_divisible

make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8


Created 2024-02-20, Updated 2024-06-20
Authors: glenn-jocher (8), ambitious-octopus (1), IvorZhu331 (1), RizwanMunawar (1), Burhan-Q (2)

Ý kiến