Opencv虚拟相机旋转/平移鸟瞰图

发布于 2024-11-18 15:04:04 字数 503 浏览 3 评论 0原文

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

我知道 2 个点可以通过单应性从一张图像转换为另一张图像

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

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

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

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

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

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

番泻叶

I've a calibrated camera where I exactly know the intrinsic and extrinsic data. Also the height of the camera is known. Now I want to virtually rotate the camera for getting a Bird's eye view, such that I can build the Homography matrix with the three rotation angles and the translation.

I know that 2 points can be transformed from one image to another via Homography as

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

there are a few things I'd like to know now:
if I want to bring back the image coordinate in ccs, I have to multiply it with K^-1, right? As Image coordinate I use (x',y',1) ?

Then I need to built a rotation matrix for rotating the ccs...but which convention should I use? And how do I know how to set up my WCS?

The next thing is the normal and the distance. Is it right just to take three points lying on the ground and compute the normal out of them? and is the distance then the camera height?

Also I'd like to know how I can change the height of the virtually looking bird view camera, such that I can say I want to see the ground plane from 3 meters height. How can I use the unit "meter" in the translation and homography Matrix?

So far for now, it would be great if someone could enlighten and help me. And please don't suggest generating the bird view with "getperspective", I ve already tried that but this way is not suitable for me.

Senna

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏了南城 2024-11-25 15:04:04

这是我建议的代码(这是我的代码之一),在我看来它回答了你的很多问题,
如果你想要距离,我会精确地说它在 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);
}

That is the code i would advise (it's one of mine), to my mind it answers a lot of your questions,
If you want the distance, i would precise that it is in the Z matrix, the (4,3) coefficient.

Hope it will help you...

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);
}
囚你心 2024-11-25 15:04:04

这段代码对我有用,但我不知道为什么要交换横滚角和俯仰角。当我更改“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);

问候

This code works for me but I don't know why the Roll and Pitch angles are exchanged. When I change "alpha", the image is warped in pitch and when I change "beta" the image in warped in roll. So, I changed my rotation matrix, as can be seen below.

Also, the RY has a signal error. You can check Ry at: http://en.wikipedia.org/wiki/Rotation_matrix.

The rotation metrix I use:

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

Regards

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文