我试图找出如何将下面绿色梯形内的坐标 Pxy 转换为真实地平面上的等效坐标。
我有房间的确切尺寸,这意味着我可以准确地说出 A、B、C 和 D 在下面显示的那个房间里有多长。我也知道 A、B、C 和 D 在那个绿色三角形中的长度(坐标)。
我已经在阅读有关单应性和矩阵变换的内容,但无法真正理解它。任何将我引导到正确方向的输入将不胜感激。
谢谢!
我试图找出如何将下面绿色梯形内的坐标 Pxy 转换为真实地平面上的等效坐标。
我有房间的确切尺寸,这意味着我可以准确地说出 A、B、C 和 D 在下面显示的那个房间里有多长。我也知道 A、B、C 和 D 在那个绿色三角形中的长度(坐标)。
我已经在阅读有关单应性和矩阵变换的内容,但无法真正理解它。任何将我引导到正确方向的输入将不胜感激。
谢谢!
有代码使用库 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 姿势估计)。
我希望这将为您指明正确的方向;)
只是为了完成。我最终查看了@mmgp 建议的线程并实现了一个与 Christopher R. Wren 提出的解决方案等效的解决方案:
事实证明,这对我的情况非常有效,尽管相机有些失真。