PointCloud из двух неискаженных изображений

Я хочу сделать некоторую структуру из движения, используя OpenCV. Это должно произойти на Android. В настоящее время у меня есть cameraMatrix (внутренние параметры) и коэффициенты искажения от калибровки камеры.

Теперь пользователь должен взять 2 изображения из здания, и приложение должно сгенерировать облако точек. Примечание: пользователь может также немного поворачивать камеру смартфона, когда он движется вдоль одной из сторон здания...

На данный момент у меня есть следующая информация:

  • неискаженное левое изображение
  • неискаженное правое изображение
  • список хороших совпадений с использованием SIFT
  • матрица гомографии
  • фундаментальная матрица

Я искал в Интернете, и теперь я очень смущен, как мне действовать... Некоторые говорят, что мне нужно использовать StereoRectify для получения Q и использовать Q с reprojectImageTo3D() для получения pointCloud.

Другие говорят, что мне нужно использовать StereoRectifyUnCalibrated и использовать H1 и H2 из этого метода, чтобы заполнить все параметры triangulatePoints. В triangulatePoints мне нужна проекцияMatrix каждой камеры/изображения, но, насколько я понимаю, это кажется определенно неправильным.

Итак, для меня есть некоторые проблемы:

  • Как мне получить R и T (вращение и перемещение) из всей имеющейся у меня информации
  • Если я использую StereoRectify, первые 4 параметра — это cameraMatrix1, DistortionCoeff1, cameraMatrix2, DistortionCoeff2). Если у меня нет стереокамеры, такой как Kinect, ameraMatrix1 и cameraMatrix2 равны для моей настройки (монокамера на смартфоне)
  • Как я могу получить Q (угадайте, если у меня есть R и T, я могу получить его от StereoRectify)
  • Есть ли другой способ получить projectioMatrices для каждой камеры, чтобы я мог использовать метод триангуляции, предоставляемый OpenCV

Я знаю, что вопросов много, но гугление меня смутило, поэтому мне нужно разобраться. Я надеюсь, что кто-то может помочь мне с моими проблемами.

Спасибо

PS, так как это больше теоретические вопросы, я не публиковал какой-то код. Если вы хотите/нужно увидеть код или значения калибровки моей камеры, просто спросите, и я добавлю их в свою публикацию.


person glethien    schedule 26.03.2014    source источник


Ответы (2)


Я уже писал об использовании оптического потока Farneback для Structure from Motion. Подробности можно прочитать здесь.

Но вот фрагмент кода, это несколько рабочая, но не очень хорошая реализация. Надеюсь, что вы можете использовать его в качестве ссылки.

/* Try to find essential matrix from the points */
Mat fundamental = findFundamentalMat( left_points, right_points, FM_RANSAC, 0.2, 0.99 );
Mat essential   = cam_matrix.t() * fundamental * cam_matrix;

/* Find the projection matrix between those two images */
SVD svd( essential );
static const Mat W = (Mat_<double>(3, 3) <<
                     0, -1, 0,
                     1, 0, 0,
                     0, 0, 1);

static const Mat W_inv = W.inv();

Mat_<double> R1 = svd.u * W * svd.vt;
Mat_<double> T1 = svd.u.col( 2 );

Mat_<double> R2 = svd.u * W_inv * svd.vt;
Mat_<double> T2 = -svd.u.col( 2 );

static const Mat P1 = Mat::eye(3, 4, CV_64FC1 );
Mat P2 =( Mat_<double>(3, 4) <<
         R1(0, 0), R1(0, 1), R1(0, 2), T1(0),
         R1(1, 0), R1(1, 1), R1(1, 2), T1(1),
         R1(2, 0), R1(2, 1), R1(2, 2), T1(2));

/*  Triangulate the points to find the 3D homogenous points in the world space
    Note that each column of the 'out' matrix corresponds to the 3d homogenous point
 */
Mat out;
triangulatePoints( P1, P2, left_points, right_points, out );

/* Since it's homogenous (x, y, z, w) coord, divide by w to get (x, y, z, 1) */
vector<Mat> splitted = {
    out.row(0) / out.row(3),
    out.row(1) / out.row(3),
    out.row(2) / out.row(3)
};

merge( splitted, out );

return out;
person sub_o    schedule 28.03.2014
comment
Да, кажется, я забыл. Это здесь: subokita. ком/2014/03/26/ - person sub_o; 30.03.2014

Это не OpenCV, но вот пример того, что вы просите:

http://boofcv.org/index.php?title=Example_Stereo_Single_Camera

Существует демонстрационное приложение для Android, которое включает этот код здесь:

https://play.google.com/store/apps/details?id=org.boofcv.android

person lessthanoptimal    schedule 26.03.2014
comment
Это не отвечает на мои вопросы. - person glethien; 27.03.2014
comment
(пожимая плечами) Он делает то, о чем вы просите, просто не входит в вашу библиотеку. Однако вам нужно будет посмотреть на источник библиотеки, чтобы получить математику. - person lessthanoptimal; 27.03.2014
comment
Книга Multiple View Geometry in Computer Vision довольно хорошо освещает этот материал. Сейчас у меня его нет под рукой, но поищите, разлагая основную матрицу. Вам понадобится внутренняя матрица камеры, чтобы получить необходимое из основной матрицы. - person lessthanoptimal; 27.03.2014