κ°λ¨ν μ νΈλ¦¬ν°
κ·Έλ¦¬κ³ ultralytics
ν¨ν€μ§μλ μν¬νλ‘λ₯Ό μ§μ, ν₯μ λ° μλλ₯Ό λμΌ μ μλ μλ§μ μ νΈλ¦¬ν°κ° ν¬ν¨λμ΄ μμ΅λλ€. λ λ§μ μ νΈλ¦¬ν°κ° μμ§λ§ μ¬κΈ°μλ λλΆλΆμ κ°λ°μμκ² μ μ©ν λͺ κ°μ§λ₯Ό μκ°ν©λλ€. λν νλ‘κ·Έλλ°μ λ°°μΈ λ μ°Έκ³ ν μ μλ νλ₯ν μ°Έκ³ μλ£μ΄κΈ°λ ν©λλ€.
Watch: Ultralytics μ νΈλ¦¬ν° > μλ μ£Όμ, νμκΈ° API λ° λ°μ΄ν° μΈνΈ λ³ν
λ°μ΄ν°
μλ λΌλ²¨λ§/μ£Όμ
λ°μ΄ν° μΈνΈ μ΄λ Έν μ΄μ μ 리μμ€μ μκ°μ΄ λ§μ΄ μμλλ νλ‘μΈμ€μ λλ€. μ μ ν μμ λ°μ΄ν°λ‘ νμ΅λ YOLO κ°μ²΄ κ°μ§ λͺ¨λΈμ΄ μλ κ²½μ°, μ΄λ₯Ό μ¬μ©νκ³ SAM λ₯Ό μ¬μ©νμ¬ μΆκ° λ°μ΄ν°(μΈλΆν νμ)μ μλ μ£Όμμ λ¬ μ μμ΅λλ€.
from ultralytics.data.annotator import auto_annotate
auto_annotate( # (1)!
data="path/to/new/data",
det_model="yolo11n.pt",
sam_model="mobile_sam.pt",
device="cuda",
output_dir="path/to/save_labels",
)
-
μ΄ ν¨μμμ λ°νλλ κ²μ μμ΅λλ€.
-
λ€μμ λν μ°Έμ‘° μΉμ μ μ°Έμ‘°νμμμ€.
annotator.auto_annotate
λ₯Ό μ°Έμ‘°νμ¬ κΈ°λ₯ μλ λ°©μμ λν΄ μμΈν μμ보μΈμ. -
μ ν¨κ» μ¬μ© ν¨μ
segments2boxes
λ₯Ό μ¬μ©νμ¬ κ°μ²΄ κ°μ§ κ²½κ³ μμλ μμ±ν μ μμ΅λλ€.
μΈλΆν λ§μ€ν¬λ₯Ό YOLO νμμΌλ‘ λ³ν
μΈλΆν λ§μ€ν¬ μ΄λ―Έμ§μ λ°μ΄ν° μΈνΈλ₯Ό 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( # (1)!
"../datasets/coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)
- μ΄ ν¨μμμ λ°νλλ κ²μ μμ΅λλ€.
μ λν μμΈν λ΄μ©μ convert_coco
ν¨μμ
λλ€, μ°Έμ‘° νμ΄μ§ λ°©λ¬Έ
λ°μ΄λ© λ°μ€ μΉμ κ°μ Έμ€κΈ°
from ultralytics.utils.plotting import Annotator
from ultralytics import YOLO
import cv2
model = YOLO('yolo11n.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",
)
- μ΄ ν¨μμμ λ°νλλ κ²μ μμ΅λλ€.
λ°©λ¬ΈνκΈ° yolo_bbox2segment
μ°Έμ‘° νμ΄μ§ κΈ°λ₯μ λν μμΈν λ΄μ©μ νμΈνμΈμ.
μΈκ·Έλ¨ΌνΈλ₯Ό λ°μ΄λ© λ°μ€λ‘ λ³ννκΈ°
λ₯Ό μ¬μ©νλ λ°μ΄ν° μ§ν©μ΄ μλ κ²½μ° μΈλΆν λ°μ΄ν° μΈνΈ νμ λ₯Ό μ¬μ©νλ©΄ μ½κ² μμ§(λλ μν) κ²½κ³ μμλ‘ λ³νν μ μμ΅λλ€(x y w h
νμ)μ μ¬μ©νμ¬ μ΄ ν¨μλ₯Ό μ¬μ©ν μ μμ΅λλ€.
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
μ΄ κΈ°λ₯μ μλ λ°©μμ μ΄ν΄νλ €λ©΄ μ°Έμ‘° νμ΄μ§λ₯Ό λ°©λ¬ΈνμΈμ.
μ νΈλ¦¬ν°
μ΄λ―Έμ§ μμΆ
κ°λ‘ μΈλ‘ λΉμ¨κ³Ό νμ§μ μ μ§νλ©΄μ λ¨μΌ μ΄λ―Έμ§ νμΌμ μΆμλ ν¬κΈ°λ‘ μμΆν©λλ€. μ λ ₯ μ΄λ―Έμ§κ° μ΅λ ν¬κΈ°λ³΄λ€ μμΌλ©΄ ν¬κΈ°κ° μ‘°μ λμ§ μμ΅λλ€.
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)!
- μ΄ ν¨μμμ λ°νλλ κ²μ μμ΅λλ€.
λ°μ΄ν° μΈνΈ μλ λΆν
λ°μ΄ν° μ§ν©μ λ€μκ³Ό κ°μ΄ μλμΌλ‘ λΆν ν©λλ€. 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
)
- μ΄ ν¨μμμ λ°νλλ κ²μ μμ΅λλ€.
μ΄ κΈ°λ₯μ λν μμΈν λ΄μ©μ μ°Έμ‘° νμ΄μ§λ₯Ό μ°Έμ‘°νμΈμ.
μΈκ·Έλ¨ΌνΈ λ€κ°νμ λ°μ΄λ리 λ§μ€ν¬λ‘ λ³ννκΈ°
λ¨μΌ λ€κ°ν(λͺ©λ‘)μ μ§μ λ μ΄λ―Έμ§ ν¬κΈ°μ μ΄μ§ λ§μ€ν¬λ‘ λ³νν©λλ€. λ€μκ³Ό κ°μ ννμ λ€κ°ν [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
ν΄λμ€λ μμ μ’ν μμ λ³ν, μμ ν¬κΈ° μ‘°μ , λ©΄μ κ³μ°, μ€νμ
ν¬ν¨ λ±μ μμ
μ λμμ€λλ€!
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) # (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]]
# )
- μ μ΄λ―Έμ§ ν¬κΈ°μ λ§κ² ν¬κΈ°κ° μ‘°μ λ λ°μ΄λ© λ°μ€
λ°μ΄λ© λ°μ€ νμ λ³ν
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)
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 ν΄λμ€κ° ν¬ν¨λμ΄ μμ΅λλ€. κ°μ²΄ κ°μ§ λ°μ΄λ© λ°μ€, ν¬μ¦ ν€ ν¬μΈνΈ, λ°©ν₯μ± λ°μ΄λ© λ°μ€μ κ°μ₯ μ½κ² μ¬μ©ν μ μμ΅λλ€.
Ultralytics μ€μ μ£Όμ
Python YOLO11 π μ¬μ© μ
import cv2
from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator, colors
# User defined video path and model file
cap = cv2.VideoCapture("Path/to/video/file.mp4")
model = YOLO(model="yolo11s-seg.pt") # Model file i.e. yolo11s.pt or yolo11m-seg.pt
if not cap.isOpened():
print("Error: Could not open video.")
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, y, flags, param): # Mouse callback for dragging line.
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.
annotator = Annotator(im0)
results = model.track(im0, persist=True) # Track objects using track method.
if f == 1:
cv2.namedWindow(window_name)
cv2.setMouseCallback(window_name, drag_line)
if results[0].boxes.id is not None:
if results[0].masks is not None:
masks = results[0].masks.xy
track_ids = results[0].boxes.id.int().cpu().tolist()
clss = results[0].boxes.cls.cpu().tolist()
boxes = results[0].boxes.xyxy.cpu()
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.
if mask is not None and mask.size > 0:
# If you want to overlay the masks
# mask[:, 0] = np.clip(mask[:, 0], line_x, w)
# mask_img = cv2.fillPoly(im0.copy(), [mask.astype(int)], color)
# cv2.addWeighted(mask_img, 0.5, im0, 0.5, 0, im0)
if box[0] > line_x:
count += 1
annotator.seg_bbox(mask=mask, mask_color=color, label=str(classes[cls]))
else:
if box[0] > line_x:
count += 1
annotator.box_label(box=box, color=color, label=str(classes[cls]))
annotator.sweep_annotator(line_x=line_x, line_y=h, label=f"COUNT:{count}") # Display the sweep
cv2.imshow(window_name, im0)
video_writer.write(im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release() # Release the video capture.
video_writer.release() # Release the video writer.
cv2.destroyAllWindows() # Destroy all opened windows.
μν λ°μ΄λ© λ°μ€
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()
- μ΄λ¦μ λ€μμμ μ¬μ©ν μ μμ΅λλ€.
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"{obb_names.get(int(c_idx))}"
ann.box_label(
obb,
label,
color=colors(c_idx, True),
rotated=True,
)
image_with_obb = ann.result()
λ°μ΄λ© μμ μ μ£Όμ μ λ μ΄λΈ
Watch: ν
μ€νΈ λ° μ μ£Όμμ λν μ¬μΈ΅ κ°μ΄λ( Python λΌμ΄λΈ λ°λͺ¨ ν¬ν¨) | Ultralytics μ£Όμ π
import cv2
from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator
model = YOLO("yolo11s.pt")
names = model.names
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)
results = model.predict(im0)
boxes = results[0].boxes.xyxy.cpu()
clss = results[0].boxes.cls.cpu().tolist()
for box, cls in zip(boxes, clss):
annotator.circle_label(box, label=names[int(cls)])
writer.write(im0)
cv2.imshow("Ultralytics circle annotation", im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
writer.release()
cap.release()
cv2.destroyAllWindows()
λ°μ΄λ© λ°μ€ ν μ€νΈ μ£Όμ ν μ€νΈ λ μ΄λΈ
import cv2
from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator
model = YOLO("yolo11s.pt")
names = model.names
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)
results = model.predict(im0)
boxes = results[0].boxes.xyxy.cpu()
clss = results[0].boxes.cls.cpu().tolist()
for box, cls in zip(boxes, clss):
annotator.text_label(box, label=names[int(cls)])
writer.write(im0)
cv2.imshow("Ultralytics text annotation", im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
writer.release()
cap.release()
cv2.destroyAllWindows()
μ°Έμ‘° Annotator
μ°Έμ‘° νμ΄μ§ λ₯Ό μ°Έμ‘°νμΈμ.
κΈ°ν
μ½λ νλ‘νμΌλ§
λ€μμ μ¬μ©νμ¬ μ€ν/μ²λ¦¬ν μ½λμ κΈ°κ°μ νμΈν©λλ€. 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)
# {'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'}
λΆν κ°λ₯ λ§λ€κΈ°
μ κ°μ₯ κ°κΉμ΄ μ μλ₯Ό κ³μ°ν©λλ€. x
λ‘ λλ λ κ· λ±νκ² λλ μ μλλ‘ ν©λλ€. y
.
from ultralytics.utils.ops import make_divisible
make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8
μμ£Ό 묻λ μ§λ¬Έ
λ¨Έμ λ¬λ μν¬νλ‘μ°λ₯Ό κ°μ νκΈ° μν΄ Ultralytics ν¨ν€μ§μ ν¬ν¨λ μ νΈλ¦¬ν°μλ μ΄λ€ κ²μ΄ μλμ?
Ultralytics ν¨ν€μ§μλ λ¨Έμ λ¬λ μν¬νλ‘μ°λ₯Ό κ°μννκ³ μ΅μ ννλλ‘ μ€κ³λ λ€μν μ νΈλ¦¬ν°κ° ν¬ν¨λμ΄ μμ΅λλ€. μ£Όμ μ νΈλ¦¬ν°μλ λ°μ΄ν° μΈνΈμ λΌλ²¨μ λΆμ΄λ μλ μ£Όμ, convert_cocoλ₯Ό μ¬μ©ν΄ COCOλ₯Ό YOLO νμμΌλ‘ λ³ννλ κΈ°λ₯, μ΄λ―Έμ§ μμΆ, λ°μ΄ν° μΈνΈ μλ λΆν λ±μ΄ μμ΅λλ€. μ΄λ¬ν λꡬλ μμμ μ μ€μ΄κ³ , μΌκ΄μ±μ 보μ₯νλ©°, λ°μ΄ν° μ²λ¦¬ ν¨μ¨μ±μ ν₯μμν€λ κ²μ λͺ©νλ‘ ν©λλ€.
Ultralytics μ μ¬μ©νμ¬ λ°μ΄ν° μ§ν©μ μλ λ μ΄λΈμ μ§μ νλ €λ©΄ μ΄λ»κ² ν΄μΌ νλμ?
μ¬μ νμ΅λ Ultralytics YOLO κ°μ²΄ κ°μ§ λͺ¨λΈμ΄ μλ κ²½μ°, μ΄λ₯Ό μΈκ·Έλ¨ΌνΈ νμμ SAM λͺ¨λΈκ³Ό ν¨κ» μ¬μ©νμ¬ λ°μ΄ν° μΈνΈμ μΈλΆν νμμΌλ‘ μλ μ£Όμμ λ¬ μ μμ΅λλ€. λ€μμ μμμ λλ€:
from ultralytics.data.annotator import auto_annotate
auto_annotate(
data="path/to/new/data",
det_model="yolo11n.pt",
sam_model="mobile_sam.pt",
device="cuda",
output_dir="path/to/save_labels",
)
μμΈν λ΄μ©μ μλ μ£Όμ λ¬κΈ° μ°Έμ‘° μΉμ μ νμΈνμΈμ.
COCO λ°μ΄ν° μΈνΈ μ£Όμμ Ultralytics μμ YOLO νμμΌλ‘ λ³ννλ €λ©΄ μ΄λ»κ² νλμ?
COCO JSON μ΄λ
Έν
μ΄μ
μ κ°μ²΄ κ°μ§λ₯Ό μν΄ YOLO νμμΌλ‘ λ³ννλ €λ©΄ convert_coco
μ νΈλ¦¬ν°λ₯Ό μ¬μ©νμΈμ. λ€μμ μν μ½λ μ€λν«μ
λλ€:
from ultralytics.data.converter import convert_coco
convert_coco(
"../datasets/coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)
μμΈν λ΄μ©μ convert_coco μ°Έμ‘° νμ΄μ§λ₯Ό μ°Έμ‘°νμΈμ.
Ultralytics ν¨ν€μ§μ YOLO λ°μ΄ν° νμκΈ°μ μ©λλ 무μμΈκ°μ?
κ·Έλ¦¬κ³ YOLO νμκΈ° μ μκ°λ κ°λ ₯ν λꡬμ
λλ€. 8.1.0
λ°μ΄ν° μΈνΈ μ΄ν΄λλ₯Ό λμ΄κΈ° μν μ
λ°μ΄νΈμ
λλ€. ν
μ€νΈ 쿼리λ₯Ό μ¬μ©ν΄ λ°μ΄ν° μΈνΈμμ κ°μ²΄ μΈμ€ν΄μ€λ₯Ό μ°Ύμ μ μμΌλ―λ‘ λ°μ΄ν°λ₯Ό λ μ½κ² λΆμνκ³ κ΄λ¦¬ν μ μμ΅λλ€. μ΄ λꡬλ λ°μ΄ν° μΈνΈ ꡬμ±κ³Ό λΆν¬μ λν κ·μ€ν μΈμ¬μ΄νΈλ₯Ό μ 곡νμ¬ λͺ¨λΈ νλ ¨κ³Ό μ±λ₯μ κ°μ νλ λ° λμμ΄ λ©λλ€.
Ultralytics μμ λ°μ΄λ© λ°μ€λ₯Ό μΈκ·Έλ¨ΌνΈλ‘ λ³ννλ €λ©΄ μ΄λ»κ² ν΄μΌ νλμ?
κΈ°μ‘΄ λ°μ΄λ© λ°μ€ λ°μ΄ν°λ₯Ό λ³ννλ €λ©΄( 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 μ°Έμ‘° νμ΄μ§λ₯Ό μ°Έμ‘°νμΈμ.