Виды представления лидарных данных. Часть 3
Voxel-based
Перед обзором репрезентации на основе вокселей, применяемой в современных алгоритмах, давайте разберемся с тем, что такое воксель и как формируется воксельная сетка.
Воксель — промежуточное представление 3D-пространства, которое содержит записи о находящихся в нем точках лидарного облака и является одним из упорядоченных элементов воксельной сетки. Воксельную сетку мы задаем при определении следующих параметров:
\( size_x — размер\ для\ x\ (ширина) \)
\( size_z — размер\ для\ z\ (высота) \)
\( также\ идентично\ BEV\ необходимо\ задать\ зону\ интереса: \)
\( x \in [\min x,\max x] — границы \ значений \ для \ x \)
\( y \in [\min y,\max y] — границы \ значений \ для \ y \)
\( z \in [\min z,\max z] — границы \ значений \ для \ z \)
После того, как мы инициализировали нужное количество пустых вокселей в соответствии с ранее определенными параметрами и размерами исходного пространства, мы приступаем к записи точек в воксели. Для определения вокселя, которому принадлежит текущая точка пространства, выполним следующие вычисления:
\( i = int(\lfloor (y − ymin)/Voxlesize_y \rfloor) — индекс \ строки \)
\( j = int(\lfloor(x − xmin)/Voxelsize_x \rfloor ) — индекс \ стобца \)
\( k = int(\lfloor (z − zmin)/Voxelsize_z \rfloor) — индекс \ слоя \)
Итак, мы изучили формирование воксельной сетки. Теперь давайте перейдем к использованию подобного подхода при представлении лидарных данных. Рассмотрим пример VoxelNet:
Для создания входного представления применяются следующие шаги:
- Формирование воксельной сетки и группировка точек согласно индексу вокселя (это мы рассмотрели выше).
- Случайный выбор из множества: в воксель может попасть разное количество точек, поэтому для уменьшения вычислений и приведения пространства к единой размерности мы случайно выбираем T точек среди тех вокселей, где количество точек больше T.
- Наборы точек в вокселях приводятся к латентному вектору. Для этого нам нужно совершить следующие преобразования.
На этапе формирования скрытого представления для вокселя мы изначально создаем дополнительные признаки для точек. Это происходит по такому алгоритму:
\( V — текущий \ воксель \)
\( V = {p_i = [x_i , y_i , z_i , r_i]^ T ∈ \mathbb{R} ^4}_{i=1…T} — набор \ точек \ попавших \ в \ воксель ,
где \ xyz — координаты\ точки , r — рефлективность \)
\( Вычислим \ центроид \ вокселя : centroid = (v_x, v_y, v_z) \)
\( Расширим\ описание \ точки :\ p_i = [x_i , y_i , z_i , r_i , x_i −v_x, y_i −v_y, z_i −v_z] \)
Затем формируем скрытое представление для каждой точки и делаем агрегацию:
\( feature_{1..t} = FCN(point_{1..t}), где \ FCN — полносвязная \ сеть \)
\( feature ∈ \mathbb{R}^m = MaxPool(feature_{1..t}) — финальное \ представление, \)
\( где\ m — размерность \ представления \)
Итоговое представление = тензору с размерностями C, D, H, W, где C — размерность скрытого представления, D x H x W — пространственные размерности воксельной сетки.
Сylinder-based
Cylinder-based — одна вариация voxel-based подхода.
Cylinder-based подход — построение воксельной сетки в цилиндрической системе координат. Отличительным признаком является не только система координат, но и принцип представления. Здесь используется неявный тип представления, где полученные воксели хранятся в виде space матрицы.
Для перевода координат точек в цилиндрическую систему необходимо сделать следующее преобразование:
\( p=\sqrt {x^2+y^2} \)
\( \theta =\tan^{−1}\frac{y}{x} \)
\( z=z \)
А затем определить принадлежность координаты к определенному вокселю:
\( i = int(\lfloor\ (p — min_p) / Voxelsize_p \rfloor) \)
\( j = int(\lfloor\ (\theta — min_\theta) / Voxelsize_\theta \rfloor) \)
\( k = int(\lfloor\ (z — min_z) / Voxelsize_z \rfloor), где \)
\( min_p — минимальная\ дистанция\ от\ центра\ координат \)
\( min_\theta — минимальный\ угол\ \)
\( min_z — минимальная\ высота \)
После нашего преобразования мы разбиваем данные на воксельную сетку. Для получения скрытых представлений для каждого вокселя воспользуемся подходами, рассмотренными ранее в методе VoxelNet.
Мы используем тип неявного представления данных, поэтому после вокселизации мы получим следующие тензоры:
\( \underset{n\times c}{Voxels} — векторы\ в\ латентном\ пространстве\ для\ каждого\ вокселя \)
\( \underset{n\times i,j,k}{Coords} — координаты\ вокселя\ в пространстве\ воксельной\ сетки \)
Важно отметить: те воксели, в которые ранее не попадали точки, не добавляются в итоговые массивы или могут быть представлены нулевыми векторами.
Для лучшего понимания полученного представления рассмотрим базовый процесс обработки:
Как было отмечено ранее, у нас есть массивы features и coordinates. Для их обработки нужно:
- С использованием правил (Rule) определить, какие индексы стоит сгруппировать в тензор и какие индексы элементов мы получим после обработки.
- Провести обработку 3D сверткой.
- Присвоить результирующим векторам их новые индексы.
По сравнению с явным пространственным представлением (использовалось в VoxelNet), где после получения результирующего представления в обработку мы подавали 4D тензор, в случае неявного пространственного представления и применения sparce convolution мы экономим большую часть вычислений при эффективной реализации подобных операций.
Polar Bird’s Eye View (BEV) Projection
Как и в случае с подходом, рассмотренным нами выше, этот подход — модификация базового BEV представления за счет использования полярных координат, а также автоматического формирования скрытых представлений вместо созданных вручную признаков.
Преобразование из декартовой системы координат в полярную аналогично преобразованию в цилиндрическую систему координат.
Давайте разберемся с принципом формирования полярной сетки. Для начала зададим границы значений идентично VoxelNet.
\( p \in [\min p,\max p] — границы \ значений \ для \ p \)
\( \theta \in [\min \theta,\max \theta] — границы \ значений \ для \ \theta \)
\( z \in [\min z,\max z] — границы \ значений \ для \ z \)
Далее воспользуемся одной из вариаций определения размера вокселя:
\( \underset{h\times w\times c}{Gridsize} — размер\ воксельной \ сетки,заданный\ как\ размеры\ выходного\ тензора \)
\( Cropsize = [max_p — min_p,max _{\theta} — min_{\theta},max_z — min_z] — размер\ области\ интереса \)
\( Voxelsize = Cropsize/Gridsize \)
Затем у нас следует схожий с Voxel/Cylinder-base подходами момент — мы группируем точки в воксели и обрабатываем их с помощью FCN/PointNet. В отличие от VoxelNet мы делаем двойную агрегацию для получения 3D тензора вместо 4D тензора.
\( \underset{n\times c\times d \times h\times w}{Voxelgrid} — воксельная\ сетка , где : \)
\( n — количество \ точек \ в \ вокселе \)
\( с — размерность\ скрытого \ представления \)
\( d,h,w — пространственные \ размерности \ воксельной\ сетки \)
\( Рассмотрим\ этапы\ агрегации: \)
\( 1.feature ∈ \mathbb{R}^c = MaxPool(feature_{1..n}) — финальное \ представление, \)
\( где\ c — размерность \ представления \)
\( \underset{c\times d \times h\times w}{Voxelgrid} -размерности\ после\ шага\ 1 \)
\( 2.feature ∈ \mathbb{R}^c = MaxPool(feature_{1..d}) — финальное \ представление, \)
\( где\ c — размерность \ представления, d — количество\ вокселей\ по\ оси\ z \)
\( \underset{c\times h\times w}{Voxelgrid} -размерности\ после\ шага\ 2 \)
Таким образом, мы получаем пространственное представление, которое можно обрабатывать c помощью классических Conv2d модулей.