В предыдущей статье мы рассказали о том, как появилась идея собственного решения и об истории создания нашего измерительного устройства.

Во второй части мы сосредоточимся на технической стороне проекта: разберём алгоритмы измерения и инженерные решения, которые позволили добиться высоких точности и скорости замеров. Мы также поделимся опытом преодоления ключевых технических вызовов и расскажем, как пришли к текущему виду устройства.

Зачем разрабатывать собственный измеритель, если на рынке уже есть готовые решения?

Проект был необходим по причине специфики логистических процессов Ozon. Стандартные устройства, такие как лидары, ультразвуковые датчики и механические весы, имеют существенные ограничения. Лидары дороги и чувствительны к пыли и особенностям поверхностей, ультразвук плохо справляется с измерением мягких и неровных объектов, а механические устройства не масштабируются и требуют участия человека.

Мы провели анализ существующих технологий и пришли к выводу, что лучшим решением станет система на базе стереокамер в сочетании с моделями машинного обучения. Такой подход позволяет обеспечить универсальность, надёжность и высокую скорость измерений при работе с самыми разными типами товаров.

Сегодня мы имеем целую линейку устройств, спроектированных для решения разных задач и для разных типов товаров. Мы не только производим их, но и интегрируем в склады Ozon, где они активно используются для автоматизации и оптимизации логистических процессов.

Знакомьтесь! Это устройство для измерения объемно-весовых  характеристик (ОВХ) товаров, которое разработала команда Ozon.

Алгоритмы. Как всё устроено

Прежде чем углубляться в алгоритмы, давайте вспомним конструкцию устройства и типы сенсоров, которые мы используем. Это поможет лучше понять, как работает система и почему мы выбрали именно такие компоненты для решения наших задач.

Для определения габаритов товаров мы используем:

  1. Две стереокамеры Intel RealSense, установленные в углах устройства, для получения 3D-модели объекта.

  2. Одну веб-камеру, размещённую в центре верхней плоскости (см. рисунок), для получения изображений объекта измерения сверху.

Такое расположение сенсоров позволяет получать точные данные о размерах объектов с разных ракурсов, что значительно повышает точность измерений и помогает в создании трёхмерных моделей товаров.

Теперь, когда мы вспомнили устройство аппаратной части проекта, давайте перейдём к алгоритмам. Система, рассчитывающая ОВХ товаров, написана на Python. Несмотря на то что Python немного медленнее компилируемых языков, использование библиотек OpenCV, NumPy, Open3D и JIT-компиляции минимизирует издержки, обеспечивая при этом быструю разработку и отладку.

Программа получает на вход изображения с камер глубины, обрабатывает их и выдаёт результат в виде габаритов объекта. Данные с каждой камеры конвертируются в 3D-облака точек, которые затем объединяются. При этом используются параметры внутренней калибровки камер (intrinsics), а для корректного совмещения данных необходимо учитывать положение и ориентацию камер относительно общей системы координат (extrinsics).

После формирования единого облака точек система приступает к анализу параметров объекта. Определение высоты — самая простая часть: достаточно найти самую высокую точку в облаке и зафиксировать её координату.

Определение длины и ширины устроено сложнее. Здесь алгоритм разделяется на два подхода (см. рисунок). Если объект имеет сложную форму, используется его 3D-модель, построенная на основе облака точек. В случае с плоскими предметами, такими как коробки или книги, применяется другой метод: программа анализирует фото с веб-камеры, выполняет сегментацию изображения и определяет размеры объекта. Такой комбинированный подход позволяет учитывать особенности разных типов товаров и добиваться высокой точности измерений.

Логика использования алгоритмов измерения длины и ширины товара.
Логика использования алгоритмов измерения длины и ширины товара.

Качество построения карты глубины и облака точек

Как работает камера Intel RealSense D415

Представьте, что вам нужно определить расстояние до объектов, но у вас нет измерительных инструментов — есть только глаза. Как понять, насколько далеко находится тот или иной предмет? Человеческий мозг справляется с этим благодаря стереозрению: два глаза видят одну и ту же сцену с небольшим смещением, и мозг вычисляет глубину (третье измерение) из двух 2D-изображений. Примерно так же работает и стереокамера Intel RealSense D415.

Принцип работы стереозрения. Объекты 1 и 2 расположены на разном расстоянии от стереопары и поэтому имеют разное смещение на левом и правом изображениях.
Принцип работы стереозрения. Объекты 1 и 2 расположены на разном расстоянии от стереопары и поэтому имеют разное смещение на левом и правом изображениях.

