При разработке и тестировании алгоритмов видеоаналитики мы используем большие наборы видео, которые воспроизводят все возможные ситуации с помехами — мухи, птички, облачка, дождик, сильный ветер, день ночь и т.д. (сутки видео с сотнями, а иногда и тысячами различных ситуаций). И естественно в алгоритмах мы не можем затачиваться под конкретное видео, так как это приведет к тому, что на других видео качество резко упадет. Мы еще 5 лет назад успешно прошли тесты ILIDS (у нас есть соответствующий сертификат от министерства внутренних дел Великобритании), которые воспроизводят эти все эти ситуации.
Прежде чем писать обличительные статьи, рекомендую сначала ознакомиться с предметной областью.
Компания Синезис делает не одну универсальную видеоаналитику для работы во всех возможных условиях, а несколько различных модулей для конкретных специфических условиях. То, что вы привели в обзоре — это ДЕТЕКТОР ДВИЖЕНИЯ — простейший алгоритм, который в большинстве случаев не требует настройки. Он специально создавался из более продвинутого уличного детектора путем упрощения и отбрасывания всего сложного, что требует настройки.
Типичное время адаптации алгоритма в ситуации (в темной комнате включили свет) — до 10 секунд. Для более плавного изменения освещенности (солнце зашло за облачко) — алгоритмы адаптируются на ходу без потери трекинга объектов.
По поводу фильтрации ложных объектов — мы не утверждаем, что фильтруем 100 процентов ложных срабатываний, однако фильтрация 90-95% ложных срабатываний уже делает наши алгоритмы практически применимыми. Все равно срабатывания детектора на конечном этапе как правило проверяются живым оператором.
Конечно можно основывать работу алгоритмов на детектировании на видео конкретных объектов путем работы различных детекторов, однако такой подход тоже имеет недостатки — низкая производительность, чувствительность только к узкому классу объектов (а реальность очень разнообразна). Так что для каждого задачи нужен свой подход. Пока не льзя сказать, что один подход однозначно лучше другого.
У нас собственные наработки — анализируется поведение фона на достаточно большом отрезке времени для каждого признака (серое изображение, градиент и т.д.), затем мы строим нижнюю и верхнюю границу таким образом, чтобы большинство значений лежало внутри этого интервала. Сигналом считается все то, что лежит за верхними и нижними границами. Использование в качестве признаков градиентов с усилением позволяет нам детектировать малоконтрастные объекты (поэтому как правило у нас нет проблем с со светлыми объектами на светлом фоне и темными на темном, исключая конечно ситуацию, когда и живой оператор начинает сомневаться). Использование многомасштабных признаков позволяет нам быть эффективнее связывать части слабоконтрастных объектов между собой, а также делает алгоритмы сегментации более эффективными в плане вычислений. Ну и мы активно используем SIMD инструкции процессоров для оптимизации вычислений — в среднем получается в 9 раз быстрее, чем без них.
P.S. Если интересно, то могу написать отдельную статью про это.
Здравствуйте. Хотелось бы сделать пару замечаний по поводу вашего анализа видеоаналитики от компании Синезис.
Да, многие алгоритмы видеоаналитики компании Синезис используют принцип выделение подвижных объектов на неподвижном фоне. Однако, думать, что алгоритмы только на этом и оканчиваются — это очень упрощенное представление. Так, мы используем адаптирующуюся модель фона, которая достаточно быстро подстраивается под изменения освещенности и прочие изменения на сцене. Хотя наши алгоритмы и не осуществляют распознавания всех объектов на сцене, однако мы применяем различные методики по минимизации ложных срабатываний от различных помех, характерных для уличного видеонаблюдения: насекомые, птицы, изменения освещенности, атмосферные осадки и прочее. Без этого наши алгоритмы были бы практически не применимы. И автор бы сам заметил бы это, если бы лучше проанализировал наши продукты.
К стати, синий квадратик на экране, который вы привели — это не еще одна зона, и минимальный размер объекта для детекции. И естественно, что уровни чувствительности не надо подбирать отдельно для ночи и дня — алгоритм сам прекрасно адаптируется.
По поводу OpenCV — это безусловно очень полезная библиотека компьютерного зрения и мы отдельные ее элементы иногда используем в своих проектах, однако в большинстве случаев без существенной доработки ее нельзя использовать в коммерческих решениях по соображениям точности и производительности.
С глубочайшим уважением, начальник отдела машинного зрения компании Синезис, Игорь Ермолаев.
Так как я занимаюсь оптимизацией алгоритмов обработки изображений, то меня особенно интересует работа с 16-bit и 8-bit целыми значениями. Поэтому мне приходится активно использовать SSE2, SSSE3, SSE4.1 и AVX2 векторные расширения. На сколько я понял из документации, в AVX-512 есть только операции для работы с целыми 64-bit и 32-bit числами.
Вопрос: когда стоит ожидать появление в процессорах Intel 512-bit векторов с поддержкой операций с 16-bit и 8-bit целыми значениями?
P.S. Мы оба правы. Радиус гауссова фильтра растет как корень квадратный от количества последовательного примененных фильтров. Но радиус окна фильтра растет линейно до тех пор, пока мы не начинаем пренебрегать его крайними значениями.
применение фильтра 3х3 два раза подряд приводит к увеличению окна на один пиксел в каждую сторону, соответственно на 2 пикселя всего. 3x3 + 3x3 = 5x5. и т.д.
Есть замечательное свойство фильтра Гаусса — вместо расчета один раз окном 9x9 можно применить последовательно 4 раза фильтр Гаусса с окном 3x3 и получить тот же результат (если конечно не учитывать ошибки округления).
Как не сложно подсчитать в первом случае будет порядка 81 операций сложения и умножения, а во втором только 36.
Зато второй вариант хуже параллелится и более требователен к пропускной способности памяти (ну и конечно гораздо менее показателен в плане прироста производительности GPU по сравнению с CPU).
Для сравнения результаты работы Гауссова фильтра размера 3x3 для RGB картинки на CPU (i7-4770).
Для корректности сравнения нужно умножить результаты на 4:
Scalar — 3.4 ms, SSE2 — 0.53 ms, AVX2 — 0.28 ms.
По итогу — код на CPU фактически в 10 раз быстрее кода на GPU и это даже без учета необходимости копирования данных. Тут к стати отдельный вопрос почему автор не ипользует ::cudaMallocHost для аллокации памяти на хосте. Это на порядок повысит скорость копирования данных на устройство.
Операционную систему, версию компилятора, версии OpenMP и CUDA… в общем все то, что может потребоваться для воспроизведения результатов, которые вы измерили.
Если вы приводите в тексте конкретное время расчета задачи в миллисекундах, то наверное нужно обязательно указать также аппаратную и программную конфигурацию машины на которой эти расчеты были выполнены, а еще размер тестовых данных.
Первое стоит отметить, что в реальности при конвертации BGRA -> Gray обычно ведут расчет в целых числах.
Так же ради интереса запустил функцию преобразования BGRA -> Gray, которая работает на одном ядре i7-4770. Получил следующие результаты:
Scalar version — 54.7 ms.
SSE2 version — 20.9 ms.
AVX2 version — 19.0 ms.
Вывод — задача явно упирается в пропускную способность памяти даже для CPU. Иначе говоря, слишком мало вычислений на каждый пиксель, что бы было оправдано использование GPU, хотя наверное и подойдет как учебный пример.
Как-то пытался по сходному алгоритму детектировать по цвету униформы персонал (магазины) на видео. В целом результат получился не совсем удовлетворительным. Основные проблемы: 1) Внешнее освещение сильно влияет на цвет объекта. Тон (hue) объекта вариабелен меньше всего, но тоже существенно. 2) При сегментации объекта возможны ошибки с выделением его границ. 3) В объекте, особенно при виде сверху, видна не только униформа, но и волосы, кожа и другая одежда — что дополнительно осложняет анализ.
Из полезного от того проекта осталось разве что функция быстрого получения Hue компоненты пространства (HSV) из YUV420p. Реализация, если что здесь.
Я использовал тесты производительности встроенные в библиотеку Simd. Хотя вы правы: в качестве тестов там используется серая картинка в разрешении Full HD размеров 2 MB. Так как все данные влазят в процессорный кеш, то получается выигрыш в 20-25 раз. Если размер тестовой картинки увеличить, то выигрыш от оптимизации будет всего 7.5 раз и для SSE2 и для AVX2 кода — все упрется в шину данных. Но честно говоря в моем случае (видеоаналитика), данных обычно не так много — часто все влезает в кеш.
По моим данным выигрыш от для данного примера на SSE2 получается порядка 22-25 раз.
К стати, у вас в коде довольно нелогично — вы используете выровненные массивы данных, но при этом для чтения из них используете функцию _mm_loadu_si128, которая вдвое медленнее чем _mm_load_si128. На одном этом теряете порядка 20% производительности.
С разворачиванием цикла (если опустить вопрос о ее целесообразности для кода с SIMD инструкциями — ибо процессор может одновременно исполнить не более двух векторных инструкций за такт) тоже не все гладко — если операции _mm_loadu_si128 и _mm_sad_epu8 у вас потенциально могут исполняться одновременно, то функции _mm_add_epi32 (к стати почему не _mm_add_epi64 ?) работают с oдной переменной sum — что может поставить компилятор в тупик (код с его точки зрения может выглядеть последовательным).
Прежде чем писать обличительные статьи, рекомендую сначала ознакомиться с предметной областью.
Типичное время адаптации алгоритма в ситуации (в темной комнате включили свет) — до 10 секунд. Для более плавного изменения освещенности (солнце зашло за облачко) — алгоритмы адаптируются на ходу без потери трекинга объектов.
По поводу фильтрации ложных объектов — мы не утверждаем, что фильтруем 100 процентов ложных срабатываний, однако фильтрация 90-95% ложных срабатываний уже делает наши алгоритмы практически применимыми. Все равно срабатывания детектора на конечном этапе как правило проверяются живым оператором.
Конечно можно основывать работу алгоритмов на детектировании на видео конкретных объектов путем работы различных детекторов, однако такой подход тоже имеет недостатки — низкая производительность, чувствительность только к узкому классу объектов (а реальность очень разнообразна). Так что для каждого задачи нужен свой подход. Пока не льзя сказать, что один подход однозначно лучше другого.
P.S. Если интересно, то могу написать отдельную статью про это.
Да, многие алгоритмы видеоаналитики компании Синезис используют принцип выделение подвижных объектов на неподвижном фоне. Однако, думать, что алгоритмы только на этом и оканчиваются — это очень упрощенное представление. Так, мы используем адаптирующуюся модель фона, которая достаточно быстро подстраивается под изменения освещенности и прочие изменения на сцене. Хотя наши алгоритмы и не осуществляют распознавания всех объектов на сцене, однако мы применяем различные методики по минимизации ложных срабатываний от различных помех, характерных для уличного видеонаблюдения: насекомые, птицы, изменения освещенности, атмосферные осадки и прочее. Без этого наши алгоритмы были бы практически не применимы. И автор бы сам заметил бы это, если бы лучше проанализировал наши продукты.
К стати, синий квадратик на экране, который вы привели — это не еще одна зона, и минимальный размер объекта для детекции. И естественно, что уровни чувствительности не надо подбирать отдельно для ночи и дня — алгоритм сам прекрасно адаптируется.
По поводу OpenCV — это безусловно очень полезная библиотека компьютерного зрения и мы отдельные ее элементы иногда используем в своих проектах, однако в большинстве случаев без существенной доработки ее нельзя использовать в коммерческих решениях по соображениям точности и производительности.
С глубочайшим уважением, начальник отдела машинного зрения компании Синезис, Игорь Ермолаев.
Вопрос: когда стоит ожидать появление в процессорах Intel 512-bit векторов с поддержкой операций с 16-bit и 8-bit целыми значениями?
P.S. Совсем не обязательно было привязывать скотчем сливы к моему цветку.
применение фильтра 3х3 два раза подряд приводит к увеличению окна на один пиксел в каждую сторону, соответственно на 2 пикселя всего. 3x3 + 3x3 = 5x5. и т.д.
Как не сложно подсчитать в первом случае будет порядка 81 операций сложения и умножения, а во втором только 36.
Зато второй вариант хуже параллелится и более требователен к пропускной способности памяти (ну и конечно гораздо менее показателен в плане прироста производительности GPU по сравнению с CPU).
Для сравнения результаты работы Гауссова фильтра размера 3x3 для RGB картинки на CPU (i7-4770).
Scalar — 0.853 ms, SSE2 — 0.132 ms, AVX2 — 0.069 ms.
Для корректности сравнения нужно умножить результаты на 4:
Scalar — 3.4 ms, SSE2 — 0.53 ms, AVX2 — 0.28 ms.
По итогу — код на CPU фактически в 10 раз быстрее кода на GPU и это даже без учета необходимости копирования данных. Тут к стати отдельный вопрос почему автор не ипользует ::cudaMallocHost для аллокации памяти на хосте. Это на порядок повысит скорость копирования данных на устройство.
Так же ради интереса запустил функцию преобразования BGRA -> Gray, которая работает на одном ядре i7-4770. Получил следующие результаты:
Scalar version — 54.7 ms.
SSE2 version — 20.9 ms.
AVX2 version — 19.0 ms.
Вывод — задача явно упирается в пропускную способность памяти даже для CPU. Иначе говоря, слишком мало вычислений на каждый пиксель, что бы было оправдано использование GPU, хотя наверное и подойдет как учебный пример.
Из полезного от того проекта осталось разве что функция быстрого получения Hue компоненты пространства (HSV) из YUV420p. Реализация, если что здесь.
К стати, у вас в коде довольно нелогично — вы используете выровненные массивы данных, но при этом для чтения из них используете функцию _mm_loadu_si128, которая вдвое медленнее чем _mm_load_si128. На одном этом теряете порядка 20% производительности.
С разворачиванием цикла (если опустить вопрос о ее целесообразности для кода с SIMD инструкциями — ибо процессор может одновременно исполнить не более двух векторных инструкций за такт) тоже не все гладко — если операции _mm_loadu_si128 и _mm_sad_epu8 у вас потенциально могут исполняться одновременно, то функции _mm_add_epi32 (к стати почему не _mm_add_epi64 ?) работают с oдной переменной sum — что может поставить компилятор в тупик (код с его точки зрения может выглядеть последовательным).