Чем лучше удастся рассмотреть потенциальную покупку перед оплатой, тем меньше шансов столкнуться с неприятными сюрпризами после, вопреки недобросовестным продавцам и недостаточно подробным описаниям. Чтобы ожидания пользователей чаще совпадали с реальностью, всё больше онлайн-магазинов внедряют 3D-фото на карточки своих товаров: одежда, электроника и даже маркетплейсы. Спрос на панорамные фото автомобилей был только делом времени и технологий, ведь в отличие от обуви или телефона, съёмка машины требует намного больше места и усилий.
Привет, на связи Антон Тимофеев, продуктовый менеджер в Авто.ру, и Александр Сапатов, разработчик команды компьютерного зрения Яндекса. Под катом расскажем о том, что происходит под капотом нашего приложения, после того как вы нажимаете кнопку «Панорама», и почему для создания хорошего снимка теперь достаточно обычного смартфона.
Что было до
Крупные автодилеры начали массово использовать панорамы где-то в 2017 году. Строго говоря, это были не совсем панорамы: вокруг автомобиля строили целые съёмочные павильоны или замкнутые «рельсы», по которым толкали камеру, пока она не возвращалась на место старта, на выходе — видео, где машина видна со всех сторон. В 2018 мы поддержали этот формат на Авто.ру и наблюдали процесс подготовки: дилеры закупают оборудование ценой в сотни тысяч рублей, возводят вспомогательные приспособления — камера, мотор! Красивые фото и видео приятно рассматривать даже если не собираешься приобретать автомобиль. Неудивительно, что частные продавцы стали интересоваться, можно ли повторить такое в домашних условиях.
Технологии развивались, процесс упрощался, но для создания качественной панорамы всё ещё требовалась если не профессиональная камера, то, как минимум, топовый смартфон. К 2019 году мы поставили себе амбициозную цель — сделать панорамную съёмку авто доступной почти каждому владельцу смартфона: простой и быстрой, не требующей дополнительных затрат, специального оборудования и профессиональных навыков.
И сделали.
Как это работает
В двух словах так: пользователь снимает видео в нашем приложении, а оно обрабатывает полученные кадры с использованием технологий компьютерного зрения и машинного обучения — очищает от шумов, выравнивает изображение, склеивает панораму. Звучит просто, но если представить, каким образом человек идёт с телефоном вокруг автомобиля, удерживая его в кадре, задача начнёт обрастать подробностями: например, телефон шатается из стороны в сторону, несмотря на оптическую стабилизацию. На пути могут возникнуть препятствия — столбы, деревья, заборы — и объект съёмки пропадёт из кадра. А походка или скорость шага могут привести к неравномерности съёмки — ниже ещё вернёмся к тому, как боремся с этими и подобными шумами.
Итак, вы открыли приложение, нажали кнопку «Панорама» в форме редактирования объявления, обошли автомобиль с включённой камерой, тщательно следуя всем инструкциям. Что дальше?
Шаг 0. Снятое видео отправляется к нам на сервера: во-первых, зачем экспериментировать, справится ли ваше устройство с не самыми лёгкими расчётами, если можем взять это на себя. Во-вторых, чем больше вычислительных мощностей, тем быстрее сгенерируется панорама. Запускается классический для задач Structure from Motion алгоритм обработки видео, который умеет одновременно делать всё, что потребуется для моделирования: позиционировать камеру в пространстве, понимать, где находился объект, и оценивать его размеры.
Шаг 1. От реальной картины мира к математической модели. По доступным кадрам видео алгоритм вычисляет облако подозрительных точек для проверки на совпадение и определяет какие из них на самом деле одна и та же точка, снятая с разных ракурсов. Ещё не известно, что из этого действительно машина, а что фон. Выбираются «опорные» кадры — включающие много подозрительных точек. Пока идёт работа с облаком, реальные, абсолютные расстояния не понадобятся, важны именно взаимное расположение камеры и объекта, то есть модель — проекция реального мира в некотором масштабе. По небольшому количеству кадров выполняется грубая оценка позиций камеры в пространстве: чем точнее известно, где она находилась, тем качественнее получится ограничить интересующие нас объекты.
Можно было бы попробовать определить позицию камеры с помощью гироскопа и других встроенных в телефон датчиков, но они накапливают ошибку измерения с течением времени: чем дольше видео — тем больше ошибка. Поэтому мы пытаемся восстановить точки в трёхмерном пространстве: сравнивая соседние кадры, собираем общую трёхмерную модель траектории движения камеры. Опытные читатели могут возразить — почему не попробовать делать сегментацию на разных кадрах? — маска может получиться разная, возникнет дрожание объекта.
Шаг 2. Для опорных кадров алгоритм ищет соседние: выбирает таким образом, чтобы они равномерно (по углу обхода), покрывали панораму. То есть точки, существующие в реальном 3D-мире, не рассчитываются для каждого нового кадра, а ищутся на соседних.
Параллельно алгоритм* подбирает параметры камеры: после нахождения опорных точек оптимизирует систему линейных уравнений (минимизирует ошибку определения положения), по которым эти точки проецируются на кадры, где были найдены. Решая такую систему уравнений, требуем, чтобы параметры камеры на каждом кадре были одинаковы, позиция — от кадра к кадру — разная, а точка в 3D-профайле тоже опять-таки на всех кадрах должна быть одинаковая. Для кадров, где опорных точек не было, соответственно, определяются только позиции камеры.
*Мы уже ссылались на эту статью выше: больше деталей, математические подробности.
Шаг 3. Облако точек есть: как понять, какие из них относятся к машине? Технология, помогающая по кадрам создавать облако точек и находить позицию камеры, довольно известна. Мы для решения этой задачи используем opensfm. Однако следом отрабатывает наша собственная технология, позволяющая сделать фильтрацию облака точек и выравнивание позиции камеры. Эвристика следующая:
- Объект должен быть вытянут: машина в любом сечении больше длинная, чем высокая.
- Облако точек — плотное: автомобиль едва ли просвечивает.
- Всё, что вне траектории камеры (а она теперь известна) — шум.
- Машина обычно стоит на земле — плотное скопление точек в нижней части кадра также обычно имеет характерную форму.
Итого: ищем некий параллелепипедообразный (bbox) объект, в который входит как можно больше точек из облака. Если таких объектов оказалось более одного (в кадр попал столб или что-то ещё), сегментация оставит только центральный.
Кстати, развеем популярный миф. Неоднородный фон — самый лучший:
- Для нас — потому что алгоритму проще отличить, какие точки относятся к машине, а какие к фону. Кирпичная стена, сетка-рабица и другие повторяющиеся текстуры исключения — алгоритм может неправильно определить, какие точки совпадают.
- Для вас — потому что машины на живом фоне, по статистике, находят больший отклик у покупателей, чем салонные интерьеры и правильная подсветка.
Шаг 4. Избавиться от шумов. Основные — вызванные матрицей телефона, расфокус и motion blur. Из-за них на разных кадрах нельзя точно определить одинаковую точку — например, из-за блюра ±3 пикселя в разную сторону накапливается ошибка нахождения этой точки в трёхмерном пространстве.
Когда не получается найти точное положение точки на фотографиях, трёхмерная модель начинает напоминать ежа: пиксельное дрожание на кадрах переносится в такое же дрожание, но с большими расстояниями. Обязательно сглаживаем поверхность, боремся с выбросами: если возникают далёкие точки, рядом с которыми нет никакого облака — выкидываем их, так как скорее всего шум.
Лучше один раз увидеть:
Шаг 5. От облака точек возвращаемся к понятной человеческому глазу картинке: панораме.
Когда мы саппроксимировали bounding box машины, можно оценить, насколько много именно её попало на разные кадры и отбраковать неудачные. Если известно местоположение объекта, все нужные точки легко спроецировать на каждый кадр, обрезать его до нужных размеров. Параллельно алгоритм восстанавливал параметры камеры: он знает, когда картинку нужно отмасштабировать (приблизить/удалить) или повернуть.
Для безопасности продавца не забываем скрыть номера: в России мы были одними из первых, кто реализовал эту опцию. Тут тоже есть нюанс: если искать номер на каждом сыром кадре — возникнет дрожание, и есть шанс, что где-то что-то упустим. Поэтому наш алгоритм ищет номер на готовой 3D-модели и проецирует его на панораму.
Конечно, если подходящих кадров недостаточно, придётся переснять видео, но мы очень стараемся извлечь максимум из исходников.
Шаг 6. Готовая панорама отправляется в объявление.
Немного цифр для масштаба
- Сейчас для создания панорамы используется около 60 опорных кадров, «приклеиваются» к ним ещё около 120. Для этого выбирается по 15 соседних кадров, для них вычисляются позиции камеры и облако совпавших точек. Количества кадров не случайны: так не страдает ни качество панорамы, ни скорость сборки. Первые панорамы, где мы ещё не нащупали баланс, собирались по 40 минут, что, конечно, недопустимо.
- Обычно съёмка панорамы автомобиля происходит где-то за минуту. На смартфонах видео такой длительности после съёмки занимает от 100 до 300 МБ, что с условием загрузки на наши сервера было бы серьёзным стопором для пользователя. Поэтому в рамках проекта мы стали «на лету» менять битрейт и формат съёмки, тем самым сократив размер файла видео до приемлемых 20–40 мегабайт, без потерь в размере картинки или качества для компьютерного зрения.
- С другой стороны, нам пришлось провести адаптацию выдачи объявлений с панорамами, т.к. пользователи не готовы ждать загрузки 5–6 мегабайт на каждое, учитывая, что за сессию поиска автомобиля они просматривают десятки и даже сотни объявлений. Для решения этой проблемы мы перекодируем полученный результат под разные разрешения и форматы файлов – от простого сета .jpeg до достаточно редкого .webm, в некоторых случаях сокращая размер скачиваемой панорамы до 150 КБ.
- На данный момент у нас на сайте можно встретить больше 3000 панорам автомобилей, созданных как дилерами (мы не забыли и про них), так и обычными продавцами.
- Будущие покупатели видят в выдаче «живые» объявления с панорамами и «залипают» на них до 30% дольше. Конверсия звонков продавцу для автомобиля с панорамой также растёт.
Панорама позволяет увидеть товар со всех сторон, скрыть дефекты практически невозможно. Дополнительно затрудняет возможность сжульничать и то, что картинка собирается на наших серверах, нельзя вмешаться и, например, отретушировать дефекты. В будущем, кстати, планируем предоставить продавцам возможность отмечать на панорамах проблемные зоны и прикреплять к ним фото с подробностями.
Товар != автомобиль. Надеемся, что наш опыт окажется полезным и для других сфер ритейла: простое, быстрое и бесплатное создание 3D-модели для объявления облегчит жизнь продавцам, возможность тщательно осмотреть предмет сделки поможет покупателям.