У D415 есть две инфракрасные камеры, расположенные на небольшом расстоянии друг от друга. Они фиксируют сцену с двух ракурсов, подобно тому, как делают это наши глаза. Вместе с ними работает RGB-камера, которая фиксирует цветное изображение. Но как из этих снимков получается информация о глубине? Здесь в дело вступает принцип стерео-диспарности (stereo disparity) — разница между положением одного и того же объекта на левом и правом изображениях. Чем больше эта разница, тем ближе объект. Камера анализирует различие и строит так называемую карту несоответствий — disparity map.

Когда камера получает стереоснимки, встроенный процессор запускает алгоритм Semi-Global Matching (SGM, полуглобальный способ), который сопоставляет пиксели на обоих изображениях и определяет смещение. После этого система преобразует полученные данные в реальные расстояния, создавая карту глубины. Хотя точная реализация алгоритма матчинга не раскрывается, часть информации можно найти в вайт пейперах на официальном сайте и в статье про RealSense, представленной на конференции CVPR 2017.

Однако сырые данные не идеальны: они содержат шумы, артефакты и погрешности, особенно на границах объектов и в сложных сценах. Это происходит из-за ошибок в алгоритме сопоставления пикселей и аппаратных ограничений сенсоров. Качество карты  глубины напрямую влияет на точность измерений. Шумы могут приводить к ошибкам при расчёте габаритов.

Стереокартинка, сгенерированная из паттерна и объекта в онлайн-сервисе.
Стереокартинка, сгенерированная из паттерна и объекта в онлайн-сервисе.

Проблема №1. Шумные данные

Фильтрация

Для повышения точности измерений необходима дополнительная постобработка облака точек. Мы применяем фильтрацию, устранение артефактов и методы улучшения облака точек, которые помогают добиться более стабильных и достоверных измерений. Рассмотрим, какие техники позволили нам улучшить результаты и минимизировать ошибки:

  1. В камеры Intel RealSense встроена поддержка Temporal Filtering (временная фильтрация), которую можно включить через librealsense SDK.
    Temporal Filtering сглаживает случайные колебания глубины, анализируя информацию с нескольких кадров. Даже если сцена неподвижна, измеренные расстояния могут немного меняться от кадра к кадру. По нашим данным, на расстоянии 850 мм средняя ошибка измерения составляет 3 мм. Однако на множестве кадров распределение ошибки измерения (или погрешность измерения) аппроксимируется нормальным законом. Если глубина пикселя резко меняется на одном кадре, но стабильна на остальных, скорее всего, это изменение является ошибкой. Фильтр сравнивает текущие данные с предыдущими и подавляет шум, заменяя нестабильные значения усреднёнными или предсказанными по тренду. Можно настраивать степень сглаживания, балансируя между точностью и скоростью реакции.

    Если запускать пример box dimensioner multicam из официального репозитория для SDK, то стоит учесть, что Temporal Filtering там не работает, так как объект Temporal Filtering создаётся заново каждый раз при обработке фрейма и история не успевает накопиться (актуально на момент публикации статьи). Мы тестировали разный размер буфера для фильтра и пришли к тому, что семь фреймов — оптимальное количество для баланса точности и скорости.

  2. Мы также используем доступный в Intel RealSense SDK Spatial Filtering (пространственная фильтрация). Он сглаживает резкие скачки карты глубины и устраняет артефакты, корректируя каждый пиксель карты глубины с учётом соседних пикселей. В отличие от простого усреднения, фильтр сохраняет резкие границы, что важно при измерении объектов. Temporal Filtering убирает шум от кадра к кадру, а Spatial Filtering сглаживает артефакты на одном кадре. В итоге камера выдаёт детализированную карту глубины, где каждый пиксель имеет своё расстояние до объекта.

Кластеризация

После объединения изображений с двух камер глубины мы получаем 3D-облако точек. Далее мы можем применить кластеризацию, этот метод позволяет группировать точки на основе близости друг к другу, чтобы выделять объекты, сегментировать сцену и фильтровать шум. Его использование показалось нам заманчивой идеей как способ выделить точки, принадлежащие измеряемому предмету, и одновременно избавиться от выбросов.

В Open3D реализован один из самых популярных алгоритмов кластеризации — DBSCAN (Density-Based Spatial Clustering of Applications with Noise, алгоритм кластеризации, основанный  на плотности, для приложений с шумами), который находит плотные области в пространстве.

Алгоритму нужно задать два параметра: расстояние до соседей в кластере (eps) и минимальное количество точек в кластере (min_points). Время его работы с параметрами eps = 0,01 и min_points = 10 в облаке из 100 000 точек размером составило 35 секунд. Запускали на Raspberry Pi 4 Model B. Мы отказались от использования данного метода, поскольку он не давал ощутимого улучшения точности измерения, а время обработки при этом увеличивалось значительно.

TSDF (Truncated Signed Distance Function, усеченная функция расстояния со знаком)

