OpenCV - проекция, матрица гомографии и вид с высоты птичьего полета
Я хотел бы получить матрицу гомографии для Bird's eye view, и я знаю матрицу проецирования камеры. Есть ли какая-то связь между ними?
Благодарю.
1 ответ
Матрица проекции определяется как произведение внутренней (например, фокусного расстояния, главных точек и т. Д.) Матрицы и внешней (вращение и перемещение) матрицы. Вопрос в том, каковы ваши ротация и перевод? Например, я могу представить другую камеру или объект в 3D, относительно которого у вас есть эти повороты и перемещения. В противном случае ваша проекция - это просто внутренняя матрица.
Сначала подумайте о том, какую информацию вы должны знать, чтобы получить представление с высоты птичьего полета: вам нужно знать хотя бы, как ваша камера ориентирована относительно поверхности земли. Если вы также знаете высоту камеры, вы можете создать метрическую реконструкцию. Но так как вы упомянули гомографию, я предполагаю, что вы рассматриваете плоскую поверхность с высоты птичьего полета, поскольку гомография отображает точки на двух плоских поверхностях, в вашем случае точки на плоской поверхности, на точки на вашем плоском датчике.
Давайте рассмотрим уравнение камеры-обскуры. В основном это говорит о том, что [u, v, 1]T ~ A * [R|t] [x, y, z, 1]T, где A - собственная матрица камеры. Теперь, когда вы имеете дело с земной плоскостью, вы можете выровнять новую систему координат с ней, установив z=0; R|t - матрицы вращения и перевода из этой системы координат в вашу систему, выровненную по камере;
Далее, обратите внимание, что ваша R|t является матрицей 3x4, и она теряет одно измерение, так как z = 0; оно становится 3х3 или гомографией, которая теперь равна H=A*R '|t; Хорошо, все, что мы сделали, это доказали, что между землей и вашим датчиком существует картография гомографии;
Теперь вам нужен другой вид гомографии, который происходит при чистых поворотах камеры и масштабировании между точками на датчике до и после вращения / масштабирования; то есть вы хотите повернуть камеру вниз и, возможно, уменьшить масштаб. Опять же, подумайте в терминах уравнения камеры-обскуры: изначально у вас было H1=A (здесь я выбросил R|T как неактуальную на данный момент), а затем вы повернули камеру и у вас H2=AR; другими словами, H1 - это то, как вы делаете свое изображение сейчас, а H2 - то, как вы хотите, чтобы ваше изображение выглядело.
Отношения между двумя - это то, что вы хотите найти, H12, и это также гомография, поскольку гомография - это семья преобразований (используйте эту простую эвристику: то, что происходит в семье, остается в семье). Поскольку одна и та же поверхность может генерировать изображения либо с H1, либо с H2, мы можем собрать H12, отменив H1 (обратно к плоскости земли) и применив H2 (от земли к сенсору с высоты птичьего полета); в некотором смысле это похоже на операции с векторами, вы просто должны соблюдать порядок применения матрицы справа налево:
H12 = H2 * H1-1= A * R * A-1= P * A-1, где мы подставили выражения для H1, H2 и, наконец, для матрицы проекции (если она у вас есть)
Это ваш ответ, и если поворот R неизвестен, его можно угадать по ориентации камеры относительно земли или рассчитать с помощью solvePnP() из библиотеки opeCV. Наконец, когда я делаю это на мобильном телефоне, я просто использую его показания акселерометра как хорошее приближение, так как когда сотовый телефон не ускоряется, показания представляют вектор силы тяжести, который дает вращение относительно плоской горизонтальной поверхности.
Когда вы начертите вид с высоты птичьего полета как изображение, вы заметите, что его границы превратились из прямоугольника в некую трапецию (из-за формы усеченной камеры), и в отдаленных местах есть некоторые отверстия (из-за недостаточной частоты дискретизации), Вы можете интерполировать внутри отверстий, используя wrapPerspective()