OpenCV виртуальная камера вращается / переводится с высоты птичьего полета - PullRequest
7 голосов
/ 07 июля 2011

У меня есть откалиброванная камера, в которой я точно знаю внутренние и внешние данные. Также известна высота камеры. Теперь я хочу виртуально повернуть камеру, чтобы получить вид с высоты птичьего полета, чтобы я мог построить матрицу гомографии с тремя углами поворота и сдвигом.

Я знаю, что 2 точки могут быть преобразованы из одного изображения в другое с помощью гомографии как

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

Есть несколько вещей, которые я хотел бы знать сейчас: если я хочу вернуть координату изображения в ccs, я должен умножить ее на K ^ -1, верно? В качестве координаты изображения я использую (x ', y', 1)?

Тогда мне нужно построить матрицу вращения для вращения ccs ... но какое соглашение я должен использовать? И как мне узнать, как настроить мой WCS?

Следующая вещь - нормаль и расстояние. Правильно ли просто взять три точки, лежащих на земле, и вычислить нормальные из них? и расстояние тогда высота камеры?

Также я хотел бы знать, как я могу изменить высоту виртуально выглядящей камеры для наблюдения за птицами, чтобы я мог сказать, что хочу видеть наземную плоскость с высоты 3 метра. Как я могу использовать единицу «метр» в переводе и матрице омографии?

Пока что было бы здорово, если бы кто-то мог просветить меня и помочь мне. И, пожалуйста, не предлагайте генерировать птичий вид с помощью «getperspective», я уже пробовал это, но этот способ мне не подходит.

Сенна

Ответы [ 2 ]

14 голосов
/ 12 июля 2011

Это код, который я бы посоветовал (он один из моих), на мой взгляд, он отвечает на многие ваши вопросы, Если вы хотите расстояние, я бы уточнил, что оно находится в матрице 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);
}
0 голосов
/ 22 мая 2014

Этот код работает для меня, но я не знаю, почему меняются углы крена и тангажа. Когда я изменяю «альфа», изображение деформируется по высоте, а когда я меняю «бета», изображение деформируется в рулоне. Итак, я изменил свою матрицу вращения, как видно ниже.

Кроме того, 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);

Привет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...