Преобразовать положение точки в трапеции в положение прямоугольника

Я пытаюсь выяснить, как я могу преобразовать координату Pxy внутри зеленой трапеции ниже в эквивалентную координату на реальной плоскости земли.

У меня есть точные размеры комнаты, то есть я могу точно сказать, как долго A,B,C и D находятся в этой комнате, как показано ниже. Также я знаю, как долго A,B,C и D находятся в этом зеленом треугольнике (по координатам).

Я уже читал о гомографии и преобразовании матриц, но не могу действительно обдумать это. Любой вход, направляющий меня в правильном направлении, будет оценен.

Спасибо!

3 ответа

Решение

Просто ради завершения. В итоге я посмотрел на тему, предложенную @mmgp, и реализовал решение, эквивалентное предложенному Кристофером Р. Реном:

Оценка Перспективного Преобразования

Это оказалось очень хорошо для моего случая, хотя с камерой были некоторые искажения.

Здесь код вычисляет матрицу аффинного преобразования с использованием библиотеки Opencv (она показывает, как преобразовать трапецию в прямоугольник и как найти матрицу преобразования для дальнейших вычислений):

//example from book
//   Learning OpenCV: Computer Vision with the OpenCV Library
//     by Gary Bradski and Adrian Kaehler
//     Published by O'Reilly Media, October 3, 2008

#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    IplImage *src=0, *dst=0;

    // absolute or relative path to image should be in argv[1]
    char* filename = argc == 2 ? argv[1] : "Image0.jpg";
    // get the picture
    src = cvLoadImage(filename,1);

    printf("[i] image: %s\n", filename);
    assert( src != 0 );


    // points (corners of )
    CvPoint2D32f srcQuad[4], dstQuad[4];
    // transformation matrix
    CvMat* warp_matrix = cvCreateMat(3,3,CV_32FC1);

    // clone image
    dst = cvCloneImage(src);

    // define all the points
    //here the coordinates of corners of your trapezoid 
    srcQuad[0].x = ??;   //src Top left
    srcQuad[0].y = ??;
    srcQuad[1].x = ??;   //src Top right
    srcQuad[1].y = ??;
    srcQuad[2].x = ??;   //src Bottom left
    srcQuad[2].y = ??;
    srcQuad[3].x = ??;   //src Bot right
    srcQuad[3].y = ??;
    //- - - - - - - - - - - - - -//
    //coordinates of rectangle in src image 
    dstQuad[0].x = 0;       //dst Top left
    dstQuad[0].y = 0;
    dstQuad[1].x = src->width-1;  //dst Top right
    dstQuad[1].y = 0;
    dstQuad[2].x = 0;     //dst Bottom left
    dstQuad[2].y = src->height-1;      
    dstQuad[3].x = src->width-1;  //dst Bot right
    dstQuad[3].y = src->height-1;

    // get transformation matrix that you can use to calculate 
    //coordinates of point Pxy  
    cvGetPerspectiveTransform(srcQuad,dstQuad,warp_matrix);
    // perspective transformation
    cvWarpPerspective(src,dst,warp_matrix);


    cvNamedWindow( "cvWarpPerspective", 1 );
    cvShowImage( "cvWarpPerspective", dst );

    cvWaitKey(0);

    cvReleaseMat(&warp_matrix);

    cvReleaseImage(&src);
    cvReleaseImage(&dst);

    cvDestroyAllWindows();
    return 0;

Надеюсь, это будет полезно!


Если я правильно понимаю ваш вопрос, вы ищете матрицу преобразования, которая выражает положение и ориентацию ("поза") вашей камеры относительно мира. Если у вас есть эта матрица - давайте назовем ее M - вы можете отобразить любую точку от координатной рамки вашей камеры до мировой координатной рамки и наоборот. В вашем случае вы захотите преобразовать прямоугольник в плоскость (0, 1, 0)^T + 0 в мировых координатах.

Есть несколько способов вывести эту позу Матрицы. Прежде всего вам нужно знать другую матрицу - K - которая описывает внутренние параметры камеры для преобразования позиций в координатной рамке камеры в фактические положения пикселей. Это включает в себя стандартную проекцию с точечным отверстием, а также радиальное искажение и некоторые другие вещи.

Чтобы определить K и M, вы должны откалибровать камеру. Обычно это делается путем выбора калибровочного шаблона (например, шахматной доски), для которого известны позиции шахматных полей. Затем вы можете установить так называемые точечные соответствия между известными позициями на шаблоне и наблюдаемыми позициями пикселей. Когда у вас будет достаточно этих пар точек, вы можете решить Матрицу H = KM. Это ваша матрица гомографии, о которой вы уже упоминали. Когда у вас есть это, вы можете восстановить K и M.

Так много для теории. Для практической части я бы предложил взглянуть на документацию OpenCV (например, вы можете начать здесь: калибровка камеры OpenCV и здесь: оценка позы OpenCV).

Я надеюсь, что это укажет вам правильные направления;)

Другие вопросы по тегам