opencv - 当只有屏幕空间坐标可用时,将世界空间中的正方形扩展为立方体

标签 opencv math graphics 3d

我有一张 Go-board 的照片,它基本上是一个带有 n*n 个正方形的网格,每个正方形的大小为 a。 根据图像的拍摄方式,网格可以有一个这样的消失点(n = 15,板尺寸 b = 15*a):

Grid with one vanishing point

或像这样的两个消失点(n = 9,棋盘尺寸 b = 9*a):

Grid with two vanishing points

所以我可以得到的是平板四个角的四个屏幕空间坐标:p1,p2,p3,p4。

我想做的是计算板角的相应四个屏幕空间坐标 q1、q2、q3、q4,如果板“向上”移动(垂直于板平面)世界空间由 a,或者换句话说,如果板的厚度为 a,则为板顶部的坐标。

这四个点的信息是否足以计算这个?

如果这还不够,假设相机到电路板中心的距离通常是电路板尺寸 b 的 1.5 倍或 2 倍的量级可能会有所帮助?

根据我的理解,p1-q1、p2-q2、p3-q3、p4-q4 这四条线都会经过位于棋盘下方某处的相同(但未知)的消失点。

对于每条线 p1-q1、p2-q2、...在屏幕空间中是简单地选择一条垂直于地平线的线(由两个消失点 vp1-vp2 给出,或者在只有一个消失点的情况下由 p1-p2 给出)?

做出这个近似后,仍然需要计算 p1-q1、p2-q2、p3-q3、p4-q4 这四条线的长度 ...

非常感谢任何提示!

PS:我正在使用 Objective-C 和 OpenCV

最佳答案

还没有完整的答案,但这可能有助于向前推进。正如MvG 所指出的那样,仅有4 分是不够的。幸运的是,我们知道棋盘是一个正方形,所以即使存在透视变形,2D 中的对角线也应该/将在棋盘中心相交(除非出现严重的鱼眼或其他扭曲)图片)。这是一张测试图像(由 OpenGL 创建,我用作测试输入):

mid point

灰色表面是 2D QUAD 使用 2D 透视扭曲角点(您的输入)。浅绿色/蓝色网格是 3D OpenGL 网格,我用它创建了 2D 角点(以查看它们是否匹配)。绿线是 2D 对角线,橙色点是 2D 角点和对角线交点。如您所见,2D 对角线交叉点与 3D 电路板中间单元中心完全一致。

现在我们可以使用半对角线长度之间的比率来假设/拟合透视图。如果我们处理 <0,9> 范围内的单元格坐标我们想像这样进一步划分对角线:

uv

我仍然不确定(线性比率 l0/(l0+l1) 不起作用)所以我需要检查透视映射方程以找到相对比率依赖并计算逆(当我有时间做这件事时)。

如果这会成功,那么我们就可以计算沿对角线的任何点(我们需要单元格边缘)。如果这样做,我们可以轻松计算任何单元格大小的视觉大小 a并使用完全没有任何 3D 变换矩阵的消失点。

如果这不可行,仍然可以选择使用 DIP/CV 技术来检测细胞交叉,如下所示:

仅使用子弹 #2 但为此您需要考虑您将拥有的图像类型并调整检测器或为其添加预处理 ...

现在回到您的偏移,您可以像这样简单地将单元格向上偏移单元格的视觉大小:

offset

并处理左侧点(插入大小或使用正常的相邻单元格)除非使用太奇怪的板角度,否则这应该有效。

关于opencv - 当只有屏幕空间坐标可用时,将世界空间中的正方形扩展为立方体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49806366/

相关文章:

java - jogl 列出所有图形设备

python - 以给定角度在矩形上查找点

c++ - 使用 opencv C++ 进行面部定向

c++ - Opencv Mat结构坐标

android - Android下OpenCV-imdecode联动错误

arrays - 降低 Perl 数组的时间复杂度

math - 如何找到 X1、X2、Y1、Y2 的 Y 截距

c++ - 如何更改 cv::Mat 中所有像素的值

java - 尝试制作图形计算器,在线程 "AWT-EventQueue-0"java.lang.StackOverflowError 中收到异常

javascript - CSS图形操作——连接动态Divs