Ultralytics YOLO27: انضم إلى قائمة الانتظار.
Get Started
درّب أول نموذج YOLO لديك·النشر·الدرس 9/10
الدرسمبتدئ

تشغيل الاستدلال على الفيديو

شغّل YOLO26 على ملفات الفيديو والكاميرات المباشرة مع ذاكرة محدودة، وتتبع الأجسام لاحتساب كل جسم مرة واحدة، وتحقق من أن النموذج يواكب معدل الإطارات.

تعتمد معظم أنظمة الرؤية المنشورة على الفيديو: كاميرات فوق السيور الناقلة والأبواب والطرق. يضيف الفيديو مشكلتين لا تظهران في الصور المفردة. الذاكرة: لا يمكن الاحتفاظ بتسجيل طويل في RAM. الهوية: يرصد الكاشف الشخص نفسه في 60 إطارًا ويبلّغ عن 60 شخصًا.

في هذا الدرس، ستبث الفيديو إطارًا بإطار باستخدام وضع التنبؤ، وتضيف تتبع الأجسام لاحتساب كل شخص مرة واحدة، وتكتب حلقة الكاميرا الخاصة بك، وتقيس ما إذا كان النموذج يواكب سرعة المعالجة.

النتيجة

يمكنك بث فيديو أو كاميرا عبر YOLO26 بذاكرة محدودة، واحتساب الأجسام الفريدة باستخدام التتبع، وتحديد ما إذا كان النموذج يواكب المصدر استنادًا إلى الوقت المقاس بالميلي ثانية لكل إطار.

المسار السريع
إذا كنت تعرف الأساسيات بالفعل، فإليك النسخة المختصرة.
  1. ينتج model(video, stream=True) قيمة Results واحدة لكل إطار مع ذاكرة محدودة.

  2. يضيف model.track(video, stream=True, persist=True, tracker='bytetrack.yaml') boxes.id.

  3. احتسب الأجسام الفريدة باستخدام مجموعة من المعرّفات، ولا تعتمد أبدًا على أعلى معرّف.

  4. الميزانية = 1000 ÷ معدل إطارات المصدر؛ قارنها بـresult.speed['inference'].

عملي

مثال تطبيقي: التنبؤ على ملف فيديو#

تُعالج مقاطع الفيديو باستخدام وضع التنبؤ نفسه المستخدم للصور. يعرض هذا المقطع، المؤلف من 62 إطارًا، أشخاصًا يعبرون ردهة:

yolo predict model=yolo26n.pt source=https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4
video 1/1 (frame 1/62) solutions_ci_demo.mp4: 384x640 22 persons, 27.3ms
...
video 1/1 (frame 62/62) solutions_ci_demo.mp4: 384x640 22 persons, 54.8ms
Results saved to runs/detect/predict
  • frame 1/62: يفك Ultralytics ترميز الفيديو ويعالج كل إطار كما لو كان صورة.
  • 22 persons: عمليات الكشف في ذلك الإطار. يُحتسب المشاة أنفسهم مجددًا في كل إطار.
  • 27.3ms ... 54.8ms: يختلف الزمن لكل إطار بحسب المهام الأخرى التي ينفذها الجهاز.

الفيديو المشروح هو runs/detect/predict/solutions_ci_demo.mp4. يعمل نموذجك بالطريقة نفسها: استبدل yolo26n.pt بـruns/detect/pills_v1/weights/best.pt.

بث المصادر الطويلة والمباشرة#

لإنشاء شيفرة تتصرف بناءً على عمليات الكشف، استخدم حلقة لمعالجة التدفق. تنتج كل دورة Results لإطار واحد، ثم تتخلص منه:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
source = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"

frames, people = 0, 0
for result in model(source, stream=True, classes=[0], verbose=False):  # one Results object per frame
    frames += 1
    people += len(result.boxes)
print(f"{frames} frames, {people / frames:.1f} people per frame")
62 frames, 22.2 people per frame

تقبل الحلقة نفسها فهرس كاميرا الويب (source=0) أو عنوان URL للكاميرا مثل rtsp://camera.local/stream، وتستمر حتى ينتهي التدفق أو توقفها. أضف vid_stride=2 لمعالجة كل إطار ثانٍ. لإنشاء واجهة متصفح حول هذه الحلقة، يغلّف دليل الاستدلال المباشر باستخدام Streamlit الحلقة في تطبيق.