TSDF — это метод, используемый для построения 3D-моделей из RGBD-данных (Red, Green, Blue, Depth, данные как о цвете (RGB), так и о глубине (D)). Он основан на использовании усечённой функции знакового расстояния: для каждой точки (вокселя) в 3D-пространстве рассчитывается расстояние до ближайшей поверхности объекта. В отличие от стандартных алгоритмов, которые хранят только значения глубины, TSDF хранит знаковое расстояние (положительное — перед поверхностью, отрицательное — за ней), но только в пределах заданного (усечённого) диапазона. Значения вне этого диапазона отбрасываются.

Этапы работы TSDF  
1. Инициализация

Пространство заранее разбивается на регулярную сетку вокселей. Изначально каждый воксель не содержит полезной информации (часто инициализируется нулями или специальным значением, например «Неизвестно»).

2. Обработка глубинного изображения

Для каждой точки на карте глубины вычисляется её положение в мировых координатах (по камере и калибровке). Точка представляет поверхность, до которой будет вычисляться расстояние. Затем для каждого вокселя вдоль луча, проходящего от камеры к точке, рассчитывается подписанное расстояние до поверхности:

  • положительное — если воксель находится перед поверхностью,

  • отрицательное — если воксель находится за поверхностью,

  • равное нулю — если воксель лежит на поверхности.

3. Усечение (truncation)

Чтобы избежать хранения нерелевантной информации, расстояния обрезаются по заданному порогу (truncate threshold). Если расстояние больше порога по модулю, оно не записывается.

4. Агрегация данных

При поступлении новых кадров (с разных ракурсов) воксели обновляются с помощью взвешенного усреднения. Это помогает сгладить шум, убрать артефакты и повысить точность реконструкции.

5. Извлечение поверхности

После построения TSDF-поля применяется алгоритм Marching Cubes, чтобы извлечь модель поверхности из поля расстояний. Воксели, где TSDF-переход меняет знак (от + к −), считаются границей поверхности и превращаются в сетку (mesh) или облако точек.

Преимущества использования TSDF:

  • усреднение данных позволяет уменьшить шум и улучшить качество модели;

  • исключение данных за пределами поверхности объекта и усечение значений позволяют уменьшить объём хранимых данных и улучшить производительность вычислений.

Недостатком метода является необходимость большого количества вычислительных ресурсов для обработки всех точек.

Для улучшения производительности алгоритм можно ускорить, исключив подсчёт вокселей вне зоны интереса (ROI), что позволяет уменьшить вычислительную нагрузку и увеличить скорость обработки данных. В результате использования TSDF можно получить высококачественные 3D-модели — при значительном уменьшении объёма данных, улучшении сглаживания и повышении точности.

Внедрение этого алгоритма дало неплохие результаты. Но они могли бы быть ещё лучше, если бы мы использовали больше двух камер.

Демонстрация работы TSDF. Объединение двух изображений глубины, глубина  рассчитана нейронкой IGEV-Stereo.
Демонстрация работы TSDF. Объединение двух изображений глубины, глубина  рассчитана нейронкой IGEV-Stereo.
Демонстрация работы TSDF. Объединение четырёх изображений глубины, карты глубины получены с камеры RealSense D415. Съёмка объекта 315 мм х 262 мм х 214 мм с высоты 3 м.
Демонстрация работы TSDF. Объединение четырёх изображений глубины, карты глубины получены с камеры RealSense D415. Съёмка объекта 315 мм х 262 мм х 214 мм с высоты 3 м.

Здесь можно заметить, что классический алгоритм получения облака точек сохраняет выбросы, также есть шумы у краёв объектов. TSDF помогает бороться с этим.

Фильтрация облака точек морфологическими операциями

Морфологические операции — это методы обработки изображений, которые работают с формами объектов и помогают улучшать качество изображений, устранять шум, заполнять пробелы и выделять ключевые структуры. Этими методами мы фильтруем шумы 3D-облака точек, вызванные переотражением от внешних и внутренних блестящих объектов.

Два основных метода морфологической обработки изображений — эрозия и дилатация. Их сочетания образуют более сложные операции: открытие, закрытие и градиент.

  1. Эрозия (erosion) используется для устранения мелких артефактов. Этот метод сужает границы объектов на изображении и удаляет небольшие шумовые пиксели.

  2. Дилатация (dilation) используется для заполнения пробелов и соединения разорванных элементов — расширяет границы объектов.

  3. Открытие (opening) = эрозия + дилатация. Удаляет мелкие шумы, сохраняя основные объекты. Это, например, помогает убрать случайные точки на изображении.

  4. Закрытие (closing) = дилатация + эрозия. Заполняет небольшие разрывы внутри объектов. Устраняет мелкие «дыры» в изображении.

  5. Градиент (morphological gradient) помогает выделять контуры объектов. Вычисляет разницу между дилатированным и эродированным изображением.

