Внешняя камера OpenCV с характерных точек - PullRequest
12 голосов
/ 15 ноября 2011

Как мне извлечь матрицу вращения, вектор перевода и, возможно, некоторые коэффициенты масштабирования каждой камеры, используя OpenCV, когда у меня есть изображения объекта из вида каждой из этих камер?Для каждого изображения у меня есть координаты изображения нескольких характерных точек.Не все характерные точки видны на всех изображениях.Я хочу отобразить вычисленные трехмерные координаты характерных точек объекта на немного другой объект, чтобы выровнять форму второго объекта по первому объекту.

Я слышал, что это возможно при использовании cv::calibrateCamera(...), но яне могу пройти через это ...

Есть ли у кого-то опыт с такой проблемой?

Ответы [ 2 ]

12 голосов
/ 19 ноября 2011

Я столкнулся с той же проблемой, что и вы, в OpenCV.У меня была пара стереоизображений, и я хотел вычислить внешние параметры камер и мировые координаты всех наблюдаемых точек.Эта проблема была рассмотрена здесь:

Бертольд К.П. Хорн.Относительная ориентация вновь.Бертольд К.П. Хорн.Лаборатория искусственного интеллекта, Массачусетский технологический институт, 545 Технология ...

http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.64.4700

Однако я не смог найти подходящее решение этой проблемы (возможно, вы найдете один).Из-за нехватки времени у меня не было времени, чтобы разобраться во всей математике в этой статье и реализовать ее самостоятельно, поэтому я нашел быстрое и грязное решение, которое работает для меня.Я объясню, что я сделал, чтобы решить эту проблему:

Предполагая, что у нас есть две камеры, где первая камера имеет внешние параметры RT = Matx :: eye () .Теперь сделайте предположение о вращении R второй камеры.Для каждой пары точек изображения, наблюдаемых на обоих изображениях, мы вычисляем направления их соответствующих лучей в мировых координатах и ​​сохраняем их в 2d-массиве dirs (РЕДАКТИРОВАТЬ: предполагается, что внутренние параметры камеры известны),Мы можем сделать это, так как предполагаем, что знаем ориентацию каждой камеры.Теперь мы строим переопределенную линейную систему AC = 0 , где C - центр второй камеры.Я предоставляю вам функцию для вычисления A:

Mat buildA(Matx<double, 3, 3> &R, Array<Vec3d, 2> dirs)
{
    CV_Assert(dirs.size(0) == 2);
    int pointCount = dirs.size(1);
    Mat A(pointCount, 3, DataType<double>::type);
    Vec3d *a = (Vec3d *)A.data;
    for (int i = 0; i < pointCount; i++)
    {
        a[i] = dirs(0, i).cross(toVec(R*dirs(1, i)));
        double length = norm(a[i]);
        if (length == 0.0)
        {
            CV_Assert(false);
        }
        else
        {
            a[i] *= (1.0/length);
        }
    }
    return A;
}

Затем вызов cv :: SVD :: solveZ (A) даст вам решение нормы 1 для наименьших квадратовсистема.Таким образом, вы получаете вращение и перевод второй камеры.Однако, поскольку я только что сделал предположение о вращении второй камеры, я делаю несколько предположений о ее вращении (параметризованный с использованием вектора омега 3x1, из которого я вычисляю матрицу вращения с помощью cv :: Rodrigues), а затем уточняю этоРешение системы AC = 0 повторяется в оптимизаторе Левенберга-Марквардта с числовым якобианом.Это работает для меня, но это немного грязно, поэтому, если у вас есть время, я призываю вас реализовать то, что объясняется в статье.

РЕДАКТИРОВАТЬ:

Вот процедура в оптимизаторе Левенберга-Марквардта для оценки вектора остатков:

void Stereo::eval(Mat &X, Mat &residues, Mat &weights)
{

        Matx<double, 3, 3> R2Ref = getRot(X); // Map the 3x1 euler angle to a rotation matrix
        Mat A = buildA(R2Ref, _dirs); // Compute the A matrix that measures the distance between ray pairs
        Vec3d c;
        Mat cMat(c, false);
        SVD::solveZ(A, cMat); // Find the optimum camera centre of the second camera at distance 1 from the first camera
        residues = A*cMat; // Compute the  output vector whose length we are minimizing
    weights.setTo(1.0);
}

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

http://www9.in.tum.de/praktika/ppbv.WS02/doc/html/reference/cpp/toc_tools_stereo.html

http://lear.inrialpes.fr/people/triggs/src/

http://www.maths.lth.se/vision/downloads/

2 голосов
/ 18 ноября 2011

Это статические камеры, которые вы хотите откалибровать для будущего использования в качестве стереопары? В этом случае вы хотели бы использовать функцию cv :: stereoCalibrate () . OpenCV содержит пример кода, одним из которых является стерео_calib.cpp, который, возможно, стоит изучить.

...