Для расчета координат из экранных координат с OpenCV
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-это не расстояние до камеры, а" плоское " расстояние до камеры. Это может изменить соответствующие формулы.