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

3 ответа

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

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

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

Вам может понадобиться очень быстрое и простое решение, основанное на 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. мы получим матрицу 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. С помощью этих шагов вы можете оценить трехмерное положение каждого кончика пальца в любой момент при движении руки
Другие вопросы по тегам