Мы применяем эти операции перед расчётом длины и ширины предмета. Полученная 3D-модель предмета проецируется на горизонтальную плоскость, и затем к ней применяются морфологические операции.

Аналогично можно получить и отфильтрованные вертикальные проекции, которые пригодятся для точного расчёта высоты предмета.

Проблема №2. Блики на изображении от инфракрасного прожектора

Как вы помните, в нашем устройстве используются две камеры глубины с ИК-прожекторами, расположенные друг напротив друга. ИК-прожекторы проецируют определённый паттерн на объект измерения, это помогает камере получать больше данных о геометрии объекта и повышать точность построения карты.

Однако в некоторых случаях камеры могут засвечивать друг друга прожекторами, особенно если поверхность измеряемого предмета хорошо отражает свет.

Чтобы исключить этот эффект, мы реализовали поочерёдное включение лазеров во время измерения. Сначала первая камера делает снимок, затем её лазер отключается, включается противоположный, и вторая камера выполняет свою работу. Такой подход позволяет минимизировать взаимные помехи и улучшить качество карт глубины.

Иллюстрация процесса отражения света от лазерного проектора.
Иллюстрация процесса отражения света от лазерного проектора.
Пример отражения света от лазерного проектора.
Пример отражения света от лазерного проектора.
Результат при поочерёдном включении лазеров. Предмет больше не засвечивается.
Результат при поочерёдном включении лазеров. Предмет больше не засвечивается.

Однако важно учитывать, что такой подход уменьшает скорость сбора кадров глубины, что может стать критически важным при использовании более двух камер. Например, в устройстве с четырьмя камерами глубины время получения полного набора данных увеличивается примерно в 2,5 раза.

В подобных случаях оптимального баланса между скоростью и качеством можно достичь, подняв камеры выше и уменьшив мощность ИК-прожекторов. В сочетании эти меры позволяют уменьшить зашумленность карт глубины, сохраняя достаточную точность измерений. Как демонстрируют экспериментальные данные на приведённом ниже изображении, параллельный захват кадров при пониженной мощности прожектора обеспечивает качество карт глубины, сопоставимое с результатами поочерёдного захвата при повышенной мощности прожектора.

Проблема №3. Влияние качества освещения на карты глубины

Качество освещения играет ключевую роль в точности карт глубины, создаваемых стереокамерами. Однако освещение сцены может как помочь, так и помешать точному построению.

Негативное влияние плохого освещения

  1. Низкая текстурированность сцены. Если объект или фон обладают низкой текстурной детализацией (например, имеют однотонную или белую поверхность), алгоритмы сопоставления кадров могут испытывать трудности с определением глубины. Это приводит к увеличению уровня шума и появлению разрывов на карте глубины, снижая точность измерений.

    Мы экспериментировали с использованием внешних текстурированных паттернов для улучшения качества карт глубины на гладких поверхностях, чтобы не полагаться исключительно на встроенную ИК-подсветку. Однако этот подход не дал значительного улучшения. Встроенной подсветки в нашем сетапе, где расстояние от камеры до объекта меньше 1 м, оказывается достаточно. А если глубину всё-таки не удалось определить, то и внешняя подсветка не поможет. Данная проблема не оказалась для нас критичной, поскольку в системе предусмотрен альтернативный алгоритм, способный эффективно справляться с измерением любых типов объектов. Подробнее о его работе я расскажу далее.

  2. Избыток ИК света может существенно повлиять на качество работы камеры. Хотя устройство оснащено встроенной ИК-подсветкой для повышения точности измерений, внешние ИК-источники, такие как солнечный свет или мощные инфракрасные лампы, могут вызывать засветы и артефакты, снижая точность карт глубины.

    Чтобы минимизировать это влияние, мы покрыли устройство светонепроницаемым материалом, защитив его от постороннего освещения. Важно правильно выбирать место установки — камера не должна находиться вблизи окон и других зон досягаемости прямых солнечных лучей. Также мы дополнительно оснастили камеру специальными ИК-линзами, которые блокируют RGB-диапазон на инфракрасных сенсорах, что позволило уменьшить влияние нежелательных оптических помех.

  3. Резкие тени и блики. Высокая контрастность сцены может вызывать артефакты, так как алгоритмы могут интерпретировать резкие перепады яркости как изменения глубины. Мы используем рассеянный свет вместо направленного, чтобы избежать появления резких теней. На рисунке вы можете увидеть разницу разницу между картами глубины с разными источниками света.

