Стереосистема - получить 3D-позицию с помощью OpenCv

У меня есть стереосистема с 2 камерами. Я калибровал эти камеры. Я пытаюсь рассчитать расстояние между каждым кончиком пальца. На левом изображении я нахожу кончики пальцев, используя выпуклую оболочку. Я рассчитываю эпипуларную линию для этих точек. Я рисую эпиполярные линии на правом изображении. Как я могу рассчитать 3D-позицию для каждого кончика пальца? Я использовал c++ и opencv.

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

введите здесь описание изображения

Мой файл .yml ниже после калибровки стерео

%YAML:1.0
CM1: !!opencv-matrix
 rows: 3
 cols: 3
 dt: d
 data: [ 1.4947330489959640e+02, 0., 8.5026435902438408e+01, 0.,
   1.7045159164506524e+02, 6.8513237416979280e+01, 0., 0., 1. ]
CM2: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ 1.4947330489959640e+02, 0., 7.6063817190941975e+01, 0.,
   1.7045159164506524e+02, 6.9869364400956655e+01, 0., 0., 1. ]
D1: !!opencv-matrix
rows: 1
cols: 5
dt: d
data: [ 4.6664660489275862e+00, -9.5605452982913761e+01, 0., 0.,
   4.4411083031870203e+02 ]
D2: !!opencv-matrix
rows: 1
cols: 5
dt: d
data: [ -2.6243438145377401e-01, 3.1158182596121313e+00, 0., 0.,
   -6.9555261934841601e+00 ]
R: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ -9.9870707407742809e-01, 5.0820157566619700e-02,
   1.2213814337059467e-03, -4.6584627039081256e-02,
   -9.2456021193091820e-01, 3.7817758664136281e-01,
   2.0348285218473684e-02, 3.7763173343769685e-01,
   9.2573226215224258e-01 ]
T: !!opencv-matrix
rows: 3
cols: 1
dt: d
data: [ -5.0257191774306198e-01, -5.1791340062890008e+00,
   -1.7104054803114692e+00 ]
E: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ -1.8506509733057530e-01, -3.5371782058656147e+00,
   -4.1476544229091719e+00, 1.7184205294528965e+00,
   1.0286402846218139e-01, 4.6315798080871423e-01,
   -5.1490256443274198e+00, 7.2786240503729882e-01,
   -1.8373573684783620e-01 ]
 F: !!opencv-matrix
  rows: 3
 cols: 3
 dt: d
 data: [ -2.0635586643392613e-06, -3.4586914187982223e-05,
   -4.3677532717492718e-03, 1.6802903312164187e-05,
   8.8202517402136951e-07, -8.1218529743132760e-04,
   -9.5988974549000728e-03, 3.6330053228360980e-03, 1. ]

person zakjma    schedule 14.12.2014    source источник


Ответы (3)


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

  • Сначала используйте 3D-реконструкцию изображения, чтобы получить глубинное изображение вашей руки.
  • Затем используйте существующий алгоритм, чтобы получить кончики пальцев на изображении глубины.
  • Наконец, используйте информацию о глубине, чтобы восстановить трехмерное положение кончиков пальцев.
person Mario    schedule 14.12.2014
comment
Мне не нужна только глубина. Я хочу рассчитать координаты x, y, z. - person zakjma; 15.12.2014
comment
@holazolllil Это только первый шаг. Как только вы получите глубину для каждого пикселя, вы сможете восстановить фактические мировые координаты, учитывая, что у вас есть преобразования вашей камеры, поскольку вы знаете расстояние до изображенного пикселя, а также угол (вертикальный и горизонтальный на основе координаты и поле зрения). - person Mario; 15.12.2014

Вам может понадобиться очень быстрое и простое решение, основанное на соответствии точек 3D-2D. Затем вы выполняете подгонку точек к 3D-модели, много 3D-моделей руки можно найти в свободном доступе, например: http://www.turbosquid.com/3d-model/anatomy/hand OpenCV предоставляет хороший метод -solvePnP - который может выполнить шаг настройки. Нам нужно сделать следующее:

  1. скачать бесплатную модель руки.
  2. Используйте любой 3D-редактор для редактирования модели (например: MeshLab)
  3. Отметьте положение каждого кончика пальца, мы получим пять 3D точек
  4. сохранить их в файле в качестве эталонной модели
  5. ваша программа opencv найдет вам пять 2D-точек.
  6. Теперь у вас есть точки модели (3d) и точки реального изображения (2D), вы должны подогнать их с помощью функцииsolvePnP:
  7. мы получим матрицу 3x3, которую вы можете определить как: double calMat[9] = { x_center, 0, x_shift, 0, y_center, y_shift, 0, 0, 1 }; //"калибровочная матрица": точка x_center,y_center должна учитывать центр изображения с фокусным расстоянием, т.е. x_center=y_center=30 cameraMatrix = Mat(3,3,CV_64FC1,calMat);
  8. По этим шагам вы можете оценить трехмерное положение каждого кончика пальца в любой момент движения руки.
person Y.AL    schedule 15.12.2014

Исправьте 2D-точки с помощью cv::undistortPoints(). Передайте неискаженные точки с обеих камер в cv::triangulatePoints() (вместе с матрицами проекции камеры) и cv::Mat для хранения (однородных) 3D-координат. Вызовите convertPointsFromHomogenous(), чтобы получить обычные (неоднородные) 3D-точки. Примечание: матрицы проекций — это P1 и P2 из cv::stereoRectify и/или <opencv-dir>/samples/cpp/stereo_calib.cpp. Вы можете найти полезное Как правильно использовать cv::triangulatePoints().

person mannyglover    schedule 25.07.2018