Разберись в детекции объектов
Научись читать выходные данные детектора — класс, рамку и уверенность — и выбирать пороги уверенности и IoU с учетом цены каждой ошибки.
Большинство работающих в производственной среде систем компьютерного зрения — это системы детекции с дополнительной логикой: счетчики, трекеры, оповещения о зонах, размытие для защиты конфиденциальности. Когда что-то работает не так, причина обычно не в модели, а в пороге, который никто не выбирал осознанно. Если точно знать, что возвращает детектор и какие два параметра формируют этот список, можно отладить почти любую систему, построенную на его основе.
Практические занятия
Что возвращает детектор#

Каждая метка на этом изображении — это одна строка выходных данных: название класса, оценка уверенности и рамка вокруг объекта. Модель детекции возвращает именно такой список:
- Класс — целочисленный индекс, сопоставленный с названием через
result.names(0— этоperson, а5— этоbus). - Рамка — четыре числа, задающие положение объекта;
xyxyвозвращает координаты верхнего левого и нижнего правого углов в пикселях. - Уверенность — оценка от 0 до 1, используемая для ранжирования и фильтрации детекций.
Подсчет объектов, оповещения, треккинг и размытие — это код, который ты пишешь поверх этих строк.
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
result = model("https://ultralytics.com/images/bus.jpg", verbose=False)[0]
for box in result.boxes:
name = result.names[int(box.cls)]
x1, y1, x2, y2 = box.xyxy[0].tolist()
print(f"{name:8} conf={float(box.conf):.2f} box=({x1:.0f}, {y1:.0f}, {x2:.0f}, {y2:.0f})")bus conf=0.88 box=(0, 230, 803, 751)
person conf=0.87 box=(49, 398, 240, 902)
person conf=0.86 box=(223, 405, 345, 861)
person conf=0.85 box=(670, 395, 810, 880)
person conf=0.65 box=(0, 553, 60, 871)Разберем по порядку: рамка автобуса начинается с x=0, потому что автобус выходит за левый край; уверенность для трех человек — 0.85–0.87; у четвертого человека, обрезанного левым краем, оценка всего 0.65 — модель видит половину тела. Низкая уверенность у частично обрезанных объектов — обычное явление, и именно здесь порог проявляет себя в первую очередь.
Каждая рамка представлена в одном из четырех форматов; используй тот, который ожидает твой код для последующей обработки:
| Атрибут | Формат | Типичное применение |
|---|---|---|
boxes.xyxy | Координаты углов в пикселях (x1, y1, x2, y2) | Кадрирование, отрисовка, правила перекрытия |
boxes.xywh | Координаты центра в пикселях, ширина и высота | Фильтры по размеру, движение |
boxes.xyxyn | Координаты углов, нормализованные в диапазон 0–1 | Правила, сохраняющие работоспособность при смене разрешения |
boxes.xywhn | Координаты центра и размеры, нормализованные в диапазон 0–1 | Файлы меток YOLO |
От кандидатов к итоговому списку#
Внутри модель оценивает множество рамок-кандидатов для каждого объекта. Два фильтра превращают их в список, который ты видишь:
Фильтр уверенности. conf отбрасывает рамки ниже порога; значение по умолчанию при предсказании — 0.25. На изображении автобуса число детекций быстро меняется:
conf | Рамки на bus.jpg |
|---|---|
| 0.10 | 7 |
| 0.25 | 5 |
| 0.50 | 5 |
| 0.75 | 4 |
Фильтр дубликатов. Подавление немаксимумов (NMS) оставляет рамку с наибольшей уверенностью и отбрасывает другие рамки того же класса, если они перекрывают ее больше, чем на iou (по умолчанию 0.7). Перекрытие измеряется как пересечение над объединением: общая площадь, деленная на площадь объединения.

