【问题标题】:Opencv virtually camera rotating/translating for bird's eye viewOpencv虚拟相机旋转/平移鸟瞰图
【发布时间】:2011-07-07 06:49:19
【问题描述】:

我有一个校准过的相机,我完全知道内在和外在数据。相机的高度也是已知的。现在我想虚拟地旋转相机以获得鸟瞰图,这样我就可以构建具有三个旋转角度和平移的单应矩阵。

我知道可以通过 Homography 将 2 个点从一个图像转换为另一个图像

x=K*(R-t*n/d)K^-1 * x'

现在我想知道一些事情: 如果我想带回 ccs 中的图像坐标,我必须将它乘以 K^-1,对吗?作为图像坐标我使用 (x',y',1) ?

然后我需要建立一个旋转矩阵来旋转 ccs...但是我应该使用哪种约定?我怎么知道如何设置我的 WCS?

接下来是法线和距离。只取地上的三个点并计算它们的法线是否正确?距离然后是相机高度?

我还想知道如何更改虚拟鸟瞰相机的高度,这样我就可以说我想从 3 米的高度看到地平面。如何在翻译和单应矩阵中使用单位“米”?

到目前为止,如果有人可以启发和帮助我,那就太好了。请不要建议使用“getperspective”生成鸟瞰图,我已经尝试过,但这种方式不适合我。

塞纳

【问题讨论】:

  • 代码对您有帮助吗?如果没有,您可以在这里发布您的新问题吗?

标签: opencv rotation translation homography


【解决方案1】:

这是我建议的代码(它是我的一个),在我看来它回答了你的很多问题, 如果你想要距离,我会精确地说它在 Z 矩阵中,即 (4,3) 系数。

希望对你有帮助...

Mat source=imread("Whatyouwant.jpg");
int alpha_=90., beta_=90., gamma_=90.;
int f_ = 500, dist_ = 500;

Mat destination;

string wndname1 = getFormatWindowName("Source: ");
string wndname2 = getFormatWindowName("WarpPerspective: ");
string tbarname1 = "Alpha";
string tbarname2 = "Beta";
string tbarname3 = "Gamma";
string tbarname4 = "f";
string tbarname5 = "Distance";
namedWindow(wndname1, 1);
namedWindow(wndname2, 1);
createTrackbar(tbarname1, wndname2, &alpha_, 180);
createTrackbar(tbarname2, wndname2, &beta_, 180);
createTrackbar(tbarname3, wndname2, &gamma_, 180);
createTrackbar(tbarname4, wndname2, &f_, 2000);
createTrackbar(tbarname5, wndname2, &dist_, 2000);

imshow(wndname1, source);
while(true) {
    double f, dist;
    double alpha, beta, gamma;
    alpha = ((double)alpha_ - 90.)*PI/180;
    beta = ((double)beta_ - 90.)*PI/180;
    gamma = ((double)gamma_ - 90.)*PI/180;
    f = (double) f_;
    dist = (double) dist_;

    Size taille = source.size();
    double w = (double)taille.width, h = (double)taille.height;

    // Projection 2D -> 3D matrix
    Mat A1 = (Mat_<double>(4,3) <<
        1, 0, -w/2,
        0, 1, -h/2,
        0, 0,    0,
        0, 0,    1);

    // Rotation matrices around the X,Y,Z axis
    Mat RX = (Mat_<double>(4, 4) <<
        1,          0,           0, 0,
        0, cos(alpha), -sin(alpha), 0,
        0, sin(alpha),  cos(alpha), 0,
        0,          0,           0, 1);

    Mat RY = (Mat_<double>(4, 4) <<
        cos(beta), 0, -sin(beta), 0,
                0, 1,          0, 0,
        sin(beta), 0,  cos(beta), 0,
                0, 0,          0, 1);

    Mat RZ = (Mat_<double>(4, 4) <<
        cos(gamma), -sin(gamma), 0, 0,
        sin(gamma),  cos(gamma), 0, 0,
        0,          0,           1, 0,
        0,          0,           0, 1);

    // Composed rotation matrix with (RX,RY,RZ)
    Mat R = RX * RY * RZ;

    // Translation matrix on the Z axis change dist will change the height
    Mat T = (Mat_<double>(4, 4) <<
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, dist,
        0, 0, 0, 1);

    // Camera Intrisecs matrix 3D -> 2D
    Mat A2 = (Mat_<double>(3,4) <<
        f, 0, w/2, 0,
        0, f, h/2, 0,
        0, 0,   1, 0);

    // Final and overall transformation matrix
    Mat transfo = A2 * (T * (R * A1));

    // Apply matrix transformation
    warpPerspective(source, destination, transfo, taille, INTER_CUBIC | WARP_INVERSE_MAP);

    imshow(wndname2, destination);
    waitKey(30);
}

