간단한 유틸리티#
ultralytics 패키지는 워크플로를 지원, 강화 및 가속화하는 다양한 유틸리티를 제공합니다. 이 가이드에서는 사용 가능한 많은 유틸리티 중 개발자에게 가장 유용한 몇 가지를 강조하여 Ultralytics 도구 프로그래밍을 위한 실용적인 참고 자료를 제공합니다.
Watch: Ultralytics Utilities | Auto Annotation, Explorer API and Dataset Conversion
데이터#
자동 라벨링 / 주석#
데이터셋 주석은 자원이 많이 소모되고 시간이 오래 걸리는 작업입니다. 적당한 양의 데이터로 학습된 Ultralytics YOLO 객체 검출 모델이 있는 경우, 이를 SAM과 함께 사용하여 분할 형식으로 추가 데이터를 자동으로 주석 처리할 수 있습니다.
from ultralytics.data.annotator import auto_annotate
auto_annotate(
data="path/to/new/data",
det_model="yolo26n.pt",
sam_model="mobile_sam.pt",
device="cuda",
output_dir="path/to/save_labels",
)이 함수는 어떤 값도 반환하지 않습니다. 자세한 내용은 다음을 참조하세요:
- 함수 작동 방식에 대한 자세한 내용은
annotator.auto_annotate의 참조 섹션을 참조하세요. - 함수
segments2boxes과 함께 사용하여 객체 검출 바운딩 박스도 생성합니다.
데이터셋 어노테이션 시각화#
이 함수는 학습 전에 이미지에 YOLO 주석을 시각화하여, 잘못된 검출 결과로 이어질 수 있는 잘못된 주석을 식별하고 수정하는 데 도움을 줍니다. 바운딩 박스를 그리고, 클래스 이름으로 객체에 라벨을 지정하며, 가독성을 높이기 위해 배경 휘도에 따라 텍스트 색상을 조정합니다.
from ultralytics.data.utils import visualize_image_annotations
label_map = { # Define the label map with all annotated class labels.
0: "person",
1: "car",
}
# Visualize
visualize_image_annotations(
"path/to/image.jpg", # Input image path.
"path/to/annotations.txt", # Annotation file path for the image.
label_map,
)분할 마스크를 YOLO 형식으로 변환#

