ΠŸΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΊ содСрТимому

ΠŸΡ€ΠΎΡΡ‚Ρ‹Π΅ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹

ΠΊΠΎΠ΄ с пСрспСктивой

The ultralytics ΠŸΠ°ΠΊΠ΅Ρ‚ поставляСтся с ΠΎΠ³Ρ€ΠΎΠΌΠ½Ρ‹ΠΌ количСством ΡƒΡ‚ΠΈΠ»ΠΈΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ, ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ ΠΈ ΡƒΡΠΊΠΎΡ€ΠΈΡ‚ΡŒ Ρ‚Π²ΠΎΠΈ Ρ€Π°Π±ΠΎΡ‡ΠΈΠ΅ процСссы. Π˜Ρ… ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π³ΠΎΡ€Π°Π·Π΄ΠΎ большС, Π½ΠΎ Π²ΠΎΡ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ пригодятся Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Ρƒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ². Они Ρ‚Π°ΠΊΠΆΠ΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹ΠΌ ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠΌ ΠΏΡ€ΠΈ ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ.



Π‘ΠΌΠΎΡ‚Ρ€ΠΈ: Ultralytics Π£Ρ‚ΠΈΠ»ΠΈΡ‚Ρ‹ | АвтоматичСская аннотация, API ΠΏΡ€ΠΎΠ²ΠΎΠ΄Π½ΠΈΠΊΠ° ΠΈ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π°Π±ΠΎΡ€ΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ…

Π”Π°Π½Π½Ρ‹Π΅

YOLO ΠŸΡ€ΠΎΠ²ΠΎΠ΄Π½ΠΈΠΊ Π΄Π°Π½Π½Ρ‹Ρ…

YOLO Π˜ΡΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π±Ρ‹Π» Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ Π² 8.1.0 юбилСйного обновлСния ΠΈ являСтся ΠΌΠΎΡ‰Π½Ρ‹ΠΌ инструмСнтом, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ‚Ρ‹ моТСшь ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠΎΠ½ΡΡ‚ΡŒ свой Π½Π°Π±ΠΎΡ€ Π΄Π°Π½Π½Ρ‹Ρ…. Одна ΠΈΠ· ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ прСдоставляСт YOLO Explorer, - это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ тСкстовыС запросы для поиска экзСмпляров ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² Ρ‚Π²ΠΎΠ΅ΠΌ Π½Π°Π±ΠΎΡ€Π΅ Π΄Π°Π½Π½Ρ‹Ρ….

АвтоматичСская ΠΌΠ°Ρ€ΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° / Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ

АннотированиС массивов Π΄Π°Π½Π½Ρ‹Ρ… - ΠΎΡ‡Π΅Π½ΡŒ рСсурсоСмкий ΠΈ Ρ‚Ρ€ΡƒΠ΄ΠΎΠ΅ΠΌΠΊΠΈΠΉ процСсс. Если Ρƒ тСбя Π΅ΡΡ‚ΡŒ модСль обнаруТСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² 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 . Для Π½Π°Π±ΠΎΡ€ΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΡŽ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² (bounding box), 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
) 

ΠžΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ€Π°ΠΌΠΊΠΈ

ЭкзСмпляры Bounding Box (Π³ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΡŒΠ½Ρ‹Π΅)

Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ€Π°ΠΌΠΎΠΊ, Π½ΡƒΠΆΠ½ΠΎ 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, width, height), Π³Π΄Π΅ (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 Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ класс Annotator, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для аннотирования Π»ΡŽΠ±Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…. ΠŸΡ€ΠΎΡ‰Π΅ всСго ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ с ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ Ρ€Π°ΠΌΠΊΠ°ΠΌΠΈ для обнаруТСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹ΠΌΠΈ Ρ‚ΠΎΡ‡ΠΊΠ°ΠΌΠΈ ΠΏΠΎΠ·Ρ‹ ΠΈ ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌΠΈ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ Ρ€Π°ΠΌΠΊΠ°ΠΌΠΈ.

Π“ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ€Π°ΠΌΠΊΠΈ

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
Авторы: RizwanMunawar (1), glenn-jocher (3), Burhan-Q (2)

ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