Ultralytics YOLO27: Tham gia danh sách chờ.
Get Started
Bài họcngười mới bắt đầu

Chạy suy luận trên video

Chạy YOLO26 trên tệp video và camera trực tiếp với bộ nhớ được giới hạn, theo dõi đối tượng để đếm mỗi đối tượng một lần và kiểm tra xem model có theo kịp tốc độ khung hình hay không.

Hầu hết hệ thống thị giác được triển khai đều xử lý video: camera trên băng chuyền, cửa ra vào và đường phố. Video có thêm hai vấn đề mà ảnh đơn không gặp phải. Bộ nhớ: không thể giữ bản ghi dài trong RAM. Danh tính: detector nhìn thấy cùng một người trong 60 khung hình và báo cáo 60 người.

Trong bài học này, bạn sẽ truyền video từng khung hình bằng Predict mode, thêm theo dõi đối tượng để đếm mỗi người một lần, tự viết vòng lặp camera và đo xem model có theo kịp hay không.

Kết quả

Bạn có thể truyền video hoặc luồng camera qua YOLO26 với bộ nhớ được giới hạn, đếm các đối tượng duy nhất bằng tính năng theo dõi và dựa vào số ms đo được trên mỗi khung hình để xác định model có theo kịp nguồn hay không.

Lộ trình cấp tốc
Nếu bạn đã nắm rõ cách thực hiện, đây là phiên bản tóm tắt.
  1. model(video, stream=True) tạo ra một Results cho mỗi khung hình với bộ nhớ được giới hạn.

  2. model.track(video, stream=True, persist=True, tracker='bytetrack.yaml') thêm boxes.id.

  3. Đếm đối tượng duy nhất bằng tập hợp ID, không bao giờ dựa vào ID lớn nhất.

  4. Ngân sách = 1000 ÷ FPS của nguồn; so sánh với result.speed['inference'].

Thực hành

Ví dụ minh họa: Dự đoán trên tệp video#

Video dùng cùng Predict mode như ảnh. Đoạn clip 62 khung hình này cho thấy mọi người đi qua một sảnh lớn:

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 giải mã video và xử lý từng khung hình như một ảnh.
  • 22 persons: các detection trong khung hình đó. Những người đi bộ giống nhau được đếm lại trong mọi khung hình.
  • 27.3ms ... 54.8ms: thời gian xử lý mỗi khung hình thay đổi tùy vào các tác vụ khác mà máy đang thực hiện.

Video đã chú thích là runs/detect/predict/solutions_ci_demo.mp4. Model của bạn hoạt động tương tự: thay yolo26n.pt bằng runs/detect/pills_v1/weights/best.pt.

Truyền nguồn dài và trực tiếp#

Với mã xử lý detection, hãy lặp qua một luồng. Mỗi vòng lặp trả về Results của một khung hình, rồi loại bỏ khung hình đó:

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

Cùng vòng lặp này chấp nhận chỉ số webcam (source=0) hoặc URL camera như rtsp://camera.local/stream, và chạy cho đến khi luồng kết thúc hoặc bạn dừng vòng lặp. Thêm vid_stride=2 để xử lý cách mỗi khung hình. Để tạo giao diện web quanh vòng lặp này, hướng dẫn suy luận trực tiếp với Streamlit sẽ đóng gói vòng lặp trong một ứng dụng.

Ví dụ minh họa: Đếm mỗi người một lần#

"22 người mỗi khung hình" không phải con số mọi người cần; điều họ muốn biết là "đã có bao nhiêu người đi qua". Theo dõi nhiều đối tượng liên kết các hộp qua các khung hình, còn Track mode gán cho mỗi đối tượng một ID trong 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 là False trên các khung hình trước khi bất kỳ track nào được xác nhận, khi boxes.id là None. Dùng ID để đếm, xác định quỹ đạo hoặc triển khai logic như "đối tượng này đã ở đây được 3 giây".

Theo dõi bằng Ultralytics YOLO trên đường cao tốc: mỗi ô tô, xe buýt và xe tải có nhãn ID ổn định cùng vệt chuyển động

Bộ theo dõiTốc độĐộ bền vững
bytetrack.yamlNhanh hơn, đơn giản hơnMất ID thường xuyên hơn khi đối tượng biến mất trong thời gian ngắn
botsort.yamlChậm hơnGiữ ID tốt hơn khi camera di chuyển (bù chuyển động; ReID theo ngoại hình là tùy chọn thông qua with_reid)

Nếu không chỉ định tracker, Ultralytics dùng tracktrack.yaml, mặc định hiện tại; Track mode cũng tích hợp ocsort.yaml, deepocsort.yaml và fasttrack.yaml. Cách chọn và tinh chỉnh bộ theo dõi, cũng như xây dựng đếm đối tượng, bản đồ nhiệt và ước tính tốc độ dựa trên các bộ theo dõi đó, được trình bày trong hướng dẫn Theo dõi đối tượng với ByteTrack, BoT-SORT và TrackTrack.

