Для расчета координат из экранных координат с OpenCV

Я рассчитал внутренние и внешние параметры камеры с помощью OpenCV. Теперь я хочу вычислить мировые координаты (x,y,z) из координат экрана (u,v).

Как я это делаю?

N. B. Когда я использую kinect,я уже знаю координату Z.

любая помощь очень ценится. Спасибо!

2 ответов


во-первых, чтобы понять, как вы вычисляете его, это поможет вам, если вы прочитаете некоторые вещи о модели камеры-обскуры и простой проекции перспективы. Для быстрого взгляда, Проверьте этой. Я постараюсь обновить.

Итак, давайте начнем с противоположного, которое описывает, как работает камера: проецируйте 3d-точку в мировой системе координат на 2d-точку на нашем изображении. Согласно модели камеры:

P_screen = I * P_world

или (используя однородные координаты)

| x_screen | = I * | x_world |
| y_screen |       | y_world |
|    1     |       | z_world |
                   |    1    |

здесь

I = | f_x    0    c_x    0 | 
    |  0    f_y   c_y    0 |
    |  0     0     1     0 |

является 3x4 внутренней матрицей, f является фокусом, а c-центром проекции.

если вы решите систему выше, вы получаете:

x_screen = (x_world/z_world)*f_x + c_x
y_screen = (y_world/z_world)*f_y + c_y

но вы хотите сделать обратное, поэтому ваш ответ:

x_world = (x_screen - c_x) * z_world / f_x
y_world = (y_screen - c_y) * z_world / f_y

z_world-это глубина, которую Kinect возвращает вам, и вы знаете f и c из своей внутренней калибровки, поэтому для каждого пикселя, вы применяете вышеизложенное, чтобы получить фактические мировые координаты.

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

во-первых, проверить этот, это очень хорошо объясняет различные системы координат.

ваши 3d системы координат: объект - - - > мир - - - > камера. Существует преобразование, которое переносит вас из системы координат объекта в мир и еще один который доставит вас от мира к камере (extrinsics вы ссылаетесь). Обычно вы предполагаете, что:

  • либо объектная система соответствует мировой системе,
  • или система камеры соответствует мировой системе

1. При захвате объекта с помощью Kinect

при использовании Kinect для захвата объекта, то, что возвращается к вам от датчика расстояние от камера. Это означает, что координата z уже находится в координатах камеры. Преобразуя x и y с помощью приведенных выше уравнений, вы получаете точку в координаты камеры.

Итак, мировая система координат определяется вами. Одним из распространенных подходов является предположение, что камера расположена на (0,0,0) мировой системы координат. Таким образом, в этом случае матрица extrinsics фактически соответствует матрице идентичности, а координаты камеры, которые вы нашли, соответствуют к координаты.

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

2. При калибровке камеры

Я полагаю, вы калибруете камеру с помощью OpenCV, используя калибровочную плату с различными позами. Обычный способ-предположить, что плата на самом деле стабильна, и камера движется вместо противоположного (преобразование одинаково в обоих случаях). это означает, что теперь мировая система координат соответствует объектной системе координат. таким образом, для каждого кадра мы находим углы шахматной доски и назначаем им 3d-координаты, делая что-то вроде:

std::vector<cv::Point3f> objectCorners;

for (int i=0; i<noOfCornersInHeight; i++) 
{
    for (int j=0; j<noOfCornersInWidth; j++) 
    {
        objectCorners.push_back(cv::Point3f(float(i*squareSize),float(j*squareSize), 0.0f));
    }
} 

здесь noOfCornersInWidth, noOfCornersInHeight и squareSize зависят от калибровки доски. Если, например, noOfCornersInWidth = 4, noOfCornersInHeight = 3 и squareSize = 100, мы получаем 3d-точки

(0  ,0,0)  (0  ,100,0)  (0  ,200,0)    (0  ,300,0)
(100,0,0)  (100,100,0)  (100,200,0)    (100,300,0)
(200,0,0)  (200,100,0)  (200,200,0)    (200,300,0)

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

до суммы в Kinect корпус:

  • камеры и Мир систем coodinate считаются одинаковыми, поэтому нет необходимости для extrinsics там.
  • нет необходимости в преобразовании объекта в мир(камера), так как возвращаемое значение Kinect уже находится в системе камеры.

Edit 2 (в используемой системе координат):

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

Sidenote: вам бы очень помогло, если бы вы визуализировали облако точек и немного поиграли с ним. Вы можете сохранить свои очки в формате 3d-объекта (например,ply или параметр obj), а затем просто импортировать его в программу как Meshlab (очень легко использовать).


Edit 2 (в используемой системе координат):

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

Если вы, например, используете Microsoft sdk: тогда Z-это не расстояние до камеры, а" плоское " расстояние до камеры. Это может изменить соответствующие формулы.