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

Dự đoán trên ảnh

Chạy model YOLO26 pretrained từ Python, đọc class, confidence và bounding box theo pixel từ kết quả, đồng thời tinh chỉnh các tham số xử lý phần lớn trường hợp bỏ sót.

Mọi ứng dụng thực tế của model phát hiện — đếm hàng hóa trên kệ, cắt khuôn mặt để làm mờ, gửi bounding box đến JSON API — đều bắt đầu từ việc đọc đúng đối tượng kết quả. Chỉ cần sai một chi tiết, chẳng hạn dùng tensor làm chỉ số cho tên class, ứng dụng của bạn sẽ gặp sự cố ngay ở ảnh đầu tiên.

Model detect YOLO26 pretrained đã nhận biết 80 class COCO. Trong bài học này, bạn sẽ chạy chế độ Predict từ Python, lấy mọi trường hữu ích từ kết quả và tìm hiểu cần thay đổi tham số nào khi bị bỏ sót, phát hiện trùng lặp hoặc gặp vật thể nhỏ. Sau này, đối tượng kết quả tương tự cũng được trả về từ model bạn tự huấn luyện.

Kết quả

Bạn có thể viết một script Python chạy YOLO26 trên ảnh và in tên class, confidence cùng bounding box theo pixel của từng phát hiện, đồng thời biết tham số nào xử lý từng kiểu bỏ sót.

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. Chỉ tải một lần: model = YOLO('yolo26n.pt'); sau đó result = model(source)[0].

  2. Lặp qua result.boxes; chuyển đổi bằng int(box.cls), float(box.conf), box.xyxy[0].tolist().

  3. Ánh xạ chỉ số class sang tên bằng result.names[int(box.cls)].

  4. Tinh chỉnh conf, iou, imgsz và classes cho từng lần gọi.

Thực hành

Dự đoán và in mọi phát hiện#

Các phát hiện của Ultralytics YOLO trên lối đi dạo ven sông: bounding box có nhãn và điểm confidence quanh người, xe đạp, chó và ô tô

Gọi model với một nguồn dữ liệu sẽ chạy chế độ Predict và trả về danh sách gồm một đối tượng Results cho mỗi ảnh. Với một ảnh, hãy đọc results[0].

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
results = model("https://ultralytics.com/images/bus.jpg")

result = results[0]
for box in result.boxes:
    name = result.names[int(box.cls)]
    conf = float(box.conf)
    x1, y1, x2, y2 = box.xyxy[0].tolist()
    print(f"{name:>8} {conf:.2f}  ({x1:.0f}, {y1:.0f}) -> ({x2:.0f}, {y2:.0f})")

result.save("bus_annotated.jpg")

Đầu ra thực tế từ predict.py, sau dòng log thông thường:

     bus 0.88  (0, 230) -> (803, 751)
  person 0.87  (49, 398) -> (240, 902)
  person 0.86  (223, 405) -> (345, 861)
  person 0.85  (670, 395) -> (810, 880)
  person 0.65  (0, 553) -> (60, 871)

Cách đọc kết quả:

  • bus 0.88: tên class và confidence. Các bounding box được sắp xếp theo confidence, từ cao xuống thấp.
  • (0, 230) -> (803, 751): tọa độ góc trên bên trái và góc dưới bên phải theo pixel của ảnh gốc 810×1080, với gốc tọa độ ở góc trên bên trái. Bạn có thể dùng trực tiếp các tọa độ này để cắt ảnh hoặc vẽ.
  • person 0.65 tại (0, 553): người thứ năm, bị cắt mất một phần ở mép trái, có điểm số thấp hơn. Vật thể chỉ xuất hiện một phần thường có điểm thấp hơn.

result.save() ghi ảnh đã được chú thích; result.show() mở ảnh trong cửa sổ.

Tìm hiểu nội dung của kết quả#

Mọi tác vụ đều trả về cùng một kiểu Results; chỉ các trường được điền là khác nhau. Xem toàn bộ các trường trong hướng dẫn sử dụng Python.

Thuộc tínhChứa
boxesCác phát hiện: pixel xyxy, định dạng tâm đã chuẩn hóa xywhn, conf, cls và id khi theo dõi
masks, keypoints, obb, probsĐầu ra của model segment, pose, OBB và classify (None đối với model detect)
namesDict ánh xạ chỉ số class → tên class
orig_img, orig_shapeẢnh đầu vào dưới dạng mảng NumPy và chiều cao × chiều rộng của ảnh
speedThời gian tiền xử lý, inference và hậu xử lý tính bằng ms
path, save_dirNguồn đầu vào và nơi ghi đầu ra

Đối với phát hiện đối tượng, bạn chủ yếu cần boxes, tức bounding box. result.summary() trả về cùng các phát hiện dưới dạng danh sách dict thuần, sẵn sàng dùng với JSON API.

Tinh chỉnh dự đoán#

Các giá trị mặc định phù hợp với hầu hết ảnh. Nếu không phù hợp, hãy thay đổi từng tham số một:

Vấn đề bạn gặpĐối sốMặc địnhThay đổi
Bỏ sót: vật thể nhìn thấy được nhưng không có bounding boxconf0.25Giảm, ví dụ: 0.1
Dương tính giả: có bounding box ở vị trí không có vật thểconf0.25Tăng, ví dụ: 0.5
Hai bounding box trên cùng một vật thểiou0.7Giảm: ngưỡng độ chồng lấp (IoU) của NMS để gộp các phát hiện trùng lặp
Bỏ sót vật thể nhỏ ở xaimgsz640Tăng, ví dụ: 1280 (làm tròn đến bội số của 32)
Chỉ một số class là cần thiếtclassestất cảví dụ: classes=[0] cho người
Phần cứng không phù hợpdevicetự độngcpu, mps hoặc chỉ số GPU như 0

Confidence làm thay đổi kết quả, không chỉ số lượng. Trên cùng một ảnh xe buýt:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
model("https://ultralytics.com/images/bus.jpg", conf=0.5, classes=[0])  # 4 persons
model("https://ultralytics.com/images/bus.jpg", conf=0.1)  # 5 người, 1 xe buýt, 1 biển báo dừng

Ở conf=0.1, model cũng báo cáo một biển báo dừng mà model không chắc chắn. Giảm conf là cách nhanh nhất để xem model suýt phát hiện được những gì. Các tham số khác có trong tài liệu tham khảo cấu hình.

Khi dự đoán trả về kết quả trống, hãy lần lượt kiểm tra theo hướng dẫn sau:

Chạy trên nhiều ảnh#

Truyền vào danh sách, thư mục hoặc glob như "photos/*.jpg". Predict mặc định dùng batch=1; đặt batch để xử lý nhiều ảnh cùng lúc qua model, nhanh hơn đáng kể trên GPU:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
images = ["https://ultralytics.com/images/bus.jpg", "https://ultralytics.com/images/zidane.jpg"]
for result in model(images, batch=2):
    print(result.path, len(result.boxes), result.verbose())
image0.jpg 5 4 persons, 1 bus,
image1.jpg 3 2 persons, 1 tie,

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

Dùng tensor để truy cập tên

Triệu chứng: KeyError: tensor([5.]). Nguyên nhân: box.cls và box.conf là tensor PyTorch, còn result.names là dict có khóa là int. Cách khắc phục: trước tiên hãy chuyển đổi: result.names[int(box.cls)], float(box.conf), box.xyxy[0].tolist().

Nạp model trong mỗi lần gọi

Triệu chứng: một hàm tiện ích gọi YOLO("yolo26n.pt") bên trong hàm chạy chậm. Trên CPU laptop, việc nạp lại model cho mỗi ảnh mất 71 ms, so với 25 ms khi chỉ nạp model một lần. Cách khắc phục: tạo model một lần khi khởi động và dùng lại cho mọi ảnh.

Hàng trăm ảnh hoặc bất kỳ video nào? Hãy xử lý theo luồng

model(list_or_folder) thu thập mọi object Results vào bộ nhớ trước khi trả về. Với thư mục lớn và toàn bộ video, hãy truyền stream=True và lặp: kết quả được trả về từng cái một. Bài học về video trình bày nội dung này chuyên sâu.

Dùng thử

Viết top3.py: chỉ tải yolo26n.pt một lần, chạy model trên bus.jpg, zidane.jpg và một ảnh của bạn, rồi in số lượng phát hiện của mỗi ảnh cùng ba class có confidence cao nhất. Sau đó chạy lại ảnh có ít phát hiện nhất ở conf=0.1 và viết một câu về những gì xuất hiện.

Đ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.
  • Script của bạn in số lượng và ba class đứng đầu cùng confidence cho mỗi ảnh, không có KeyError.

  • Bạn đã so sánh một ảnh ở conf=0.25 và conf=0.1, đồng thời ghi lại những thay đổi.

  • Bạn có thể nêu tên tham số cần thay đổi khi gặp tình trạng bỏ sót, bounding box trùng lặp và vật thể nhỏ.

Hiển thị lời giải
from ultralytics import YOLO

model = YOLO("yolo26n.pt")  # load once
images = ["https://ultralytics.com/images/bus.jpg", "https://ultralytics.com/images/zidane.jpg"]

for result in model(images, verbose=False):
    top3 = sorted(result.summary(), key=lambda d: d["confidence"], reverse=True)[:3]
    print(f"{result.path}: {len(result.boxes)} detections")
    for d in top3:
        print(f"  {d['name']:>8} {d['confidence']:.2f}")
image0.jpg: 5 detections
       bus 0.90
    person 0.85
    person 0.85
image1.jpg: 3 detections
    person 0.89
    person 0.79
       tie 0.59

summary() đã trả về tên và số thực thuần, nên không cần chuyển đổi tensor. Confidence hơi khác predict.py vì danh sách ảnh được đệm về cùng một kích thước. Ở conf=0.1, bus.jpg bổ sung một biển báo dừng.

Tiếp theo là gì

Bạn đã dùng model nhỏ nhất. Tiếp theo, hãy quyết định kích thước YOLO26 nào phù hợp để huấn luyện và triển khai cho dự án của bạn.

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