Ví dụ minh họa: Vòng lặp camera của riêng bạn#

Các ứng dụng thực tế thường tự đọc khung hình — để thay đổi kích thước, cắt, gắn dấu thời gian hoặc chia sẻ camera với mã khác — rồi truyền từng khung hình cho model. Khi đó, persist=True giữ cho bộ theo dõi hoạt động giữa các lần gọi:

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

Vẫn là 32 người như track.py. Lưu ý ID lớn nhất là 67, không phải 32: bộ theo dõi cũng cấp ID cho các track tạm thời không bao giờ được xác nhận, nên ID có khoảng trống.

Theo kịp nguồn#

Camera 30 FPS cung cấp một khung hình sau mỗi 33 ms; tốc độ thực tế của bạn bị giới hạn bởi khâu chậm nhất trong giải mã, suy luận và ghi dữ liệu. Trên CPU máy tính xách tay của chúng tôi, yolo26n mất từ 26 đến 46 ms cho mỗi khung hình 384×640 qua các lần chạy, tùy thuộc vào những tác vụ khác máy đang thực hiện: chạm hoặc vượt ngân sách, không có dư địa. Nếu hệ thống của bạn không theo kịp, hãy điều chỉnh theo thứ tự sau:

Điều chỉnhTác động
Model nhỏ hơn (n thay cho s)Thường nhanh hơn 2–3 lần
Giảm imgsz (480 thay vì 640)Ít pixel hơn, ít tính toán hơn; đối tượng nhỏ bị ảnh hưởng trước tiên
vid_stride=2Giảm một nửa khối lượng xử lý; phù hợp với cảnh chuyển động chậm
GPU hoặc bản export đã tối ưuCải thiện lớn nhất — engine TensorRT trên NVIDIA hoặc INT8; xem bài học tiếp theo

Bài Suy luận nhiều luồng trình bày cách xử lý nhiều camera cùng lúc và cơ chế đa luồng đi kèm.

Tránh những lỗi này#

Quên stream=True

Triệu chứng: bộ nhớ tăng dần cho đến khi tiến trình bị dừng khi xử lý bản ghi dài, hoặc lời gọi camera trực tiếp không bao giờ trả về. Nguyên nhân: nếu không có tham số này, lời gọi Python thu thập một object Results cho mỗi frame trước khi trả về. Cách khắc phục: truyền stream=True và lặp qua generator — generator không làm gì cho đến khi bạn lặp qua nó.

Quên persist=True trong vòng lặp của bạn

Triệu chứng: trong cv2_loop.py mà không có persist=True, số lượng giảm còn 27 và ID cao nhất cũng là 27: ID khởi động lại ở mỗi frame, nên số lượng "duy nhất" thực ra chỉ là số lượng ở frame đông nhất. Cách khắc phục: truyền persist=True mỗi khi gọi track một lần cho mỗi frame.

Đếm bằng ID cao nhất

Triệu chứng: đếm được 67 người dù thực tế có 32 người. Nguyên nhân: ID có khoảng trống do các track chưa được xác nhận. Cách khắc phục: đếm kích thước của tập ID, như trong track.py.

Chỉ định rõ tracker

Tracker mặc định có thể thay đổi giữa các bản phát hành. Hãy truyền tracker="bytetrack.yaml" (hoặc tracker bạn chọn) để số lượng luôn có thể so sánh giữa các phiên bản.

Dùng thử

Chạy track_any.py (trong lời giải) trên đoạn clip demo, sau đó chạy trên một video ngắn của riêng bạn. Nộp báo cáo ba dòng: số đối tượng duy nhất, thời gian suy luận trung bình tính bằng ms mỗi khung hình và việc thời gian đó có đáp ứng khoảng thời gian khung hình của nguồn hay không; nếu không, hãy nêu điều chỉnh đầu tiên bạn sẽ thực hiện. Lưu một tệp đầu ra đã chú thích bằng yolo track ... save=True và ghi chú xem ID có ổn định khi bị che khuất hay không; nếu ID chập chờn, hãy thử tracker=botsort.yaml.

Điều kiện hoàn thành
Bạn đã hoàn thành bài học khi tất cả các điều kiện sau đều đúng.
  • Bạn đã lưu một video có chú thích bằng yolo predict hoặc yolo track.

  • Script truyền luồng của bạn in ra số đối tượng duy nhất bằng cách lấy một tập hợp các giá trị boxes.id.

  • Bạn đã so sánh số ms đo được trên mỗi khung hình với khoảng thời gian khung hình của nguồn và nêu điều chỉnh tốc độ đầu tiên.

Hiển thị lời giải
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")

Chạy bằng 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
Tiếp theo là gì

Model của bạn hoạt động với ảnh và video trong Python. Bước cuối: export model sang định dạng mà runtime production có thể tải.

Đăng nhập để lưu tiến độ