我在视频(或图像)中有4个共面点代表一个四边形(不一定是方形或矩形),我希望能够在它们顶部显示一个虚拟立方体,其中立方体的角正好位于角落视频四边形.
由于这些点是共面的,我可以计算单位平方的角(即[0,0] [0,1] [1,0] [1,1])和四边形的视频坐标之间的单应性.
根据这个单应性,我应该能够计算出正确的相机姿势,即[R | t],其中R是3x3旋转矩阵,t是3x1平移向量,因此虚拟立方体位于视频四边形上.
我已经阅读了很多解决方案(其中一些是关于SO的)并试图实现它们,但它们似乎仅在一些"简单"的情况下工作(例如当视频四边形是正方形时)但在大多数情况下不起作用.
以下是我尝试过的方法(大多数是基于相同的原理,只是翻译的计算略有不同).设K是摄像机的内在矩阵,H是单应性.我们计算:
A = K-1 * H
Run Code Online (Sandbox Code Playgroud)
设a1,a2,a3为A和r1,r2,r3的列向量,即旋转矩阵R的列向量.
r1 = a1 / ||a1||
r2 = a2 / ||a2||
r3 = r1 x r2
t = a3 / sqrt(||a1||*||a2||)
Run Code Online (Sandbox Code Playgroud)
问题是在大多数情况下这不起作用.为了检查我的结果,我将R和t与OpenCV的solvePnP方法获得的结果进行了比较(使用以下3D点[0,0,0] [0,1,0] [1,0,0] [1,1 ,0]).
由于我以相同的方式显示立方体,我注意到在每种情况下solvePnP都提供了正确的结果,而从单应性中获得的姿势大多是错误的.
理论上,因为我的点是共面的,所以可以从单应性计算姿势,但是我找不到从H计算姿势的正确方法.
我对错误的看法有何见解?
尝试@Jav_Rock的方法后编辑
嗨Jav_Rock,非常感谢你的答案,我尝试了你的方法(以及其他许多方法)似乎或多或少都可以.然而,在基于4个共面点计算姿势时,我仍然遇到一些问题.为了检查结果,我将与solvePnP的结果进行比较(由于迭代重投影误差最小化方法,这将更好).
这是一个例子:
正如你所看到的,黑色立方体或多或少都可以,但看起来并不均匀,尽管矢量看似正交.
EDIT2:我在计算它之后对v3进行了规范化(为了强制执行正交性),它似乎也解决了一些问题.
我有两张图片来自不同的位置.第二个摄像头位于右侧,相对于第一个摄像头向上和向后.所以我认为两个视图之间存在透视变换而不仅仅是仿射变换,因为摄像机处于相对不同的深度(我是对的吗?)我在两个图像之间有一些对应的点.我想使用这些对应点来确定每个像素从第1个到第2个图像的变换.
我对函数findFundamentalMat和findHomography感到困惑.... 两者都返回3x3矩阵,两者有什么区别?
是否有任何条件/使用它们的先决条件(何时使用它们)?
哪一个用于将点从第一图像转换为第二图像?在函数返回的3x3矩阵中,它们是否包括两个图像帧之间的旋转和平移?
从维基百科,我们发现基本矩阵是相应图像点之间的关系.在苏答案在这里,它是说本质矩阵E被需要得到相应的点...但我没有照相机内部矩阵计算è.....我只是有两个图像.
我该如何确定相应的点?等待建议..谢谢
opencv transform homography perspectivecamera projective-geometry
这个问题是关于OpenCV的功能findHomography
,getPerspectiveTransform
&getAffineTransform
有什么区别findHomography
和getPerspectiveTransform
?我从文档中理解的是,getPerspectiveTransform
使用4个对应关系(这是计算单应性/透视变换所需的最小值)findHomography
计算变换,即使你提供4个以上的对应关系(大概使用像最小二乘法这样的东西),计算变换也是如此? ).它是否正确?(在这种情况下,OpenCV仍然继续支持getPerspectiveTransform的唯一原因应该是遗留?)
我的下一个问题是,我想知道是否有相当于findHomography
计算仿射变换的东西?即使用最小二乘法或等效鲁棒方法计算和仿射变换的函数.根据文档getAffineTransform
只需3个对应关系(这是计算仿射变换所需的最小值).
最好,
当使用OpenCV的findHomography
函数来估计两组点之间的单应性时,从不同的图像中,即使使用RANSAC或LMEDS,由于输入点内的异常值,有时也会得到差的单应性.
// opencv java example:
Mat H = Calib3d.findHomography( src_points, dst_points, Calib3d.RANSAC, 10 );
Run Code Online (Sandbox Code Playgroud)
如何判断得到的3x3单应矩阵是否可以接受?
我在Stackoverflow和Google中找到了这个问题的答案,但无法找到它.
我找到了这篇文章,但对我来说有点神秘:
这个问题已被问到,但我仍然没有得到它.我通过cv::findHomography
从一组点调用来获得单应矩阵.我需要检查它是否相关.
所提出的方法是计算内部的最大重投影误差并将其与阈值进行比较.但是经过这样的过滤后,我不断进行疯狂的变换,物体边界框转换成几乎一条直线或一些奇怪的非凸四边形,有自交叉等.
可以用什么约束来检查单应矩阵本身是否足够?
我正在使用findHomography
点列表并将结果发送到warpPerspective
.
问题是有时结果是完全垃圾,结果图像由奇怪的灰色矩形表示.
如何检测何时findHomography
向我发送不良结果?
我正在使用OpenCV计算的单应性.我目前使用此单应性来使用下面的函数转换点.这个函数执行我需要的任务但是我不知道它是如何工作的.
任何人都可以一行一行地解释最后3行代码背后的逻辑/理论,我知道这会改变点x,y但是我不清楚它为什么会起作用:
为什么Z
,px
并py
以这种方式计算,元素h
对应的是什么?
非常感谢您的评论:)
double h[9];
homography = cvMat(3, 3, CV_64F, h);
CvMat ps1 = cvMat(MAX_CALIB_POINTS/2,2,CV_32FC1, points1);
CvMat ps2 = cvMat(MAX_CALIB_POINTS/2,2,CV_32FC1, points2);
cvFindHomography(&ps1, &ps2, &homography, 0);
...
// This is the part I don't fully understand
double x = 10.0;
double y = 10.0;
double Z = 1./(h[6]*x + h[7]*y + h[8]);
px = (int)((h[0]*x + h[1]*y + h[2])*Z);
py = (int)((h[3]*x + h[4]*y + h[5])*Z);
Run Code Online (Sandbox Code Playgroud) 从Kinect深度图获得两个连续的3D点云1和2(不是整个云,比如用OpenCV的GoodFeaturesToMatch从云中选择的100个点),我想从1到2计算摄像机的单应性.我理解这是一个投影变换,它已经由很多人完成了:这里(幻灯片12),这里(幻灯片30)和这里似乎是经典论文.我的问题是,虽然我是一名称职的程序员,但我没有数学或触发技巧将其中一种方法转化为代码.由于这不是一个简单的问题,我为解决以下问题的代码提供了大量的赏金:
相机位于原点,沿Z方向看,不规则的五面体[A,B,C,D,E,F]:
相机向左移动-90mm(X),向上移动60mm(Y),向前移动+ 50mm(Z)并向下旋转5°,向右旋转10°,逆时针旋转-3°:
旋转整个场景以使相机返回其原始位置允许我在2处确定顶点的位置:
以下是顶点之前和之后的位置,内在函数等:
请注意,camera2的顶点不是100%准确,有一些故意的噪音.
我需要的代码,必须可以很容易地翻译成VB.Net或C#,必要时使用EMGUCV和OpenCV,获取2组顶点和内在函数并生成此输出:
Camera 2 is at -90 X, +60 Y, +50 Z rotated -5 Y, 10 X, -3 Z.
The homography matrix to translate points in A to B is:
a1, a2, a3
b1, b2, b3
c1, c2, c3
Run Code Online (Sandbox Code Playgroud)
我不知道单应性坐标的单应性是3X3还是3X4,但它必须允许我将顶点从1转换为2.
我也不知道值a1,a2等; 那是你必须找到的; ;-)
500赏金提供'替换'我提供给这个非常相似的问题的赏金,我在那里添加了一个指向这个问题的评论.
编辑2:我想知道我问这个问题的方式是否具有误导性.在我看来,问题更多的是点云拟合而不是相机几何(如果你知道如何平移和旋转A到B,你知道相机变换,反之亦然).如果是这样,那么也许可以用Kabsch的算法或类似的方法获得解决方案
任何人都可以告诉我如何使用RANSAC算法在两个具有一定重叠部分的图像中选择共同的特征点吗?问题来自基于特征的图像拼接.
我想根据从这里提取的这个方案使用控制点转换图像:
A
并B
包含源目标顶点的坐标.
我正在将转换矩阵计算为:
A = [51 228; 51 127; 191 127; 191 228];
B = [152 57; 219 191; 62 240; 92 109];
X = imread('rectangle.png');
info = imfinfo('rectangle.png');
T = cp2tform(A,B,'projective');
Run Code Online (Sandbox Code Playgroud)
到目前为止它似乎正常工作,因为(使用标准化坐标)源顶点产生其目标顶点:
H = T.tdata.T;
> [51 228 1]*H
ans =
-248.2186 -93.0820 -1.6330
> [51 228 1]*H/ -1.6330
ans =
152.0016 57.0006 1.0000
Run Code Online (Sandbox Code Playgroud)
问题是会imtransform
产生意想不到的结果:
Z = imtransform(X,T,'XData',[1 info.Width], 'YData',[1 info.Height]);
imwrite(Z,'projective.png');
Run Code Online (Sandbox Code Playgroud)
我如何用它imtransform
来产生我预期的结果?:
有没有其他方法可以实现它?
matlab image-processing octave homography projective-geometry