Comments 24
А двухрядные номера как читает? ))
Просмотрел что ли нагрузку на процессор... Хочется прикинуть сколько камер i7 потянет.
Отличный вопрос. Точное количество сильно зависит от разрешения камер, FPS и количества машин в кадре.
На моем i7-9700KF одна камера ~480p@30fps загружала процессор на ~90%. Использовалось видео с "живого" регистратора.
С учетом оптимизаций (пропуск кадров, детектор движения) можно ожидать, что такой процессор уверенно "потянет" 2-3 камеры с разрешением 720p или 1-2 камеры 1080p. Для большего количества уже настоятельно рекомендуется использовать GPU.
YOLO внутри сразу, скорей всего, "пожмёт" Ваши данные к 640х640 и ничего не поменяется. Причём и снизу(480p) и сверху (1080p). Так что в детекции только небольшие накладные расходы..
Извините что опять встреваю)
Да, вы правы. YOLO работает с 640х640, нагрузка от работы нейросети что для 480, что для 1080 особо не изменится. А вот привидение к этим 640х640 для 1080 будет несколько "дороже" по ресурсам.
А в целом по затратам ресурсов, проект сейчас MVP с достаточно "топорной" реализацией, предполагал оптимизировать уже под конкретные задачи/реализации)
Да, не скорей всего, а 100%. ну так в целом получается, дорого-богато. Нам на 200 камер прийдется раскошелиться с таким решением.
Да, вы абсолютно правы. Для 200 камер потребуется совершенно другой подход к архитектуре и "железу".
Этот проект вырос из небольшого фриланс-задания для автосервиса, поэтому и фокус в статье был на максимальной оптимизации под CPU.
Но если говорить о масштабировании на сотни камер, то архитектура решения кардинально меняется - без GPU уже не обойтись
Кстати для таких задач часто используют не полноценные CPU, а что-то вроде Intel NUC с OpenVINO или Jetson Nano от NVIDIA, они оптимизированы именно под инференс нейросетей и при меньшей общей производительности могут показывать лучшие результаты на конкретной задаче, чем "универсальный" Core i7

