рд╕рд╛рдордЧреНрд░реА рдкрд░ рдЬрд╛рдПрдВ

рд╕рд░рд▓ рдЙрдкрдпреЛрдЧрд┐рддрд╛рдПрдБ

рдкрд░рд┐рдкреНрд░реЗрдХреНрд╖реНрдп рдХреЗ рд╕рд╛рде рдХреЛрдб

рд╡рд╣реА ultralytics рдкреИрдХреЗрдЬ рдЙрдкрдпреЛрдЧрд┐рддрд╛рдУрдВ рдХреЗ рдЕрд╕рдВрдЦреНрдп рдХреЗ рд╕рд╛рде рдЖрддрд╛ рд╣реИ рдЬреЛ рдЖрдкрдХреЗ рд╡рд░реНрдХрдлрд╝реНрд▓реЛрдЬрд╝ рдХрд╛ рд╕рдорд░реНрдерди, рд╡реГрджреНрдзрд┐ рдФрд░ рдЧрддрд┐ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдХрдИ рдФрд░ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдХреБрдЫ рдРрд╕реЗ рд╣реИрдВ рдЬреЛ рдЕрдзрд┐рдХрд╛рдВрд╢ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдВрдЧреЗред рд╡реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕реАрдЦрддреЗ рд╕рдордп рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╣рд╛рди рд╕рдВрджрд░реНрдн рдмрд┐рдВрджреБ рднреА рд╣реИрдВред



рд╕рддрд░реНрдХрддрд╛: Ultralytics рдЙрдкрдпреЛрдЧрд┐рддрд╛рдПрдБ | рдСрдЯреЛ рдПрдиреЛрдЯреЗрд╢рди, рдПрдХреНрд╕рдкреНрд▓реЛрд░рд░ рдПрдкреАрдЖрдИ рдФрд░ рдбреЗрдЯрд╛рд╕реЗрдЯ рд░реВрдкрд╛рдВрддрд░рдг

рдбрд╛рдЯрд╛

YOLO рдбреЗрдЯрд╛ рдПрдХреНрд╕рдкреНрд▓реЛрд░рд░

YOLO рдЦреЛрдЬрдпрд╛рддреНрд░реА рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ 8.1.0 рд╡рд░реНрд╖рдЧрд╛рдВрда рдЕрджреНрдпрддрди рдФрд░ рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЙрдкрдХрд░рдг рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрдк рдЕрдкрдиреЗ рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЛ рдмреЗрд╣рддрд░ рдврдВрдЧ рд╕реЗ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкреНрд░рдореБрдЦ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдЬреЛ YOLO рдПрдХреНрд╕рдкреНрд▓реЛрд░рд░ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЖрдкрдХреЗ рдбреЗрдЯрд╛рд╕реЗрдЯ рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдЯреЗрдХреНрд╕реНрдЯ рдХреНрд╡реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред

рдСрдЯреЛ рд▓реЗрдмрд▓рд┐рдВрдЧ/рдПрдиреЛрдЯреЗрд╢рди

рдбреЗрдЯрд╛рд╕реЗрдЯ рдПрдиреЛрдЯреЗрд╢рди рдПрдХ рдмрд╣реБрдд рд╣реА рд╕рдВрд╕рд╛рдзрди рдЧрд╣рди рдФрд░ рд╕рдордп рд▓реЗрдиреЗ рд╡рд╛рд▓реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ YOLO рдСрдмреНрдЬреЗрдХреНрдЯ рдбрд┐рдЯреЗрдХреНрд╢рди рдореЙрдбрд▓ рдХреЛ рдЙрдЪрд┐рдд рдорд╛рддреНрд░рд╛ рдореЗрдВ рдбреЗрдЯрд╛ рдкрд░ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЖрдк рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ SAM рдЕрддрд┐рд░рд┐рдХреНрдд рдбреЗрдЯрд╛ (рд╡рд┐рднрд╛рдЬрди рдкреНрд░рд╛рд░реВрдк) рдХреЛ рдСрдЯреЛ-рдПрдиреЛрдЯреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред

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. рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдХреБрдЫ рднреА рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ

  2. рдХреЗ рд▓рд┐рдП рд╕рдВрджрд░реНрдн рдЕрдиреБрднрд╛рдЧ рджреЗрдЦреЗрдВ annotator.auto_annotate рдлрд╝рдВрдХреНрд╢рди рдХреИрд╕реЗ рд╕рдВрдЪрд╛рд▓рд┐рдд рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдПред

  3. рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдлрд▓рди segments2boxes рдСрдмреНрдЬреЗрдХреНрдЯ рдбрд┐рдЯреЗрдХреНрд╢рди рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рднреА рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП

COCO рдХреЛ рдореЗрдВ рдмрджрд▓реЗрдВ YOLO рдкреНрд░рд╛рд░реВрдк

COCO JSON рдПрдиреЛрдЯреЗрд╢рди рдХреЛ рдЙрдЪрд┐рдд рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ YOLO рдкреНрд░рд╛рд░реВрдкред рдСрдмреНрдЬреЗрдХреНрдЯ рдбрд┐рдЯреЗрдХреНрд╢рди (рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕) рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЗ рд▓рд┐рдП, use_segments рдФрд░ use_keypoints рджреЛрдиреЛрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП False

from ultralytics.data.converter import convert_coco

convert_coco(#(1)!
    '../datasets/coco/annotations/',
    use_segments=False, 
    use_keypoints=False,
    cls91to80=True,
)
  1. рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдХреБрдЫ рднреА рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ

рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП convert_coco рдлрд▓рди рд╕рдВрджрд░реНрдн рдкреГрд╖реНрда рдкрд░ рдЬрд╛рдПрдВ

рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рдЖрдпрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ

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()))

рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рдХреЛ рд╕реЗрдЧрдореЗрдВрдЯ рдореЗрдВ рдмрджрд▓реЗрдВ

рдореМрдЬреВрджрд╛ рдХреЗ рд╕рд╛рде x y w h рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рдбреЗрдЯрд╛, рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реЗрдЧрдореЗрдВрдЯ рдореЗрдВ рдХрдирд╡рд░реНрдЯ рдХрд░реЗрдВ yolo_bbox2segment рдлрд▓рдиред рдЫрд╡рд┐рдпреЛрдВ рдФрд░ рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд▓рд┐рдП рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

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. рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдХреБрдЫ рднреА рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ

рднреЗрдВрдЯ yolo_bbox2segment рд╕рдВрджрд░реНрдн рдкреГрд╖реНрда рд╕рдорд╛рд░реЛрд╣ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдПред

рд╕реЗрдЧрдореЗрдВрдЯ рдХреЛ рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рдореЗрдВ рдмрджрд▓реЗрдВ

рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдбреЗрдЯрд╛рд╕реЗрдЯ рд╣реИ рдЬреЛ рд╡рд┐рднрд╛рдЬрди рдбреЗрдЯрд╛рд╕реЗрдЯ рдкреНрд░рд╛рд░реВрдк рдЖрдк рдЗрдиреНрд╣реЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рдЕрдк-рд░рд╛рдЗрдЯ (рдпрд╛ рдХреНрд╖реИрддрд┐рдЬ) рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ (x y w h рдкреНрд░рд╛рд░реВрдк) рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рдеред

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

рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╕рдВрджрд░реНрдн рдкреГрд╖реНрда рдкрд░ рдЬрд╛рдПрдВ

рдЙрдкрдпреЛрдЧрд┐рддрд╛рдУрдВ

рдЫрд╡рд┐ рд╕рдВрдкреАрдбрд╝рди

рдПрдХ рдПрдХрд▓ рдЫрд╡рд┐ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдЙрд╕рдХреЗ рдкрд╣рд▓реВ рдЕрдиреБрдкрд╛рдд рдФрд░ рдЧреБрдгрд╡рддреНрддрд╛ рдХреЛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд░рддреЗ рд╣реБрдП рдХрдо рдЖрдХрд╛рд░ рдореЗрдВ рд╕рдВрдкреАрдбрд╝рд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЗрдирдкреБрдЯ рдЫрд╡рд┐ рдЕрдзрд┐рдХрддрдо рдЖрдпрд╛рдо рд╕реЗ рдЫреЛрдЯреА рд╣реИ, рддреЛ рдЗрд╕рдХрд╛ рдЖрдХрд╛рд░ рдирд╣реАрдВ рдмрджрд▓рд╛ рдЬрд╛рдПрдЧрд╛ред

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. рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдХреБрдЫ рднреА рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ

рдСрдЯреЛ-рд╕реНрдкреНрд▓рд┐рдЯ рдбреЗрдЯрд╛рд╕реЗрдЯ

рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░реЗрдВ train/val/test рд╡рд┐рднрд╛рдЬрди рдФрд░ рдкрд░рд┐рдгрд╛рдореА рд╡рд┐рднрд╛рдЬрди рдХреЛ autosplit_*.txt рдлрд╝рд╛рдЗрд▓реЗрдВред рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдирдореВрдирд╛рдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИ fraction рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рддрд░реНрдХ.

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. рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдХреБрдЫ рднреА рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ

рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдкрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП рд╕рдВрджрд░реНрдн рдкреГрд╖реНрда рджреЗрдЦреЗрдВред

рд╕реЗрдЧрдореЗрдВрдЯ-рдкреЙрд▓реАрдЧреЙрди рдЯреВ рдмрд╛рдЗрдирд░реА рдорд╛рд╕реНрдХ

рдПрдХ рдПрдХрд▓ рдмрд╣реБрднреБрдЬ (рд╕реВрдЪреА рдХреЗ рд░реВрдк рдореЗрдВ) рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЫрд╡рд┐ рдЖрдХрд╛рд░ рдХреЗ рдмрд╛рдЗрдирд░реА рдорд╛рд╕реНрдХ рдореЗрдВ рдХрдирд╡рд░реНрдЯ рдХрд░реЗрдВред рдмрд╣реБрднреБрдЬ рдХреЗ рд░реВрдк рдореЗрдВ [N, 2] рдХреЗ рд╕рд╛рде N рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд░реВрдк рдореЗрдВ (x, y) рдмрд╣реБрднреБрдЬ рд╕рдореЛрдЪреНрдЪ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдмрд┐рдВрджреБред

рдЪреЗрддрд╛рд╡рдиреА

N рд╣рдореЗрд╢рд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рд╕рдо рд╣реЛред

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
) 

рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕

рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ (рдХреНрд╖реИрддрд┐рдЬ) рдЙрджрд╛рд╣рд░рдг

рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рдбреЗрдЯрд╛ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, Bboxes рдХрдХреНрд╖рд╛ рдмреЙрдХреНрд╕ рд╕рдордиреНрд╡рдп рд╕реНрд╡рд░реВрдкрдг, рд╕реНрдХреЗрд▓ рдмреЙрдХреНрд╕ рдЖрдпрд╛рдо, рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреА рдЧрдгрдирд╛, рдСрдлрд╕реЗрдЯ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ, рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рдХреЗ рдмреАрдЪ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧреА!

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")
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]]
)

рджреЗрдЦреЗрдВ Bboxes рд╕рдВрджрд░реНрдн рдЕрдиреБрднрд╛рдЧ рдЕрдзрд┐рдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдФрд░ рдЙрдкрд▓рдмреНрдз рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдПред

рдиреЛрдХ

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдореЗрдВ рд╕реЗ рдХрдИ рдХрд╛рд░реНрдпреЛрдВ (рдФрд░ рдЕрдзрд┐рдХ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ Bboxes рдХрдХреНрд╖рд╛ рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рд╕реАрдзреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЗрдиреНрд╣реЗрдВ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдкрд░ рдЕрдЧрд▓реЗ рдЙрдкрдЦрдВрдб рджреЗрдЦреЗрдВред

рд╕реНрдХреЗрд▓рд┐рдВрдЧ рдмреЙрдХреНрд╕

рдЬрдм рд╕реНрдХреЗрд▓рд┐рдВрдЧ рдФрд░ рдЫрд╡рд┐ рдКрдкрд░ рдпрд╛ рдиреАрдЪреЗ, рдЗрд╕реА рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдЙрдЪрд┐рдд рд░реВрдк рд╕реЗ рдорд┐рд▓рд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдХреЗрд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ 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,
)

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. рдирдП рдЫрд╡рд┐ рдЖрдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рд╕реНрдХреЗрд▓ рдХрд┐рдП рдЧрдП

рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рд╕реНрд╡рд░реВрдк рд░реВрдкрд╛рдВрддрд░рдг

XYXY тЖТ XYWH

рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЛ (x1, y1, x2, y2) рдкреНрд░рд╛рд░реВрдк рд╕реЗ (x, y, рдЪреМрдбрд╝рд╛рдИ, рдКрдВрдЪрд╛рдИ) рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдХрдирд╡рд░реНрдЯ рдХрд░реЗрдВ рдЬрд╣рд╛рдВ (x1, y1) рдКрдкрд░реА-рдмрд╛рдПрдБ рдХреЛрдиреЗ рд╣реИ рдФрд░ (x2, y2) рдирд┐рдЪрд▓реЗ-рджрд╛рдПрдБ рдХреЛрдиреЗ рд╣реИрдВред

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)

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]]
)

рд╕рднреА рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рд░реВрдкрд╛рдВрддрд░рдг

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

рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП docstring рджреЗрдЦреЗрдВ рдпрд╛ ultralytics.utils.ops рд╕рдВрджрд░реНрдн рдкреГрд╖реНрда рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдПред

рдкреНрд▓реЙрдЯрд┐рдВрдЧ

рдбреНрд░рд╛рдЗрдВрдЧ рдПрдиреЛрдЯреЗрд╢рди

Ultralytics рдПрдХ рдПрдиреЛрдЯреЗрдЯрд░ рд╡рд░реНрдЧ рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдбреЗрдЯрд╛ рдХреЛ рдПрдиреЛрдЯреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдСрдмреНрдЬреЗрдХреНрдЯ рдбрд┐рдЯреЗрдХреНрд╢рди рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕, рдкреЛрдЬрд╝ рдХреА рдкреЙрдЗрдВрдЯреНрд╕ рдФрд░ рдУрд░рд┐рдПрдВрдЯреЗрдб рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рд╣реИред

рдХреНрд╖реИрддрд┐рдЬ рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕

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. рдирд╛рдореЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ model.names рдХрдм рдбрд┐рдЯреЗрдХреНрд╢рди рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдп рдХрд░рдирд╛

рдУрд░рд┐рдПрдВрдЯреЗрдб рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ (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"{names.get(int(c_idx))}"
    ann.box_label(
        obb,
        label,
        color=colors(c_idx, True),
        rotated=True,
    )

image_with_obb = ann.result()

рджреЗрдЦреЗрдВ Annotator рд╕рдВрджрд░реНрдн рдкреГрд╖реНрда рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдПред

рдлреБрдЯрдХрд░

рдХреЛрдб рдкреНрд░реЛрдлрд╛рдЗрд▓рд┐рдВрдЧ

рдпрд╛ рддреЛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЛрдб рдХреЛ рдЪрд▓рд╛рдиреЗ/рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд╡рдзрд┐ рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВ with рдпрд╛ рдПрдХ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВред

from ultralytics.utils.ops import Profile

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

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

Ultralytics рд╕рдорд░реНрдерд┐рдд рдкреНрд░рд╛рд░реВрдк

рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рдЫрд╡рд┐рдпреЛрдВ рдпрд╛ рд╡реАрдбрд┐рдпреЛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдкреНрд░рд╛рд░реВрдкреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ Ultralytics рдкреНрд░реЛрдЧреНрд░рд╛рдо? рдпрджрд┐ рдЖрдкрдХреЛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рддреЛ рдЗрди рд╕реНрдерд┐рд░рд╛рдВрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

from ultralytics.data.utils import IMG_FORMATS
from ultralytics.data.utils import VID_FORMATS

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

рд╡рд┐рднрд╛рдЬреНрдп рдмрдирд╛рдУ

рдирд┐рдХрдЯрддрдо рдкреВрд░реНрдг рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ x рджреНрд╡рд╛рд░рд╛ рд╡рд┐рднрд╛рдЬрд┐рдд рд╣реЛрдиреЗ рдкрд░ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рд╡рд┐рднрд╛рдЬреНрдп рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП y.

from ultralytics.utils.ops import make_divisible

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


рдмрдирд╛рдпрд╛ рдЧрдпрд╛ 2024-02-20, рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ 2024-05-08
рд▓реЗрдЦрдХ: рд░рд┐рдЬрд╡рд╛рди рдореБрдирд╡реНрд╡рд░ (1), рдЧреНрд▓реЗрди-рдЬреЛрдЪрд░ (3), рдмреБрд░рд╣рд╛рди-рдХреНрдпреВ (2)

рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