Таким образом, правильная настройка освещения и учёт его влияния на карты глубины значительно повысили точность карт глубины, улучшив качество измерений и уменьшив количество артефактов.

Проблема №4. «Хвосты» на границах объектов

На полученных картах наблюдается эффект сглаживания глубины на границах объектов. Это приводит к появлению характерных «хвостов» — участков, где глубина искажается, создавая ложные данные за пределами реального объекта. Таким образом, в местах перехода объекта к фону вместо чётких границ возникает градиент глубины.

https://github.com/IntelRealSense/librealsense/issues/3741

Почему же так происходит? Это может быть вызвано следующими причинами:

  • Интерполяция данных на границах. В алгоритмах построения карты глубины применяются методы сглаживания, которые усредняют глубину соседних пикселей. Это помогает бороться с шумами, но размывает контуры объектов.

  • Ошибка disparity. В местах с резкими перепадами глубины стереокамера может испытывать трудности с точным вычислением глубины, из-за чего появляются артефакты.

  • Обработка окклюзий. Когда один объект частично перекрывает другой, алгоритм может «додумывать» отсутствующие данные, создавая ложные пиксели глубины, вытягивающиеся за границы объекта.

  • Разрешение сенсоров. Чем ниже разрешение карты глубины, тем сильнее проявляется эффект «хвостов», так как камера не может точно определить резкий перепад глубины.

Один из простых, но эффективных способов уменьшить эффект размытых границ на карте глубины — использование трешхолда (thresholding). Это метод, который позволяет отсеивать некорректные данные. Мы установили минимальный порог глубины — 15 мм. Мы считаем точки на высоте ниже 15 мм артефактами и удаляем их. В таком подходе есть свой плюс: мы не раздуваем габариты объекта за счёт размытых границ. Но при этом не можем измерять товары ниже этого значения.

Калибровка стереокамер

Для корректного совмещения 3D-изображений с двух камер Intel RealSense необходимо провести точную калибровку камер как относительно друг друга, так и относительно рабочей зоны измерения.

В процедуре калибровки применяется шахматная доска — паттерн со строго заданным размером клеток. Нам достаточно одной фотографии калибровочной поверхности со всех камер устройства. Паттерн нарисован на обратной стороне рабочей платформы (съёмной доски), которая кладётся на весы.

Калибровка камеры включает в себя определение внутренних и внешних параметров.

Внутренние параметры, такие как фокусные расстояния объектива и коэффициенты дисторсии, заданы изготовителем. Но их можно уточнить с помощью предоставляемых вместе с SDK утилит, а также выгрузить по API.

Калибровка внешних параметров камер позволяет определить их взаимное расположение, а также положение относительно рабочей зоны.

Данные канала глубины с камер Intel RealSense мы в этом процессе не используем, потому что есть более точный способ калибровки. Нам достаточно найти точки шахматной доски на изображениях со стереопары и вычислить смещение (disparity), а затем решить задачу Perspective-n-Point.

Алгоритм калибровки внешних параметров (повторяется для каждой стереопары)

  1. Делаем снимки каждой из двух камер стереопары устройства.

  2. Находим точки шахматной доски на обоих изображениях.

  3. Определяем положение левой камеры по фотографии с помощью метода solvePnP из OpenCV. Она считается «главной», так как глубинная карта вычисляется в системе координат левой камеры.

  4. Уточняем положение камеры с помощью дополнительной оптимизации параметров на фреймворке GTSAM. Для этого минимизируем ошибку репроекции найденных 3D-точек, но уже не только на левую камеру, а одновременно на левую и правую камеры. Результат solvePnP при этом используется как начальное значение оптимизации. Стоит добавить, что в наших условиях повышение точности калибровки на этом этапе оказалось незначительным, так что это действие опциональное.

  5. Сохраняем полученные параметры в файл калибровки.

Важно отметить, что приведённый выше способ калибровки внешних параметров через решение задачи Perspective-n-Point (по соответствиям между 3D-точками и их 2D-проекциями) точнее, чем просто матчинг 3D-точек, который используется в примерах к RealSense SDK.

Полезные советы по работе с Intel RealSense