이를 사용하여 분할 마스크 이미지 데이터셋을 Ultralytics YOLO 분할 형식으로 변환합니다. 이 함수는 이진 형식 마스크 이미지가 포함된 디렉터리를 가져와서 YOLO 분할 형식으로 변환합니다.
변환된 마스크는 지정된 출력 디렉터리에 저장됩니다.
from ultralytics.data.converter import convert_segment_masks_to_yolo_seg
# The classes here is the total classes in the dataset.
# for COCO dataset we have 80 classes.
convert_segment_masks_to_yolo_seg(masks_dir="path/to/masks_dir", output_dir="path/to/output_dir", classes=80)COCO를 YOLO 형식으로 변환#
이를 사용하여 COCO JSON 주석을 YOLO 형식으로 변환합니다. 객체 검출(바운딩 박스) 데이터셋의 경우 use_segments과 use_keypoints를 모두 False(으)로 설정하세요.
from ultralytics.data.converter import convert_coco
convert_coco(
"coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)convert_coco 함수에 대한 추가 정보는 참조 페이지 방문을 확인하세요.
바운딩 박스 크기 가져오기#
import cv2
from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator
model = YOLO("yolo26n.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(f"Bounding Box Width {width.item()}, Height {height.item()}, Area {area.item()}")바운딩 박스를 세그먼트로 변환#
기존 x y w h 바운딩 박스 데이터를 사용하여 yolo_bbox2segment 함수로 세그먼트로 변환합니다. 이미지와 주석 파일은 다음과 같이 구성하세요:
data
|__ images
├─ 001.jpg
├─ 002.jpg
├─ ..
└─ NNN.jpg
|__ labels
├─ 001.txt
├─ 002.txt
├─ ..
└─ NNN.txtfrom ultralytics.data.converter import yolo_bbox2segment
yolo_bbox2segment(
im_dir="path/to/images",
save_dir=None, # saved to "labels-segment" in images directory
sam_model="sam_b.pt",
)함수에 대한 자세한 내용은 yolo_bbox2segment 참조 페이지를 방문하세요.
세그먼트를 바운딩 박스로 변환#
세그멘테이션 데이터셋 형식을 사용하는 데이터셋이 있는 경우, 이 함수를 사용하여 이를 수직(또는 수평) 바운딩 박스(x y w h 형식)로 쉽게 변환할 수 있습니다.
import numpy as np
from ultralytics.utils.ops import segments2boxes
segments = np.array(
[
[805, 392, 797, 400, 812, 402, 808, 714, 808, 392],
[115, 398, 113, 400, 150, 410, 150, 400, 149, 298],
[267, 412, 265, 413, 300, 420, 300, 413, 299, 412],
],
dtype=np.float32,
)
segments2boxes([s.reshape(-1, 2) for s in segments])
# >>> array([[804.5, 553. , 15. , 322. ],
# [131.5, 354. , 37. , 112. ],
# [282.5, 416. , 35. , 8. ]],
# dtype=float32) # xywh bounding boxes이 함수의 작동 방식을 이해하려면 참조 페이지를 방문하세요.
Utilities#
이미지 압축#
종횡비와 품질을 유지하면서 단일 이미지 파일의 크기를 줄여 압축합니다. 입력 이미지가 최대 크기보다 작으면 크기가 조정되지 않습니다.
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)데이터셋 자동 분할#
데이터셋을 train/val/test 분할로 자동 분할하고 결과 분할을 autosplit_*.txt 파일에 저장합니다. 이 유틸리티는 영구적인 분할 파일을 생성하며, fraction 학습 인수는 대신 실행을 위해 재현 가능한 서브셋을 선택합니다.
from ultralytics.data.split import autosplit
autosplit(
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
)이 함수에 대한 추가 표기 세부사항은 참조 페이지를 참조하세요.
세그먼트 폴리곤을 이진 마스크로 변환#
단일 폴리곤(목록 형태)을 지정된 이미지 크기의 이진 마스크로 변환합니다. 폴리곤은 폴리곤 윤곽선을 정의하는 교대 x, y 값을 나열하는 N 좌표의 평면 1차원 배열이어야 합니다.
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 클래스는 박스 좌표 형식 간 변환, 박스 크기 조절, 면적 계산, 오프셋 포함 등을 지원합니다.
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]]
# )더 많은 속성과 메서드에 대해서는 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,
)
print(new_boxes)
# >>> 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]]
# )바운딩 박스 형식 변환#
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)
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]]
# )모든 바운딩 박스 변환#
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각 함수의 독스트링을 확인하거나 ultralytics.utils.ops 참조 페이지를 방문하여 자세히 알아보세요.
플로팅#
주석 유틸리티#
Ultralytics에는 다양한 데이터 유형에 주석을 달기 위한 Annotator 클래스가 포함되어 있습니다. 객체 검출 바운딩 박스, 포즈 키포인트, 지향성 바운딩 박스와 함께 사용할 때 가장 효과적입니다.
박스 주석#
import cv2 as cv
import numpy as np
from ultralytics.utils.plotting import Annotator, colors
names = {
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()검출 결과 작업 시 model.names의 이름을 사용할 수 있습니다.
추가적인 통찰을 위해 Annotator 참조 페이지도 참조하세요.
Ultralytics 스윕 주석#
import sys
import cv2
import numpy as np
from ultralytics import YOLO
from ultralytics.solutions.solutions import SolutionAnnotator
from ultralytics.utils.plotting import colors
# User defined video path and model file
cap = cv2.VideoCapture("path/to/video.mp4")
model = YOLO(model="yolo26s-seg.pt") # Model file, e.g., yolo26s.pt or yolo26m-seg.pt
if not cap.isOpened():
print("Error: Could not open video.")
sys.exit()
# Initialize the video writer object.
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
video_writer = cv2.VideoWriter("ultralytics.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
masks = None # Initialize variable to store masks data
f = 0 # Initialize frame count variable for enabling mouse event.
line_x = w # Store width of line.
dragging = False # Initialize bool variable for line dragging.
classes = model.names # Store model classes names for plotting.
window_name = "Ultralytics Sweep Annotator"
def drag_line(event, x, _, flags, param):
"""Mouse callback function to enable dragging a vertical sweep line across the video frame."""
global line_x, dragging
if event == cv2.EVENT_LBUTTONDOWN or (flags & cv2.EVENT_FLAG_LBUTTON):
line_x = max(0, min(x, w))
dragging = True
while cap.isOpened(): # Loop over the video capture object.
ret, im0 = cap.read()
if not ret:
break
f = f + 1 # Increment frame count.
count = 0 # Re-initialize count variable on every frame for precise counts.
results = model.track(im0, persist=True)[0]
if f == 1:
cv2.namedWindow(window_name)
cv2.setMouseCallback(window_name, drag_line)
annotator = SolutionAnnotator(im0)
if results.boxes.is_track:
if results.masks is not None:
masks = [np.array(m, dtype=np.int32) for m in results.masks.xy]
boxes = results.boxes.xyxy.tolist()
track_ids = results.boxes.id.int().cpu().tolist()
clss = results.boxes.cls.cpu().tolist()
for mask, box, cls, t_id in zip(masks or [None] * len(boxes), boxes, clss, track_ids):
color = colors(t_id, True) # Assign different color to each tracked object.
label = f"{classes[cls]}:{t_id}"
if mask is not None and mask.size > 0:
if box[0] > line_x:
count += 1
cv2.polylines(im0, [mask], True, color, 2)
x, y = mask.min(axis=0)
(w_m, _), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
cv2.rectangle(im0, (x, y - 20), (x + w_m, y), color, -1)
cv2.putText(im0, label, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
else:
if box[0] > line_x:
count += 1
annotator.box_label(box=box, color=color, label=label)
# Generate draggable sweep line
annotator.sweep_annotator(line_x=line_x, line_y=h, label=f"COUNT:{count}")
cv2.imshow(window_name, im0)
video_writer.write(im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
# Release the resources
cap.release()
video_writer.release()
cv2.destroyAllWindows()sweep_annotator 방법에 대한 추가 세부사항은 여기 참조 섹션에서 찾을 수 있습니다.
어댑티브 라벨 주석#
SolutionAnnotator.adaptive_label는 shape 인수로 선택한 형태의 레이블을 그립니다(기존의 circle_label 및 text_label 메서드를 대체합니다):
- 직사각형:
annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="rect") - 원형:
annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="circle")
Watch: In-Depth Guide to Text & Circle Annotations with Python Live Demos | Ultralytics Annotations 🚀
import cv2
from ultralytics import YOLO
from ultralytics.solutions.solutions import SolutionAnnotator
from ultralytics.utils.plotting import colors
model = YOLO("yolo26s.pt")
names = model.names
cap = cv2.VideoCapture("path/to/video.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 = SolutionAnnotator(im0)
results = model.predict(im0)[0]
boxes = results.boxes.xyxy.cpu()
clss = results.boxes.cls.cpu().tolist()
for box, cls in zip(boxes, clss):
annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="circle")
writer.write(im0)
cv2.imshow("Ultralytics circle annotation", im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
writer.release()
cap.release()
cv2.destroyAllWindows()추가적인 통찰을 위해 SolutionAnnotator 참조 페이지를 참조하세요.
기타#
코드 프로파일링#
with을 사용하거나 데코레이터로 사용하여 코드가 실행/처리되는 소요 시간을 확인합니다.
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 지원 형식#
Ultralytics에서 지원되는 이미지 또는 비디오 형식을 프로그래밍 방식으로 사용해야 합니까? 필요한 경우 다음 상수를 사용하세요:
from ultralytics.data.utils import IMG_FORMATS, VID_FORMATS
print(IMG_FORMATS)
# {'avif', 'bmp', 'dng', 'heic', 'heif', 'jp2', 'jpeg', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp'}
print(VID_FORMATS)
# {'asf', 'avi', 'gif', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'ts', 'wmv', 'webm'}배수로 만들기#
y(으)로 나누어 떨어지는 x보다 크거나 같은 가장 작은 정수를 계산합니다.
from ultralytics.utils.ops import make_divisible
make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8FAQ#
Ultralytics 패키지에는 머신러닝 워크플로를 간소화하고 최적화하도록 설계된 유틸리티가 포함되어 있습니다. 주요 유틸리티에는 데이터셋 라벨링을 위한 자동 주석, convert_coco를 사용한 COCO의 YOLO 형식 변환, 이미지 압축, 데이터셋 자동 분할이 포함됩니다. 이러한 도구는 수동 노력을 줄이고, 일관성을 보장하며, 데이터 처리 효율성을 향상시킵니다.
사전 학습된 Ultralytics YOLO 객체 검출 모델이 있는 경우, SAM 모델과 함께 사용하여 분할 형식으로 데이터셋에 자동으로 주석을 달 수 있습니다. 다음은 예시입니다:
from ultralytics.data.annotator import auto_annotate auto_annotate( data="path/to/new/data", det_model="yolo26n.pt", sam_model="mobile_sam.pt", device="cuda", output_dir="path/to/save_labels", )자세한 내용은 auto_annotate reference section을 확인하시거나, SAM 2.1, SAM 3 또는 SAM 3.1을 통한 클릭 기반 마스킹 기능과 탐지(detect), 분할(segment), 방향 바운딩 박스(OBB) 작업을 위한 사전 학습 및 미세 조정된 YOLO 모델의 예측 기능을 제공하는 호스팅된 노코드 대안으로 Ultralytics Platform을 사용해 주시기 바랍니다.
객체 검출을 위해 COCO JSON 주석을 YOLO 형식으로 변환하려면
convert_coco유틸리티를 사용할 수 있습니다. 다음은 샘플 코드 스니펫입니다:from ultralytics.data.converter import convert_coco convert_coco( "coco/annotations/", use_segments=False, use_keypoints=False, cls91to80=True, )추가 정보는 convert_coco 참조 페이지를 방문하세요.
Ultralytics Platform은 자동 데이터셋 분석을 제공합니다.
Charts탭은 분할 분포, 상위 클래스 수, 이미지 치수 히스토그램, 주석 위치의 2D 히트맵을 보여주어 학습 전에 불균형과 이상치를 파악하는 데 도움을 줍니다.기존 바운딩 박스 데이터(
x y w h형식)를 세그먼트로 변환하려면yolo_bbox2segment함수를 사용할 수 있습니다. 이미지와 라벨을 위한 별도의 디렉터리로 파일이 구성되어 있는지 확인하세요.from ultralytics.data.converter import yolo_bbox2segment yolo_bbox2segment( im_dir="path/to/images", save_dir=None, # saved to "labels-segment" in the images directory sam_model="sam_b.pt", )자세한 내용은 yolo_bbox2segment 참조 페이지를 방문하세요.