Я работал над проектом, включающим обработку изображений для обнаружения логотипа. В частности, цель состоит в том, чтобы разработать автоматизированную систему для детектора грузовых автомобилей/логотипов FedEx в режиме реального времени, которая считывает кадры из потока IP-камеры и отправляет уведомление об обнаружении. Вот образец системы в действии с узнаваемым логотипом, окруженным зеленым прямоугольником.
Некоторые ограничения на проект:
- Использует сырой OpenCV (без глубокого обучения, искусственного интеллекта или обученных нейронных сетей)
- Фон изображения может быть шумным
- Яркость изображения может сильно различаться (утром, днем, ночью)
- Грузовик/логотип FedEx может иметь любой масштаб, поворот или ориентацию, так как он может быть припаркован в любом месте на тротуаре
- Логотип может быть размытым или размытым с разными оттенками в зависимости от времени суток.
- Там может быть много других транспортных средств с аналогичными размерами или цветами в той же раме
- Обнаружение в реальном времени (~ 25 кадров в секунду с IP-камеры)
- IP-камера находится в фиксированном положении, и грузовик FedEx всегда будет в одной и той же ориентации (никогда не назад или вверх ногами)
- Грузовик FedEx всегда будет "красным" вариантом вместо "зеленого" варианта
Текущая реализация/алгоритм
У меня есть две темы:
- Поток № 1 - захватывает кадры с IP-камеры с помощью
cv2.VideoCapture()
и изменяет размеры кадра для дальнейшей обработки. Решили обработать захват кадров в отдельном потоке, чтобы улучшить FPS за счет уменьшения задержки ввода/вывода, посколькуcv2.VideoCapture()
блокирует. Благодаря выделению независимого потока только для захвата кадров, это позволит основному потоку обработки всегда иметь доступный кадр для обнаружения. - Поток № 2 - основной поток обработки/обнаружения для обнаружения логотипа FedEx с использованием цветового порога и определения контура.
Общий псевдо-алгоритм
For each frame:
Find bounding box for purple color of logo
Find bounding box for red/orange color of logo
If both bounding boxes are valid/adjacent and contours pass checks:
Combine bounding boxes
Draw combined bounding boxes on original frame
Play sound notification for detected logo
Цветовой порог для определения логотипа
Для определения порога цвета я определил пороговые значения HSV (низкий, высокий) для фиолетового и красного для определения логотипа.
colors = {
'purple': ([120,45,45], [150,255,255]),
'red': ([0,130,0], [15,255,255])
}
Чтобы найти координаты ограничительной рамки для каждого цвета, я следую этому алгоритму:
- Размытие кадра
- Эрозия и расширение кадра с ядром, чтобы удалить фоновый шум
- Конвертировать кадр из цветного формата BGR в HSV
- Выполните маску на кадре, используя нижнюю и верхнюю границы цвета HSV с установленными цветовыми порогами
- Найти самый большой контур в маске и получить ограничивающие координаты
После выполнения маски я получаю эти изолированные фиолетовые (слева) и красные (справа) разделы логотипа.
Ложные положительные проверки
Теперь, когда у меня есть две маски, я выполняю проверки, чтобы убедиться, что найденные ограничивающие рамки действительно образуют логотип. Для этого я использую cv2.matchShapes()
который сравнивает два контура и возвращает показатель, показывающий сходство. Чем ниже результат, тем выше совпадение. Кроме того, я использую cv2.pointPolygonTest()
который находит кратчайшее расстояние между точкой на изображении и контуром для дополнительной проверки. Мой ложный положительный процесс включает в себя:
- Проверка правильности ограничивающих рамок
- Обеспечение того, чтобы два ограничивающих прямоугольника были смежными в зависимости от их относительной близости
Если ограничивающие блоки проходят тест на метрику смежности и сходства, ограничивающие блоки объединяются и запускается уведомление FedEx.
Результаты
Этот алгоритм проверки не очень надежен, так как существует много ложных срабатываний и неудачных обнаружений. Например, эти ложные срабатывания были вызваны.
Хотя этот подход к определению цветовых порогов и контуров работал в основных случаях, когда логотип был четким, в некоторых областях его не хватало:
- Есть проблемы с задержкой из-за необходимости вычисления ограничивающих рамок на каждом кадре
- Иногда ложно обнаруживает, когда логотипа нет
- Яркость и время суток оказали большое влияние на точность обнаружения
- Когда логотип был перекошен, обнаружение порога цвета работало, но не удалось обнаружить логотип из-за алгоритма проверки.
Кто-нибудь сможет помочь мне улучшить мой алгоритм или предложить альтернативные стратегии обнаружения? Есть ли другой способ выполнить это обнаружение, так как пороговое значение цвета сильно зависит от точной калибровки? Если возможно, я бы хотел отойти от порогового цвета и нескольких слоев фильтров, так как он не очень надежен. Любое понимание или совет с благодарностью!