Стереосистема — получи 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. ]

2

Решение

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

  • Первое использование Реконструкция трехмерного изображения чтобы получить глубокое изображение вашей руки.
  • Затем используйте существующий алгоритм, чтобы получить кончики пальцев на глубине изображения.
  • Наконец, используйте информацию о глубине, чтобы восстановить трехмерное положение кончиков пальцев.
0

Другие решения

Вам может понадобиться очень быстрое и простое решение, основанное на 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:
    solvePnP (model_points, image_points, cameraMatrix ..some_calibration_params)
  7. мы получим матрицу 3х3, которую вы можете определить как:
    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. С помощью этих шагов вы можете оценить трехмерное положение каждого кончика пальца в любой момент при движении руки
0

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

0