iou | Рамки на bus.jpg | Эффект |
|---|---|---|
| 0.3 | 5 | Строгий: пересекающиеся рамки объединяются |
| 0.7 | 5 | По умолчанию |
| 0.95 | 8 | Мягкий: почти дубликаты сохраняются |
Выбирай пороги, исходя из цены ошибок#
| Если… | То… |
|---|---|
| Пропуск обходится дорого (предупреждения о безопасности, дефекты) | Понизь conf и смирись с некоторыми ложными срабатываниями |
| Ложные срабатывания заметны пользователям (поиск, разметка тегами) | Повысь conf |
| Ты сообщаешь количество объектов | Проверь разные значения conf на валидационных изображениях и выбери то, при котором ошибка подсчёта минимальна |
| Настоящие соседние объекты пропадают в толпе | Повысь iou, например с 0.7 до 0.8 |
| Для одного объекта появляются две рамки | Понизь iou |
| Классы различаются по сложности | Используй минимальное необходимое значение conf, а затем фильтруй результаты по классам в коде |
Мониторинг безопасности на складе — классический пример, где нужен низкий порог; в разделе режим Predict перечислены все аргументы инференса.
Подводные камни#
Симптом: «модель на 88% уверена, что это автобус», а пороги выбирают интуитивно. Решение: воспринимай уверенность как оценку для ранжирования. В YOLO26 одна оценка учитывает и «объект существует», и «это объект данного класса», но она не калибрована — выбирай порог по валидационным данным, а не по смыслу числа.
Когда два человека стоят плечом к плечу, их рамки сильно перекрываются, и NMS может удалить реального человека как «дубликат». Увеличь iou, и вторая рамка появится. В YOLO26 также есть сквозная голова, которой совсем не нужен NMS; передай nms=False, чтобы использовать её.
Симптом: порог, который идеально работает на демонстрационном изображении, не подходит для реальной камеры. Решение: проверь разные пороги на валидационной выборке с камеры, где будет развёрнута модель; одно изображение показывает лишь то, как работают настройки.
Четыре способа ошибиться#
| Сбой | Что не так | Типичное исправление |
|---|---|---|
| Правильный класс, неточная рамка | Локализация | Установи более строгие и согласованные правила разметки рамок; используй более высокое значение imgsz для маленьких объектов |
| Хорошая рамка, неверный класс | Классификация | Добавь больше примеров похожей пары или объедини классы |
| Рамки нет вовсе | Полнота | Добавь больше примеров таких условий: освещение, размер, перекрытие |
| Рамка на фоне | Точность | Добавь изображения со сложными отрицательными примерами, которые ввели модель в заблуждение |
Два списка помогают быстро найти причину: истинно положительные объекты с низкой уверенностью (модель сомневается в реальных объектах) и ложноположительные результаты с высокой уверенностью (модель уверена в неверном ответе). Для них нужны разные исправления.
Показать решение
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
result = model("https://ultralytics.com/images/bus.jpg", conf=0.05, save=True, verbose=False)[0]
for box in sorted(result.boxes, key=lambda b: -float(b.conf)):
name, conf = result.names[int(box.cls)], float(box.conf)
x1, y1, x2, y2 = box.xyxy[0].tolist()
print(f"{conf:.2f} {name:10} ({x1:.0f}, {y1:.0f}, {x2:.0f}, {y2:.0f})")0.88 bus (0, 230, 803, 751)
0.87 person (49, 398, 240, 902)
0.86 person (223, 405, 345, 861)
0.85 person (670, 395, 810, 880)
0.65 person (0, 553, 60, 871)
0.18 person (0, 600, 40, 871)
0.12 stop sign (0, 252, 35, 326)
0.08 handbag (43, 732, 78, 812)
0.07 skateboard (669, 822, 808, 881)
0.06 handbag (225, 634, 291, 705)Все рамки ниже 0.5 — ложноположительные. Рамка с person 0.18 дублирует рамку человека с оценкой 0.65, частично обрезанного левым краем. Объект с stop sign 0.12 — настоящий дорожный знак, которому присвоен неверный класс. Сумки и скейтборд находятся на руках и обуви. Оценка всех реальных объектов выше 0.6, поэтому conf=0.5 сохраняет всех четырёх людей и отбрасывает весь шум — для счётчика пешеходов это защищает от двойного подсчёта. Перед запуском проверь это на валидационном наборе с реальной камеры: частично обрезанный человек с оценкой 0.65 показывает, насколько близко реальные объекты могут оказаться к порогу.