Методом проб и ошибок мы разработали несколько рекомендаций для эффективной работы с камерами Intel RealSense:

  1. Используйте только разъёмы USB 3.0 и выше. Это указано в документации к камерам Intel RealSense.

  2. Не используйте кабели длиной более 2 м. При подключении через длинные кабели ухудшается качество питания камеры, что может привести к её отключению или программному отсоединению от приложения. Этот момент обсуждается на форуме Intel RealSense.

  3. Избегайте использования USB-хабов для подключения камер. Это может снизить стабильность работы, но не так значительно, как длинные кабели. Проблемы возникают, когда камеру или другое периферийное устройство (например, USB-сканер), подключённое через хаб, случайно дёргают или повреждают. Подключение через хаб добавляет дополнительную неявную электрическую связь между компонентами. Это может привести к перебоям в подаче питания и потере соединения.

  4. Если камера теряет соединение, попробуйте закрыть её пайплайны. Используйте метод hard_reboot() из библиотеки PyRealSense или приложения RealSense Viewer, чтобы перезагрузить камеру и заново создать пайплайны.

  5. Правильно завершайте программу, закрывая пайплайны камер. Это важно для избежания необходимости физического переподключения камеры при следующем запуске.

  6. Учтите, что в PyRealSense доступна только основная функциональность для работы с камерами. Для более точного управления используйте C++-интерфейс.

  7. Будьте готовы к багам после обновления прошивки librealsense. Intel не раз удивляла пользователей новыми багами после обновлений, и это стоит учитывать.

Хотя камеры Intel RealSense не идеальны, они остаются одними из самых удобных и эффективных инструментов на рынке для работы с 3D-данными.

Алгоритм  определения размеров по фотографии для плоских объектов

Проблема «хвостов» на границах объектов небольшой высоты приводит к погрешности в несколько миллиметров, из-за чего их границы практически сливаются с фоном и становятся трудноразличимыми. Чтобы решить эту проблему, мы дополнили систему алгоритмом, который находит контуры предметов на фотографиях. Затем контур вписывается в прямоугольник, что позволяет определить длину и ширину товара.

На этапе MVP мы использовали две камеры, установленные под углом с противоположных сторон от измеряемой области. Однако такой подход требовал применения перспективной трансформации для корректного расчёта размеров. Это работало для измерения очень тонких предметов, но в остальных случаях на изображении появлялись боковые стенки, что приводило к искажению проекции.

Чтобы устранить эту проблему, мы добавили третью камеру, расположенную сверху и сфокусированную строго на центре платформы. Так как здесь не требовалась 3D-съёмка, мы установили обычную недорогую веб-камеру.
Первоначально мы использовали классические методы компьютерного зрения, включая детектор границ Кэнни. Этот выбор был обусловлен рядом преимуществ:

  • Классические методы не требуют больших датасетов для обучения и имеют мало параметров для настройки.

  • В наших устройствах товары размещаются на стандартной белой подложке при фиксированном освещении, фокусе, экспозиции и балансе белого. Мы предполагали, что стабильность внешней среды позволит классическим алгоритмам качественно выделять объекты.

Однако на практике оказалось, что многие товары слабо контрастируют с фоном, из-за чего ни один из популярных методов выделения границ и бинаризации не давал стабильного результата. Это подтолкнуло нас к использованию методов глубокого обучения.

Мы собрали датасет с изображениями товаров на платформе, размеченными вручную, и обучили модель сегментации на основе YOLOv8n-seg. Изначально обучение проводилось на нескольких сотнях снимков, но сейчас модель натренирована на более чем 37 000 реальных фотографиях со склада. Качество машинного обучения напрямую зависит от данных, и наше преимущество заключалось в использовании реальных примеров, что позволило добиться высокой точности определения границ товаров.

Как учитывается высота предмета в алгоритме определения размеров по фотографии

Для определения размеров предмета по изображению с веб-камеры мы дополнительно используем значение его высоты, полученное с камер глубины.

Процесс включает несколько этапов:

  1. Определение границ предмета — сначала находим координаты его границ в пикселях. Поскольку предмет вписывается в прямоугольник, у нас есть четыре опорные точки.

  2. Нормализация координат — для каждой из этих точек вычисляем нормализованные координаты, используя внутренние параметры камеры.

  3. Трассировка лучей — из положения камеры в мировых координатах «простреливаем» виртуальный луч, проходящий через найденные координаты.

  4. Пересечение с плоскостью — вычисляем точку пересечения луча с плоскостью XY на заданной высоте.

P(t) = O + tD

Где:

P(t) — это точка на луче при заданном параметре;

O  — это источник луча, в данном случае — положение камеры в мировых координатах;

D — это вектор направления луча в мировых координатах;

t  — скалярный параметр.

Проблема 5. Data dDrift при аппаратных изменениях системы

Data drift — это изменение распределения входных данных со временем, которое может негативно сказаться на качестве работы модели машинного обучения. В нашем проекте одной из ключевых причин дрифта данных являются аппаратные изменения, такие как изменения габаритов устройства и параметров освещения.

Примеры аппаратных изменений и их последствия

  1. Изменение габаритов устройства

Увеличение высоты монтажа камеры относительно платформы с 600 мм до 850 мм привело к изменению фокусного расстояния. Это сказалось на качестве изображения, подаваемого в модель, и изменило перспективные искажения.