مثال تطبيقي: احتساب كل شخص مرة واحدة#

«22 شخصًا في كل إطار» ليس العدد الذي يريده أحد؛ بل «كم شخصًا مرّ من هنا؟». يربط تتبع الأجسام المتعددة الصناديق عبر الإطارات، ويمنح وضع التتبع كل جسم معرّفًا في boxes.id:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
source = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"

seen = set()
for result in model.track(source, stream=True, persist=True, classes=[0], tracker="bytetrack.yaml", verbose=False):
    if result.boxes.is_track:
        seen.update(result.boxes.id.int().tolist())
print(f"{len(seen)} unique people tracked")
32 unique people tracked

is_track هي False في الإطارات السابقة لتأكيد أي مسار، عندما تكون boxes.id هي None. استخدم المعرّفات للاحتساب أو تتبع المسارات أو تنفيذ منطق مثل «ظل هذا الجسم هنا لمدة 3 ثوانٍ».

تتبع Ultralytics YOLO على طريق سريع: تحمل كل سيارة وحافلة وشاحنة تسمية معرّف مستمر ومسار حركة

أداة التتبعالسرعةالمتانة
bytetrack.yamlأسرع وأبسطيفقد المعرّفات بوتيرة أعلى عندما تختفي الأجسام لفترة وجيزة
botsort.yamlأبطأأفضل في الحفاظ على المعرّفات عند تحرك الكاميرا (تعويض الحركة؛ إعادة التعرّف على المظهر اختيارية عبر with_reid)

اترك tracker دون تحديد، وسيستخدم Ultralytics tracktrack.yaml، وهو الإعداد الافتراضي الحالي؛ كما يأتي وضع التتبع مع ocsort.yaml وdeepocsort.yaml وfasttrack.yaml. يتناول تتبع الأجسام باستخدام ByteTrack وBoT-SORT وTrackTrack اختيار أدوات التتبع وضبطها، وإنشاء احتساب الأجسام والخرائط الحرارية وتقدير السرعة باستخدامها.

مثال تطبيقي: حلقة الكاميرا الخاصة بك#

غالبًا ما تقرأ التطبيقات الفعلية الإطارات بنفسها — لتغيير حجمها أو اقتصاصها أو إضافة طابع زمني أو مشاركة الكاميرا مع شيفرات أخرى — ثم تمرر كل إطار إلى النموذج. عندئذٍ، تضمن persist=True استمرار عمل أداة التتبع بين الاستدعاءات:

import cv2

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
cap = cv2.VideoCapture("solutions_ci_demo.mp4")  # saved locally by the commands above; or 0, or an rtsp:// URL

seen = set()
while cap.isOpened():
    ok, frame = cap.read()
    if not ok:
        break
    result = model.track(frame, persist=True, classes=[0], tracker="bytetrack.yaml", verbose=False)[0]
    if result.boxes.is_track:
        seen.update(result.boxes.id.int().tolist())
cap.release()
print(f"{len(seen)} unique people, highest ID {max(seen)}")
32 unique people, highest ID 67

العدد نفسه، 32 شخصًا، كما في track.py. لاحظ أن أعلى معرّف هو 67 وليس 32: تخصص أداة التتبع أيضًا معرّفات للمسارات المؤقتة التي لا تُؤكَّد أبدًا، لذا توجد فجوات في المعرّفات.

مواكبة المصدر#

تُرسل كاميرا بمعدل 30 FPS إطارًا كل 33 ms، ويعادل معدلك الفعلي أبطأ المراحل: فك الترميز أو الاستدلال أو الكتابة. على وحدة المعالجة المركزية في حاسوبنا المحمول، استغرق yolo26n ما بين 26 و46 ms لكل إطار بدقة 384×640 عبر عمليات التشغيل، بحسب المهام الأخرى التي كان الجهاز ينفذها: أي عند الميزانية أو فوقها، من دون أي هامش إضافي. إذا لم يستطع جهازك مواكبة المصدر، فجرّب وسائل التحسين التالية بالترتيب:

