OpenCV外部摄像机从特征点 [英] OpenCV extrinsic camera from feature points

查看:249
本文介绍了OpenCV外部摄像机从特征点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我从每个摄像机的视图中获取对象的图片时,如何检索旋转矩阵,平移矢量以及使用OpenCV的每个摄像机的某些缩放因子?对于每个图片我有几个特征点的图像坐标。并非所有的特征点都在所有的图片中可见。
我要将对象的特征点的计算的3D坐标映射到稍微不同的对象,以将第二对象的形状与第一对象对齐。



我听说这是可能使用 cv :: calibrateCamera(...)但我不能得到相当透过它...



有人有这种问题的经验吗?

解决方案

我遇到了同样的问题你,在OpenCV。我有一个立体图像对,我想计算摄像机的外部参数和所有观测点的世界坐标。此问题已在此处理:



Berthold K. P. Horn。重新考虑相对取向。 Berthold K. P. Horn。人工智能实验室,马萨诸塞理工学院,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 {
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 / strong>将给你这个系统的规范1的最小二乘解。这样,您可以获得第二台摄像机的旋转和平移。然而,由于我只是猜测第二个摄像机的旋转,我做了几个猜测它的旋转(参数化使用3x1矢量欧米茄,我使用cv :: Rodrigues计算旋转矩阵),然后我细化这个猜测在带有数字jacobian的Levenberg-Marquardt优化器中重复地求解系统AC = 0。它适用于我,但它有点脏,所以如果你有时间,我鼓励你实现在文件中解释的内容。



编辑:



这是Levenberg-Marquardt优化器中用于评估残差向量的例程:



<$ pre> void Stereo :: eval(Mat& X,Mat& 3> R2Ref = getRot(X); //将3x1欧拉角映射到旋转矩阵
Mat A = buildA(R2Ref,_dirs); //计算测量射线对之间距离的A矩阵
Vec3d c;
Mat cMat(c,false);
SVD :: solveZ(A,cMat); //在第一个摄像机的距离1处找到第二个摄像机的最佳摄像机中心
residue = A * cMat; //计算我们最小化的输出向量的长度
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/


How do I retrieve the rotation matrix, the translation vector and maybe some scaling factors of each camera using OpenCV when I have pictures of an object from the view of each of these cameras? For every picture I have the image coordinates of several feature points. Not all feature points are visible in all of the pictures. I want to map the computed 3D coordinates of the feature points of the object to a slightly different object to align the shape of the second object to the first object.

I heard it is possible using cv::calibrateCamera(...) but I can't get quite through it...

Does someone have experiences with that kind of problem?

解决方案

I was confronted with the same problem as you, in OpenCV. I had a stereo image pair and I wanted to computed the external parameters of the cameras and the world coordinates of all observed points. This problem has been treated here:

Berthold K. P. Horn. Relative orientation revisited. Berthold K. P. Horn. Artificial Intelligence Laboratory, Massachusetts Institute of Technology, 545 Technology ...

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

However, I wasn't able to find a suitable implementation of this problem (perhaps you will find one). Due to time limitations I did not have time to understand all the maths in this paper and implement it myself, so I came up with a quick-and-dirty solution that works for me. I will explain what I did to solve it:

Assuming we have two cameras, where the first camera has external parameters RT = Matx::eye(). Now make a guess about the the rotation R of the second camera. For every pair of image points observed in both images, we compute the directions of their corresponding rays in world coordinates and store them in a 2d-array dirs (EDIT: The internal camera parameters are assumed to be known). We can do this since we assume that we know the orientation of every camera. Now we build an overdetermined linear system AC = 0 where C is the centre of the second camera. I provide you with the function to compute 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;
}

Then calling cv::SVD::solveZ(A) will give you the least-squares solution of norm 1 to this system. This way, you obtain the rotation and translation of the second camera. However, since I just made a guess about the rotation of the second camera, I make several guesses about its rotation (parameterized using a 3x1 vector omega from which i compute the rotation matrix using cv::Rodrigues) and then I refine this guess by solving the system AC = 0 repetedly in a Levenberg-Marquardt optimizer with numeric jacobian. It works for me but it is a bit dirty, so you if you have time, I encourage you to implement what is explained in the paper.

EDIT:

Here is the routine in the Levenberg-Marquardt optimizer for evaluating the vector of residues:

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);
}

By the way, I searched a little more on the internet and found some other code that could be useful for computing the relative orientation between cameras. I haven't tried any code yet, but it seems useful:

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/

这篇关于OpenCV外部摄像机从特征点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