Эволюция устройства
Эволюция устройства

2. Изменение параметров источников освещения

  • Высота установки нижнего источника освещения была увеличена с 150 мм до 200 мм, что привело к изменению направления и распределения теней на объекте.

  • Цветовая температура светодиодов изменилась с 4000K до 5500K, в результате чего сместился баланс белого и общая цветовая гамма изображения.

  • Экспозиция камеры была уменьшена с 120 µs до 90 µs, что снизило яркость снимков и повлияло на контрастность.

В совокупности эти изменения модифицировали характеристики ROI-областей, подаваемых на вход нейросети. Это стало причиной ошибок при сегментации:

  • появление паразитных теней,

  • смещение и размывание границ объектов,

  • частичное наложение масок на края изображения.

Все эти факторы изменили характеристики ROI-изображения, поступающего в нейросеть, что вызвало ошибки в построении масок: появление лишних теней, некорректные границы объектов, а также частичное пересечение с краями кадра.

Поскольку такие изменения являются следствием новой конфигурации устройства, для компенсации data drift необходимо дообучение модели на обновлённом датасете. Регулярный мониторинг входных данных и своевременная адаптация модели позволяют поддерживать стабильное качество работы системы.

3. Оптимизация времени вычислений

Нам удалось уменьшить время измерения с 30 с (для первого прототипа) до 1,5 с (на текущий момент). Для значительного уменьшения времени измерения мы внесли несколько ключевых улучшений в систему.

  1. Увеличение тактовой частоты процессора.

    Тактовая частота процессора напрямую влияет на производительность, но её увеличение сопровождается повышенным энергопотреблением и нагревом. В нашем случае устройство питается от сети, а дополнительный радиатор обеспечивает эффективное охлаждение. Поэтому мы разогнали процессор Raspberry Pi с 1,5 ГГц до 2 ГГц, изменив параметры arm_freq и over_voltage в файле /boot/config.txt.

  2. Перенос расчётов нейросети в облако.

    Встроенные вычислительные мощности Raspberry Pi ограничены, что приводило к высокой задержке инференса модели сегментации — порядка нескольких секунд.

    Чтобы ускорить процесс мы вынесли сегментацию в облако, экспортировав модель в ONNX и запустив сервис в Kubernetes на платформе Ozon. Это уменьшило время обработки до 0,7 с. Дальнейшая оптимизация с использованием OpenVINO позволила уменьшить время инференса до 0,5 с.

    Таким образом, Raspberry Pi выполняет только отправку данных, а основная обработка происходит на сервере, что значительно ускоряет работу системы.

  3. Переход с Firefox на Chromium.

Для отрисовки фронтенда использовался Firefox в режиме киоска, однако его высокая нагрузка на процессор привела к необходимости сравнения с Chromium.

Мы провели эксперимент по измерению нагрузки на CPU, запустив браузер с веб-приложением, и трижды произвели измерение товара. Для оценки нагрузки использовалась команда time.

Версии браузеров:

Chromium: 116.0.5845.102 (Debian 11)

Firefox: 115.4.0esr

Результаты тестирования

Для Firefox:

  • real: 1m32.294s

  • user: 1m42.739s

  • sys: 0m9.973s

Для Chromium:

  • real: 1m50.539s

  • user: 0m14.811s

  • sys: 0m9.130s

Вывод

Разница в нагрузке на процессор оказалась пятикратной:

  • Firefox задействовал 1,1 ядра ((user + sys) / real),

  • Chromium — 0,22 ядра.

На основе этих данных было принято решение перейти на Chromium, что уменьшило нагрузку на CPU и улучшило стабильность работы системы.

Дополнительно можно провести профилирование веб-приложения, чтобы оптимизировать рендеринг Vue и заменить long polling на WebSockets для более эффективной связи с бэкендом.

4. Оптимизация получения фреймов через librealsense

Долгое время для цветного канала мы запрашивали изображение в формате RS2_FORMAT_RGB8. Однако оказалось, что librealsense неявно конвертирует изображение из YUYV в RGB8, что требует значительных вычислительных ресурсов. Этот нюанс оказался неочевидным и стал заметен только при детальном изучении документации  Frame Management.

При этом фотография требуется лишь для замера, но сам пайплайн работает в фоновом режиме постоянно, что приводит к ненужной нагрузке на процессор.

После изменения формата на YUYV нагрузка на вычислитель для процесса, управляющего кадрами, уменьшилась в пять раз. Это позволило значительно повысить общую эффективность работы системы.

График результатов оптимизации. Первое падение — это смена браузера Firefox на Chromium. Второй график — смена формата изображения c RGB8 на YUYV.
График результатов оптимизации. Первое падение — это смена браузера Firefox на Chromium. Второй график — смена формата изображения c RGB8 на YUYV.