У Вас на видео в простейшем случае вылезла ошибка, а Вы забыли это упомянуть.
Потому следующие замечания:
1) 100 эпох на yolo8n для детекции номеров на 25к изображений? У меня не то чтобы много опыта, но тот что есть, говорит - скорей всего переобучение. Для подобной задачи это всё ещё большая модель.
2) Вот на видео очевидная пробелма в простейшей ситуации. И подозреваю, что Вы не знаете, как это фиксить. Проблема "коробочного" решения в 2 клика.. Но может я и ошибаюсь - распознаватель-то у Вас свой )
Было бы приятнее прочитать про Ваш опыт, если бы в статье было поменьше восторженных эпитетов, если результат отнюдь не выдающийся.
Однако какой-то результат получили, что уже неплохо!
Спасибо за критику по существу. Вы абсолютно правы, результат не идеален, и статья действительно выиграет от более честного анализа. Позвольте уточнить пару моментов.
1. Про ошибку на видео и контекст задачи.
Вы совершенно верно подметили ошибку OCR. Я специально выбрал такой сложный кадр из "живого" трафика, чтобы продемонстрировать пределы возможностей MVP.
Изначально система проектировалась для более простых условий — статичных камер в автосервисе, где машины неподвижны. Как вы и сказали, для такой задачи текущего качества (с небольшим дообучением на целевых данных) уже достаточно.
Что касается фикса ошибки на видео, то здесь действительно два пути:
ML-подход: Дообучить OCR-модель с более "агрессивными" аугментациями (перспективные искажения, размытие).
CV-подход: Улучшить алгоритм препроцессинга, добавив, например, более сложную стабилизацию изображения перед распознаванием.
2. Про 100 эпох и переобучение YOLO.
Это очень грамотное замечание. Риск переобучения при таком количестве эпох действительно существует. К счастью, в данном случае его удалось избежать, что подтверждается графиками обучения: кривые ошибок для train и val выборок идут почти в унисон, без значительного расхождения. Современные фреймворки, как ultralytics, имеют хорошие встроенные механизмы регуляризации, которые с этим помогают. Но вы правы в главном: пик метрики mAP@0.5-0.95 был достигнут значительно раньше (примерно на 70-80 эпохе), и для экономии ресурсов можно было смело останавливать обучение тогда. 100 эпох были скорее для "чистоты эксперимента".
Добрый день! Ваше сообщение очень похоже на ответ от нейросети. Может быть. попробуете сами писать ответы? Прошу прощения, если неправ.
Хорошее руководство по созданию MVP для сложной ML-задачи. Не стал изобретать велосипед там, где он не нужен (взял YOLOv8), но и не побоялся испачкать руки, когда готовое решение (Tesseract) не подошло.
Особенно ценно решение отложить квантизацию YOLO, когда стало ясно, что риск сломать окружение выше, чем потенциальная выгода - это признак зрелого инженера, а не просто исследователя
Да, использовал, и довольно активно. Мой принцип — ИИ как "второй пилот", а не как автор.
В коде он писал шаблонные вещи и комментарии, позволяя мне фокусироваться на архитектуре. Для статьи и README — выступал в роли стилиста, улучшая форму(иногда слишком и нужно было упрощать, но как говорится "ломать - не строить"), но не суть.
Работая над проектом в одиночку, ИИ действительно становится незаменимым "спарринг-партнером" для отладки и проверки идей. Это интересный и очень продуктивный опыт.
И для одиночного разработчика, когда тебе не у кого спросить/посоветоваться/обсудить и есть только статьи по теме и тех.документация, ИИ достаточно полезен, главное понимать, что ИИ врут достаточно часто, и относится к его ответам критически, хотя бы в рамках своих знаний.
А почему имена YOLOv8n, а не скажем YOLOv11n или YOLOv12n выбрали?
Выбор YOLOv8n был в первую очередь прагматичным решением для MVP, поскольку я уже имел с ней опыт работы. Цель этого проекта была не в поиске самой лучшей модели для этой задачи, а в том, чтобы проверить жизнеспособность идеи и построить полный каркас MVP
Я на днях интересовал этим LPR, взял cv2::Haar для детекции, для OCR начал с Tesseract, это вообще не подходит для этих задач, прям ноль. Потом пробовал EasyOcr, дало средний, но результат, зависит от препроцессинга кадра, руками писал поворот номеров в горизонталь, и самое главное для нее, это размер входного plate в пикселях, нужно от этого отталкиваться, стало хоть немного адекватно работать.
Но, естественно, пришел к тому же датасету, что у вас и что надо обучать свой детектор и ocr, а тут ваша статья, еще и github-ом, для MVP новичкам типа меня бесценно, спасибо вам =D
Спасибо за добрые слова) Очень приятно слышать, что моя статья и репозиторий оказались для вас полезным "шаблоном" и подтверждением ваших выводов. Именно ради таких моментов и стоит делиться своей работой с сообществом. Уверен, с таким подходом у вас все получится!
Так же поделюсь источником-вдохновением - https://habr.com/ru/articles/432444/
Напишу, для тех, кто захочет использовать ваш проект:
Если у вас произвольные данные на входе в пайплайн, скажем с видео камеры:
во первых, надо знать что из вашего frame надо вырезать roi = frame(640*640), иначе модель сожмет все до 640*640 сама и вы потеряете что-нибудь, и детектор будет хуже работать.
во вторых, если детектор найдет bbox размера отличного от 128*32 (обычно меньше), то модель OCR будет ваш bbox ресайзить, что приведет к искажениям символов и вы очень сильно потеряете или вообще не будет находить правильный текст - тут можно от центра bbox увеличить самому extended_bbox = bbox увеличенный до 128*32 с центром от оригинального bbox, а потом уже из img вырезать extended_bbox и передавать в модель OCR - confidence будет 0.87 (или можно кастомный паддинг сделать в transforms.Compose() вместо Resize, кому как).
вдруг, кому-то сэкономит время =D

Собираем ANPR-систему на Python: от YOLOv8 и кастомного OCR до INT8-квантизации