Подтвердить что ты не робот

Внешняя камера OpenCV из точек функции

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Предполагая, что у нас есть две камеры, где первая камера имеет внешние параметры RT = Matx:: eye(). Теперь сделайте предположение о вращении R второй камеры. Для каждой пары точек изображения, наблюдаемых на обоих изображениях, мы вычисляем направления их соответствующих лучей в мировых координатах и ​​сохраняем их в 2d-массиве dirs (EDIT: предполагается, что параметры внутренней камеры известны). Мы можем это сделать, поскольку мы предполагаем, что мы знаем ориентацию каждой камеры. Теперь мы построим переопределенную линейную систему 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) даст вам решение этой нормы с наименьшими квадратами. Таким образом, вы получаете поворот и перевод второй камеры. Однако, поскольку я только что сделал предположение о вращении второй камеры, я делаю несколько догадок о ее вращении (параметризованный с использованием омега вектора 3x1, из которого я вычисляю матрицу вращения с использованием cv:: Rodrigues), а затем уточню это предположение решая систему AC = 0 повторно в оптимизаторе Левенберга-Марквардта с числовым якобием. Это работает для меня, но это немного грязно, поэтому, если у вас есть время, я рекомендую вам реализовать то, что объяснено в статье.

EDIT:

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

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

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