Захватите текстуру пола с помощью ARCore - PullRequest
0 голосов
/ 14 марта 2019

Я пытаюсь захватить «текстуру пола» на основе обнаруженной ARCore плоскости и текстуры окружающей среды (камеры).Затем повторно примените эту текстуру пола в плоской сетке, создавая цифровой пол на основе реальности.Я загрузил изображение, чтобы проиллюстрировать это:

Illustration

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

Может кто-нибудь мне помочь?Спасибо !!

1 Ответ

0 голосов
/ 15 марта 2019

По сути, у нас есть три важные системы координат в этой задаче:

Coordinate Systems

У нас есть обычная трехмерная мировая система координат, которую можно определить произвольно. У нас есть 2D система координат для плоскости. Источник этой системы координат находится в центре плоскости (обратите внимание, что для этой цели я использую термин плоскость как синоним прямоугольник ), а координаты находятся в диапазоне от -1 до +1. И наконец, у нас есть 2D координата для изображения. На самом деле у нас есть две для изображения: система координат без знака (как показано на рисунке) с началом координат внизу слева и координатами в диапазоне от 0 до 1, и система со знаком с координатами в диапазоне от -1 до 1.

Мы знаем четыре угла нашей плоскости в мировом пространстве и матрицу 3x4 вида / проекции P, которая позволяет нам проецировать любую точку в мировом пространстве на пространство изображения, используя однородные координаты:

p_image,signed = P * p_world

Если ваша матрица проекции имеет размер 4x4, просто отбросьте третью строку (последнюю, но 1), поскольку нас не интересует глубина пространства изображения.

На самом деле мы не заботимся о мировом пространстве, поскольку это несколько произвольно. Учитывая 2D точку в плоском пространстве, мы можем преобразовать ее в мировое пространство, используя:

p_world = 1/4 (p0 + p1 + p2 + p3) + u * 1/2 * (p1 - p0) + v * 1/2 * (p3 - p0)

Первая часть - это начало плоскости, а точечные различия во втором и третьем членах - это оси координат. Мы можем представить это в матричной форме как

/ x \   / p1_x - p0_x   p2_x - p0_x   1/4 (p0_x + p1_x + p2_x + p3_x) \   / u \
| y | = | p1_y - p0_y   p2_x - p0_x   1/4 (p0_y + p1_y + p2_y + p3_y) | * | v |
| z |   | p1_z - p0_z   p2_x - p0_x   1/4 (p0_z + p1_z + p2_z + p3_z) |   \ 1 /
\ 1 /   \      0             0                         1              /

Давайте назовем эту матрицу M.

Теперь мы можем перейти непосредственно из плоского пространства в пространство изображения с помощью:

p_image,signed = P * M * p_plane

Матрица P * M теперь является матрицей 3х3. Это гомография между вашей земной плоскостью и плоскостью изображения.

Итак, что мы можем с этим сделать? Мы можем использовать его, чтобы нарисовать изображение в плоском пространстве. Итак, вот что мы собираемся сделать:

Мы создадим цель рендеринга, которую мы заполним одним вызовом отрисовки. Эта цель рендеринга будет содержать текстуру нашей плоскости. Чтобы нарисовать это, мы:

  1. Загрузка изображения камеры в графический процессор в виде текстуры
  2. Привязать цель рендеринга
  3. Нарисуйте полноэкранный четырехугольник с углами (-1, -1), (1, -1), (1, 1), (-1, 1)
  4. В вершинном шейдере вычислить координаты текстуры в пространстве изображения из плоского пространства
  5. В пиксельном шейдере сэмплируйте изображение с камеры по интерполированным координатам текстуры

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

                   / 1/2  0  1/2 \
p_image,unsigned = |  0  1/2 1/2 | * p_image,signed
                   \  0   0   1  /

Если мы назовем эту матрицу S, мы можем затем вычислить S * P * M, чтобы получить одну матрицу 3x3 T. Эту матрицу можно использовать в вершинном шейдере для вычисления координат текстуры из точек плоскости, которые вы передаете:

texCoords = p_image,unsigned = T * p_plane

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

...