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

Joh*_*es 7 opencv translation rotation homography

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

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

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

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

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

接下来是法线和距离.是否只是将三个点放在地上并计算它们的正常值?并且是相机高度的距离?

此外,我想知道如何改变虚拟鸟瞰摄像机的高度,这样我可以说我想看到3米高的地平面.如何在翻译和单应矩阵中使用单位"米"?

到目前为止,如果有人可以启发并帮助我,那将是很棒的.并且请不要建议用"getperspective"生成鸟类视图,我已经尝试过但这种方式不适合我.

塞纳

jma*_*tel 14

这是我建议的代码(它是我的一个代码),在我看来它会回答你的很多问题.如果你想要距离,我会精确地知道它在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);
}
Run Code Online (Sandbox Code Playgroud)

  • @jmartel你有没有任何参考资料详细描述你上面列出的变换?我检查了所有关于相机模型,三维变换,透视等的维基文章,但还没有开悟. (4认同)