Поворот изображения по данным датчика ориентации

Я хочу рассчитать информацию о глубине из 2 изображений с движущейся камеры. С помощью Sensor.TYPE_ROTATION_VECTOR У меня есть кватернионы для обоих изображений, а также относительные кватернины от Img1 до Img2.

Img1

q1 = 0.7545 - 0.1137i - 0.2715j - 0.5865k

Img2

q2 = 0.7706 - 0.2252i - 0.3511j - 0.4817k

И относительный кватерноин это:

qr = -0.9850 + 0.0072i + 0.1329j - 0.1097k

То есть относительная матрица вращения

|0.9406   -0.2142    -0.2635 |
|0.2180    0.9758    -0.0150 |
|0.2604   -0.0433     0.9645 |

Это матрица getPerspectiveTransform дает?

Когда я использую эту матрицу вращения 3x3 в warpPerspectiveЯ получаю почти пустое изображение, кроме чего-то в левом верхнем углу. (Возможно, ось, вокруг которой вращается изображение, неверна).

Что я делаю неправильно?

Примечание: между двумя изображениями также есть небольшой перевод (извините за плохие изображения)

Изменить 1: По этой ссылке для моего Moto G 2-го поколения я получаю матрицу встроенной камеры как,

K = |-3570   0         1632 |
    |  0   3554.39   1218.65|
    |  0     0           1  |

1 ответ

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

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

1. Найти точечные соответствия между двумя изображениями

В зависимости от того, что вы хотите сделать, это можно сделать либо для всех точек на изображениях (т. Е. Плотным образом), либо только для нескольких точек (т. Е. Разреженным образом). Конечно, последнее менее затратно в вычислительном отношении, следовательно, больше подходит для смартфонов.

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

  • Разреженное сопоставление требует сопоставления характерных признаков (например, SURF или SIFT или более эффективных) между двумя изображениями. Это имеет преимущество в том, что он более эффективен, чем плотное сопоставление, а также более точен.

2. Триангулируйте соответствующие точки для оценки глубины

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


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

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

Калибровка вашей камеры позволит вам оценить точную характеристическую матрицу и соответствующие коэффициенты искажения. Рекомендуется делать это, потому что ваша камера не будет точно такой же, как камеры в других телефонах (даже если это та же модель телефона). Посмотрите, например, это руководство, которое показывает методологию, хотя примеры кода находятся на C++ (эквивалент должен существовать для Android).

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


Кроме того, чтобы ответить на ваш другой вопрос, связанный с warpPerspective, вам нужно будет использовать K.R.inv(K) или же K.inv(R).inv(K)в зависимости от изображения, которое вы деформируете. Это потому что R 3D вращение, которое не имеет ничего общего с пиксельными координатами.

Другие вопросы по тегам