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.
Thực hành
Dự đoán và in mọi phát hiện#

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.65tạ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ính | Chứa |
|---|---|
boxes | Cá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) |
names | Dict á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 |
speed | Thời gian tiền xử lý, inference và hậu xử lý tính bằng ms |
path, save_dir | Nguồ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 định | Thay đổi |
|---|---|---|---|
| Bỏ sót: vật thể nhìn thấy được nhưng không có bounding box | conf | 0.25 | Giảm, ví dụ: 0.1 |
| Dương tính giả: có bounding box ở vị trí không có vật thể | conf | 0.25 | Tăng, ví dụ: 0.5 |
| Hai bounding box trên cùng một vật thể | iou | 0.7 | Giả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ỏ ở xa | imgsz | 640 | Tăng, ví dụ: 1280 (làm tròn đến bội số của 32) |
| Chỉ một số class là cần thiết | classes | tất cả | ví dụ: classes=[0] cho người |
| Phần cứng không phù hợp | device | tự động | cpu, 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#
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().
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.
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.
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.59summary() đã 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.