وسيلة التحسينالتأثير
نموذج أصغر (n بدلًا من s)أسرع غالبًا بمقدار 2–3×
خفض imgsz (480 بدلًا من 640)بكسلات أقل وحسابات أقل؛ تتأثر الأجسام الصغيرة أولًا
vid_stride=2يقلل العمل إلى النصف؛ مناسب للمشاهد بطيئة الحركة
وحدة GPU أو تصدير مُحسَّنأكبر التحسينات — محرك TensorRT على NVIDIA، أو INT8؛ راجع الدرس التالي

يتناول الاستدلال متعدد التدفقات تشغيل عدة كاميرات في الوقت نفسه، وما يرتبط بذلك من تعدد مؤشرات الترابط.

تجنّب هذه الأخطاء#

نسيان stream=True

العَرَض: تزداد الذاكرة حتى تتوقف العملية أثناء تسجيل طويل، أو لا يعود استدعاء الكاميرا المباشرة أبدًا. السبب: من دونه، يجمع استدعاء Python كائن Results لكل إطار قبل الإرجاع. الحل: مرّر stream=True وكرّر على المولّد — فهو لا يفعل شيئًا حتى تبدأ التكرار عليه.

نسيان persist=True في الحلقة الخاصة بك

العَرَض: في cv2_loop.py دون persist=True، انخفض العدد إلى 27 وكان أعلى معرّف أيضًا 27: بدأت المعرّفات من جديد في كل إطار، لذا لم يكن العدد «الفريد» سوى عدد الإطار الأكثر ازدحامًا. الحل: مرّر persist=True كلما استدعيت track مرةً لكل إطار.

العدّ باستخدام أعلى معرّف

العَرَض: عدد يبلغ 67 مقابل 32 شخصًا. السبب: توجد فجوات في المعرّفات بسبب المسارات غير المؤكدة. الحل: احسب حجم مجموعة المعرّفات، كما في track.py.

حدّد أداة التتبّع صراحةً

قد تتغير أداة التتبّع الافتراضية بين الإصدارات. مرّر tracker="bytetrack.yaml" (أو الأداة التي تختارها) كي تبقى الأعداد قابلة للمقارنة بين الإصدارات.

جرّبه

شغّل track_any.py (في الحل) على المقطع التجريبي، ثم على مقطع فيديو قصير من اختيارك. قدّم تقريرًا من ثلاثة أسطر: عدد الأجسام الفريدة، ومتوسط زمن الاستدلال بالميلي ثانية لكل إطار، وما إذا كان ذلك يتناسب مع زمن إطار المصدر، مع ذكر أول وسيلة تحسين ستلجأ إليها إن لم يتناسب. احفظ ناتجًا واحدًا مشروحًا باستخدام yolo track ... save=True، ودوّن ما إذا كانت المعرّفات مستقرة عند الاحتجاب؛ وإذا كانت تتذبذب، فجرّب tracker=botsort.yaml.

متى يُعدّ مكتملًا
تكون قد أتممت الدرس عند تحقق جميع الشروط التالية.
  • حفظت فيديو مشروحًا باستخدام yolo predict أو yolo track.

  • تطبع شيفرة البث عدد الأجسام الفريدة مستندةً إلى مجموعة من قيم boxes.id.

  • قارنت الزمن المقاس بالميلي ثانية لكل إطار بزمن إطار المصدر، وحددت أول وسيلة لتحسين السرعة.

عرض الحل
import sys

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
seen, times = set(), []
for result in model.track(sys.argv[1], stream=True, persist=True, tracker="bytetrack.yaml", verbose=False):
    times.append(result.speed["inference"])
    if result.boxes.is_track:
        seen.update(result.boxes.id.int().tolist())
print(f"{len(seen)} unique objects, {sum(times) / len(times):.1f} ms inference per frame")

شغّله باستخدام python track_any.py your_video.mp4.

32 unique objects, 30.5 ms inference per frame (26-46 ms across runs on a laptop CPU)
Source is 30 FPS -> 33 ms budget: fits only on a quiet machine, with no headroom
First lever: export to OpenVINO or ONNX for this CPU, then vid_stride=2 if still short
ما الخطوة التالية

يعمل نموذجك على الصور والفيديو باستخدام Python. الخطوة الأخيرة: تصديره إلى تنسيق تستطيع بيئة تشغيل الإنتاج تحميله.

سجّل الدخول لحفظ التقدم