シンプルなユーティリティ
について ultralytics
パッケージには、あなたのワークフローをサポートし、強化し、高速化する無数のユーティリティが付属している。利用可能なものは他にもたくさんあるが、ここではほとんどの開発者にとって有用なものをいくつか紹介しよう。また、プログラミングを学ぶ際の参考にもなります。
見るんだ: Ultralytics ユーティリティ|オートアノテーション、エクスプローラAPI、データセット変換
データ
オートラベリング / 注釈
データセットのアノテーションは非常にリソースを消費し、時間のかかるプロセスである。妥当な量のデータに対してトレーニングされた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",
)
This function does not return any value. For further details on how the function operates:
- については、参考文献のセクションを参照のこと。
annotator.auto_annotate
をご覧ください。 - と組み合わせて使用する。 機能
segments2boxes
オブジェクト検出バウンディングボックスも生成する
Visualize Dataset Annotations
This function visualizes YOLO annotations on an image before training, helping to identify and correct any wrong annotations that could lead to incorrect detection results. It draws bounding boxes, labels objects with class names, and adjusts text color based on the background's luminance for better readability.
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 形式に変換する。
セグメンテーション・マスク画像のデータセットを 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
この機能がどのように働くかを理解するには、リファレンスページをご覧ください。
ユーティリティ
画像圧縮
アスペクト比と画質を保持したまま、1つの画像ファイルを縮小して圧縮します。入力画像が最大寸法より小さい場合、リサイズされません。
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, 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
各関数のdocstringを参照するか、または 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()
バウンディング・ボックス サークル・アノテーションサークル・ラベル
見るんだ: テキスト&サークル注釈の徹底ガイド(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",
)
詳細については、auto_annotateのリファレンスセクションを参照してください。
Ultralytics 、COCOデータセットの注釈を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 Data Explorer の目的は何ですか?
について 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のリファレンスページをご覧ください。