Извлечение 3D-координат по точкам 2D-изображения, карте глубины и матрицам калибровки камеры

У меня есть набор 2D image ключевых точек, которые выводятся функцией обнаружения углов OpenCV FAST. Использование Asus Xtion I также имеет синхронизированную по времени карту глубины со всеми известными параметрами калибровки камеры. Используя эту информацию, я хотел бы извлечь набор координат 3D (облако точек) в OpenCV.

Может ли кто-нибудь дать мне какие-либо указания относительно того, как это сделать? Заранее спасибо!


person Will Andrew    schedule 07.07.2015    source источник
comment
отменить проекцию. Если я не ошибаюсь, проекция должна быть p = C*T*P, где C — внутренние характеристики камеры, T — внешние характеристики камеры, P — точка 3D. Так что сделайте что-нибудь вроде P = iT * iC * p, где iC — обратные внутренние, iT — обратные внешние. p должен быть расширен до 3D-точки, где последняя координата равна 1, а вся точка будет умножена на вашу глубину.   -  person Micka    schedule 07.07.2015
comment
если это не сработает, вы можете создать луч от (0,0,0) до пикселя (данного iC*p). Вы можете преобразовать этот луч в глобальное пространство, умножив его на T. Затем переместитесь вдоль этого луча на расстояние, равное вашему значению глубины.   -  person Micka    schedule 07.07.2015
comment
или просто взгляните на nicolas.burrus.name/index.php/Research/KinectCalibration и сделать то же самое   -  person Micka    schedule 07.07.2015
comment
Спасибо! ссылка, которую вы разместили, именно то, что мне нужно. Если вы опубликуете свои комментарии в качестве ответа, я могу принять это.   -  person Will Andrew    schedule 07.07.2015


Ответы (1)


Николя Буррус создал отличный учебник для датчиков глубины, таких как Kinect.

http://nicolas.burrus.name/index.php/Research/KinectCalibration

Я скопирую и вставлю самые важные части:

Сопоставление пикселей глубины с цветными пикселями

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

P3D.x = (x_d - cx_d) * depth(x_d,y_d) / fx_d
P3D.y = (y_d - cy_d) * depth(x_d,y_d) / fy_d
P3D.z = depth(x_d,y_d)

с fx_d, fy_d, cx_d и cy_d встроенными функциями камеры глубины.

Если вас еще интересует стереомэппинг (значения для kinect):

Затем мы можем перепроецировать каждую трехмерную точку на цветное изображение и получить ее цвет:

P3D' = R.P3D + T 
P2D_rgb.x = (P3D'.x * fx_rgb / P3D'.z) + cx_rgb
P2D_rgb.y = (P3D'.y * fy_rgb / P3D'.z) + cy_rgb

где R и T — параметры вращения и перемещения, оцененные во время стереокалибровки.

Параметры, которые я могу оценить для своего Kinect:

Цвет

fx_rgb 5.2921508098293293e+02 
fy_rgb 5.2556393630057437e+02 
cx_rgb 3.2894272028759258e+02 
cy_rgb 2.6748068171871557e+02 
k1_rgb 2.6451622333009589e-01 
k2_rgb -8.3990749424620825e-01 
p1_rgb -1.9922302173693159e-03 
p2_rgb 1.4371995932897616e-03 
k3_rgb 9.1192465078713847e-01

Глубина

fx_d 5.9421434211923247e+02 
fy_d 5.9104053696870778e+02 
cx_d 3.3930780975300314e+02 
cy_d 2.4273913761751615e+02 
k1_d -2.6386489753128833e-01 
k2_d 9.9966832163729757e-01 
p1_d -7.6275862143610667e-04 
p2_d 5.0350940090814270e-03 
k3_d -1.3053628089976321e+00

Относительное преобразование между датчиками (в метрах)

R [ 9.9984628826577793e-01, 1.2635359098409581e-03, -1.7487233004436643e-02, 
-1.4779096108364480e-03, 9.9992385683542895e-01, -1.2251380107679535e-02,
1.7470421412464927e-02, 1.2275341476520762e-02, 9.9977202419716948e-01 ]

T [ 1.9985242312092553e-02, -7.4423738761617583e-04, -1.0916736334336222e-02 ]
person Micka    schedule 07.07.2015
comment
Я бы добавил, что P2D_rgb.x и P2D_rgb.y являются индексами в изображении RGB (начиная с (0, 0) ). Если индекс выходит за пределы, это означает, что этот пиксель не виден в изображении RGB. - person Maghoumi; 21.02.2016