【讨论】:

  • 首先,非常感谢,代码对我帮助很大。但现在我想多了解一点: - 为什么我不能用逆相机矩阵 A2^-1 重新投影 2d->3d 投影? - 关于高度:我现在如何将我的虚拟相机设置为一个高度?直到现在我的值是 500 并且真的不知道这有多高。我知道我的相机在拍摄图像时例如离地面 0.5 米,我如何在这里使用它来移动 Z 以便我有一个离地面 2 米的相机?非常感谢
  • 好吧,我刚刚发现,它也适用于单应性 H=k(R+nt/dist)*k^-1,但我仍然有高度的问题。对于正常计算,我拍摄了两个位于地面上的图像点,这应该可以,对吧?还是取 n=(0,0,1) 更好?无论如何,需要以某种方式将相机位置更改为距地面约 2 米的位置
  • 我很抱歉 Johannes 但你能否在所有公式中更精确一点很想在你的脑海中帮助你,不幸的是我不是!您能否再详细说明您的问题...此外,如果您喜欢答案,则可以接受和/或投票。我猜这就是stackoverflow的哲学,非常感谢!朱利安,
  • 所以蜜蜂如此不精确。所以 K 是我的相机固有矩阵: (f,0,cx;0,f,cy;0,0,1) n 是平面的法线,距离相机中心的距离(我假设是 0.54 米) , t 是我的平移向量,R 是旋转矩阵。根据 Faugeras 的说法,一个点可以通过 Homography 映射到一个点,其定义为:H=K*(R+t*n/dist)*K^-1
  • @jmartel 您是否有任何参考资料详细描述了您上面列出的转换?我查看了所有关于相机模型、3d 变换、透视等的 wiki 文章,但还没有得到启发。
【解决方案2】:

此代码适用于我,但我不知道为什么要交换 Roll 和 Pitch 角度。当我更改“alpha”时,图像会在音调上扭曲,当我更改“beta”时,图像会在滚动中扭曲。所以,我改变了我的旋转矩阵,如下所示。

另外,RY 有一个信号错误。您可以通过以下方式查看 Ry:http://en.wikipedia.org/wiki/Rotation_matrix

我使用的旋转矩阵:

Mat RX = (Mat_<double>(4, 4) <<
    1,          0,           0, 0,
    0, cos(beta), -sin(beta), 0,
    0, sin(beta),  cos(beta), 0,
    0,          0,           0, 1);

Mat RY = (Mat_<double>(4, 4) <<
     cos(alpha), 0,  sin(alpha), 0,
              0, 1,           0, 0,
    -sin(alpha), 0,  cos(alpha), 0,
              0, 0,           0, 1);

Mat RZ = (Mat_<double>(4, 4) <<
    cos(gamma), -sin(gamma), 0, 0,
    sin(gamma),  cos(gamma), 0, 0,
    0,          0,           1, 0,
    0,          0,           0, 1);

问候

【讨论】:

    猜你喜欢
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    • 1970-01-01
    • 2021-04-05
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多