الأدوات البسيطة#
توفر حزمة 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لمعرفة المزيد حول كيفية عمل الدالة. - استخدمها بالkاتصال مع الدالة
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لفهم كيفية عمل هذه الدالة، تفضل بزيارة صفحة المراجع.
الأدوات المساعدة#
ضغط الصور#
ضغط ملف صورة واحد إلى حجم أصغر مع الحفاظ على نسبة العرض إلى الارتفاع والجودة. إذا كانت الصورة المدخلة أصغر من البعد الأقصى، فلن يتم تغيير حجمها.
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
)راجع صفحة المراجع للحصول على تفاصيل إضافية حول هذه الدالة.
تجزئة المضلع إلى قناع ثنائي#
تحويل مضلع واحد (كقائمة) إلى قناع ثنائي لحجم الصورة المحدد. يجب أن يكون المضلع مصفوفة أحادية الأبعاد مسطحة لإحداثيات 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)
# >>> 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 أو كمزيّن (decorator).
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'}جعل الرقم قابلاً للقسمة#
احسب أصغر عدد صحيح أكبر من أو يساوي x والذي يقبل القسمة بالتساوي على y.
from ultralytics.utils.ops import make_divisible
make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8الأسئلة الشائعة#
تتضمن حزمة Ultralytics أدوات مصممة لتبسيط وتحسين سير عمل تعلم الآلة. تشمل الأدوات الرئيسية التعليقات التوضيحية التلقائية لتسمية مجموعات البيانات، وتحويل COCO إلى تنسيق YOLO باستخدام convert_coco، وضغط الصور، والتقسيم التلقائي لمجموعات البيانات. تقلل هذه الأدوات من الجهد اليدوي، وتضمن الاتساق، وتحسن كفاءة معالجة البيانات.
إذا كان لديك نموذج اكتشاف كائنات 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، أو استخدم منصة Ultralytics كبديل مستضاف بدون برمجة مع إخفاء يعتمد على النقر عبر SAM 2.1، أو SAM 3، أو SAM 3.1، أو التنبؤات من نماذج YOLO المُدربة مسبقاً والمُعدلة بدقة لمهام الكشف والتجزئة و OBB.
لتحويل تعليقات 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 تحليلات تلقائية لمجموعة البيانات: تعرض علامة التبويب
Chartsتوزيع التقسيم، وأعلى عدادات للفئات، ومخططات توزيع أبعاد الصور، وخرائط الحرارة ثنائية الأبعاد لمواضع التعليقات التوضيحية، مما يساعدك على اكتشاف حالات عدم التوازن والقيم المتطرفة قبل التدريب.لتحويل بيانات مربعات الإحاطة الحالية (بتنسيق
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.