5. Переход с малины на мини-ПК.

При масштабировании проекта было принято решение перейти с Raspberry Pi 4B на более мощную вычислительную платформу. Это дало нам следующие преимущества:

Рост производительности

Процессор на Raspberry Pi 4B

Процессор на новом ПК

Cortex-A72 (ARM v8) с частотой 1,5 ГГц, 4 ядра

Intel Core i3-12100, 3,3 ГГц, 4 ядра

Новый ПК и RPi 4B имеют по 8 Гб ОЗУ.

Ниже представлена таблица, в которой указано время выполнения некоторых операций на различных устройствах.

Устройство с RPi 4B

Устройство на новом ПК

Получение данных с камер при 6 FPS (включая запрос к сервису с нейросетью)

2,4 с

1,8 с

Перевод пикселей в миллиметры и прочая обработка фото с веб-камеры

0,03 с

< 0,01 c

Отрисовка 3D-боксов

0,3 с

< 0,01 c

Полный расчёт измерения (две камеры, без TSDF)

3,3 с

2,0 с

TSDF (две камер)

2,15 с

0,4 с

Локальное сохранение изображений

1,42 с

0,22 с

  1. Замена вычислителя значительно ускорила процесс расчёта, уменьшив его продолжительность на 65%. На новом компьютере также быстрее работает память, что особенно заметно при более быстрой загрузке и открытии новых Docker-контейнеров во время релиза.

  2. Переход на более мощный вычислитель привёл к ускорению алгоритма фильтрации TSDF в 5,375 раза. Ранее мы не использовали этот алгоритм на Raspberry Pi из-за долгого выполнения, но теперь он активно используется в системах с новым вычислителем.

  3. Мощность нового компьютера позволила повысить разрешение обрабатываемых кадров с камер глубины с 848x480 px до 1280x720 px, что соответствует разрешению HD. Это улучшение слегка повысило точность измерений, что является важным шагом в улучшении качества работы системы.

  4. Более мощный компьютер позволил нам реализовать новую модель устройства для измерения крупногабаритных товаров. В этой версии используется четыре стереокамеры.

Большее количество USB-портов

Тип USB-порта

RPi 4B

Мини ПК

USB 2.0

2

4

USB 3.2

2

4

Увеличение количества USB-портов позволило нам отказаться от использования USB-хаба. Практика показала, что периферия на устройствах без хаба имеет меньшее количество программных отсоединений в суровых условиях эксплуатации на складах.

Оптимизация работы со стереокамерами

При повышении мощности железа появляется возможность более эффективно утилизировать камеры глубины. Мы увеличили FPS c 6 до 15, что ускорило сбор кадров глубины. Конечно, более правильным является отключение и включение этого потока на лету.

ВЫВОДЫ

В рамках проекта по автоматизации измерения габаритов и веса товаров мы разработали собственный аппаратно-программный комплекс, основанный на стереокамерах и нейросетевых алгоритмах. Это решение уже активно используется на складах и в сортировочных центрах Ozon: помогает ускорить обработку товаров, уменьшить количество ошибок при измерениях и в целом повысить эффективность логистических процессов.

Сейчас мы создали линейку устройств, охватывающую весь спектр товаров — от самых компактных до крупногабаритных. В 2024 году мы запустили 126 измерительных комплексов для товаров с габаритами до 500x500x500 мм и три устройства для крупногабаритных товаров с максимальными размерами до 1500x1500x2000 мм. В 2025 году мы планируем масштабировать проект и внедрить ещё порядка 500 новых устройств.

Особое внимание мы уделили оптимизации алгоритмов — это позволило как значительно повысить точность, так и увеличить скорость измерений. Благодаря этим улучшениям наша система стабильно и быстро работает даже в условиях высокой нагрузки, что критически важно для современных логистических центров.

Мы гордимся достигнутыми результатами и продолжаем развивать решение, которое уже сейчас делает работу складов быстрее, точнее и эффективнее.

*карта глубины

Комментарии (2)


  1. U235U235
    30.05.2025 15:47

    Мне кажется, что для измерения только габаритов, проще и дешевле использовать несколько коммутируемых точечных источников света, а ч/б камерой снимать тени от них. Что-то типа веерно-лучевого преобразования, как в томографии.


    1. ahdenchik
      30.05.2025 15:47

      Отличная идея!

      Это всё напоминает историю про "Аполлон": в какой-то момент оказалось что из-за вибрации приборы в капсуле не читаются. Начали придумывать виброзащиту всей капсулы за оверденег. А когда инженеры одной команды узнали у инженеров другой команды зачем изобретается эта защита - реализовали простой стробоскоп, моргающий синхронно с вибрацией и проблема решилась