如何计算图片内部的特定距离?

Posted

技术标签:

【中文标题】如何计算图片内部的特定距离?【英文标题】:How to calculate a specific distance inside of a picture? 【发布时间】:2013-03-18 05:06:38 【问题描述】:

抱歉我的英语不好。我有以下问题:

假设我的移动设备的相机正在显示这张照片。

在图片中您可以看到 4 个不同的位置。我知道每个位置(经度、纬度)。

现在我想知道图片中特定位置的位置。例如,我想在前面 20 米和左边 5 米处有一个矩形。我只知道这一点的纬度/经度,但我不知道,我必须将其放置在图片(x,y)内的哪个位置。例如,在我看来,POS3 位于 (0,400)。 POS4 在 (600,400) 处,依此类推。

我必须将新点放在哪里,即我前面 20 米和左边 5 米? (所以我的输入是:(LatXY,LonXY) 我的结果应该是屏幕上的 (x,y))

我还得到了相机的高度以及相机的 x、y 和 z 轴的角度。

我可以用简单的数学运算来解决这个问题吗?

非常感谢!

【问题讨论】:

你的问题不清楚。如果您知道该位置在前方 20 米和左侧 5 米处,那么您要确切地计算什么? 对不起...,我想知道,图片里面的位置在哪里。我需要在我的视图内有一个点 (x,y),我可以在其中“标记”位置。 【参考方案1】:

您想要的答案将取决于您需要的结果的准确性。正如 danaid 所指出的,图像传感器的非线性和大气失真等其他因素可能会导致误差,但在不同设备上使用不同的相机等将是难以解决的问题。因此,让我们从获得一个合理的近似值开始,当需要更高的准确性时可以对其进行调整。

首先,如果您愿意,您可以忽略来自设备的方向信息。如果您有五个位置(POS1 - POS4 和相机,在一组一致的坐标基础上),您就拥有了所需的一切。事实上,您甚至不需要所有这些点。

关于一致坐标的说明。在他的尺度上,一旦你使用将经纬度转换为米,使用 cos(lat) 作为比例因子,你应该能够从“平坦地球”的角度对待每个人。然后您只需要记住相机的 x-y 平面大致是全局 x-z 平面。

概念背景 下图展示了点在图像平面上的投影。用于透视的 dz 可以直接使用远点和近点之间的视野距离与它们的物理距离的比例得出。在简单情况中,POS1 到 POS2 的线平行于 POS3 到 POS4 的线,透视因子就是两条线的缩放比例:

Scale (POS1, POS2) = pixel distance (pos1, pos2) / Physical distance (POS1, POS2)
Scale (POS3, POS4) = pixel distance (pos3, pos4) / Physical distance (POS3, POS4)
Perspective factor = Scale (POS3, POS4) / Scale (POS1, POS2)

因此,应用于矩形顶点的透视因子将是与线之间顶点的距离的比例。简化:

Factor(rect) ~= [(Rect.z - (POS3, POS4).z / ((POS1, POS2).z - (POS3, POS4).z)] * Perspective factor.

回答

透视变换相对于焦点在观察方向上的距离是线性的。下图是 X 轴平行于图像平面绘制,Y 轴指向观察方向。在该坐标系中,对于任意点 P 和距原点任意距离的图像平面,投影点 p 的 X 坐标 p.x 与 P.x/P.y 成正比。这些值可以线性插值。

在图中,tp 是目标点的期望投影。要获得 tp.x,例如使用距离调整在 pos1.x 和 pos3.x 之间进行插值,如下所示:

tp.x = pos1.x + ((pos3.x-pos1.x)*((TP.x/TP.y)-(POS1.x/POS1.y))/((POS3.x/POS3.y)-(POS1.x/POS1.y))

这种方法的优点是它不需要任何关于每个像素所看到的角度的先验知识,并且对于相机位置和方向的合理错误,它相对稳健。

进一步细化

使用更多数据意味着能够弥补更多错误。在多个视点的情况下,可以使用Tienstra method 校准摄像机的位置和方向。可以在here 找到这种方法的简明证明(使用重心坐标)。

由于所需的变换都是基于齐次坐标的线性变换,因此您可以应用 barycentric coordinates 基于任意三个或更多点进行插值,假设它们在齐次 3 空间中的 X、Y、Z、W 坐标和它们的 (x ,y) 图像空间中的坐标。点越接近目标点,非线性可能越不重要,因此在您的示例中,您将使用 POS 1 和 POS3,因为矩形在左侧,而 POS2 或 POS4 取决于相对距离.

(重心坐标可能是最常见的用于在 3D 图形中的三角形(片段)上插入颜色的方法。)

编辑:重心坐标仍然需要 W 齐次坐标因子,这是表示距焦点距离的透视校正的另一种方式。有关详细信息,请参阅 GameDev 上的this article。

两个相关的 SO 问题:perspective correction of texture coordinates in 3d 和 Barycentric coordinates texture mapping。

【讨论】:

嘿。如果我正确理解您的回答,我只需要在给定点之间进行插值。嗯...我不太确定这是否给了我很好的价值。例如在我的图片中,P1 和 P3 之间的位置(我的意思是从 P1 到 P3 的确切路径(以米为单位,而不是在屏幕上)应该在图片中 P3 的位置下方 1-2 厘米。如果我在根据您的建议,该位置应恰好在 P1 和 P3 的中间。以米为单位,“新”位置将在 P1 前面约 2-3 米处。 我认为我的回答很不清楚。我的意思是:假设 P3 位于相机前方 20 厘米处。 P1约为。镜头前 120 米处。现在我想找到应该在摄像机前 60 米处的 PX。使用您的解决方案,它将位于 P1 和 P3 的中间,但它应该位于 P1 旁边的某个位置。 很抱歉我没说清楚。插值需要根据距焦点的距离进行加权。这就是齐次坐标中 W 坐标的目的。我将尝试找到更清晰的参考并更新我的答案。 我已更新我的答案以阐明如何应用插值。抱歉之前没说清楚! 这太棒了!我不知道该怎么感谢你!非常感谢!【参考方案2】:

我发现了几个问题。

唯一真正的错误是您将投影放大了 _canvasWidth/2 等,而不是从主点平移那么远 - 将这些值添加到投影结果中,乘法就像“缩放”到投影那么远。

其次,处理全局笛卡尔坐标空间是个坏主意。使用您使用的公式, (60.1234, 20.122) 和 (60.1235, 20.122) 之间的差异(即小的纬度差异)会导致所有 3 个轴上的变化幅度相似,这感觉不对。

采用与计算机图形相同的方法更简单:将您的相机设置为“相机空间”的原点,并通过获取相机位置和相机位置之间的半正弦距离(或类似距离)在世界对象和相机空间之间进行转换物体的位置。见这里:http://www.movable-type.co.uk/scripts/latlong.html

第三,您的透视投影计算适用于您可能没有的理想针孔相机。这只是一个小的修正,但为了准确起见,您需要弄清楚如何额外应用与相机的内在相机参数相对应的投影。有两种方法可以做到这一点:您可以将其作为现有方案的后乘法进行,或者您可以从乘以 3x3 矩阵更改为使用完整的 4x4 相机矩阵:http://en.wikipedia.org/wiki/Camera_matrix,其中包含参数。

使用这种方法,透视投影关于原点对称 - 如果您不检查 z 深度,您会将您身后的点投影到屏幕上,就好像它们与您前面的 z 距离相同。

最后,我不确定 android API,但请确保您获得的是真正的北向轴承而不是磁北向轴承。某些平台根据参数或配置返回。 (如果这就是 API 想要的,那么你的度数是以弧度为单位的等等 - 愚蠢的事情,但我已经减少了调试时间:))。

【讨论】:

哇!感谢您提供的内容丰富的回复!我会按照你的想法再次测试它;)。但我还有一个悬而未决的问题:在这个公式中,我应该在哪里使用相机的水平和垂直视角?我不认为,如果不使用这些值,我可以获得任何好的结果,不是吗?再次感谢! 如果视角是指镜头的视角,则(近似)由焦距和屏幕分辨率决定。将焦距添加到相机矩阵将“解决”这个问题。 (如果您有一个方形显示器并且传感器的视图被相应地裁剪,那么角度将是相等的)...... ...另一种方法是只使用基本的三角函数和相对方位角:从您的视图的中心点到边缘是一个直角三角形,角度为 1/2 视角(我们称之为 Alpha) , 占用 X 个屏幕像素。您的虚拟点相对于中心是 Beta 度。您的虚拟点的屏幕位置 u 是 tan(beta)/tan(alpha) * X - 对两个轴重复(不需要投影矩阵,您是手动进行的。我不记得相对方位是否更准确在短距离使用相机原点方法或使用带 GPS 坐标的球面坐标方位 ...我说“近似”是因为如果您使用的是手机,它们大多具有宽屏显示器,可能会在一个或两个轴上产生非线性失真 - 到确实正确,您必须进行一些相机校准,但如果您使用 GPS 进行定位,使用基本的手机传感器进行定位,那毫无意义 - 您的位置和定位精度一开始就会很差。 再次感谢您的回答!我已经奖励了它;)看起来你一直在做类似的事情。你有一些我可以看看的开源代码吗?非常感谢:)【参考方案3】:

如果您知道相机框架中的点和真实世界的坐标,一些简单的线性代数就足够了。像 OpenCV 这样的包将具有这种类型的功能,或者您也可以自己创建投影矩阵:

http://en.wikipedia.org/wiki/3D_projection

一旦你有了一组点,它就像填充几个向量来求解方程组一样简单。这会给你一个投影矩阵。一旦你有一个投影矩阵,你可以假设这 4 个点是平面的。将任意 3D 坐标相乘,得到对应的 2D 图像平面坐标。

【讨论】:

感谢您的回答!你能给我一点提示,我必须从哪里开始?我对预测不是很熟悉,我不知道我必须做什么:( 这里是过程描述的链接(如果手工完成)***.com/questions/8925569/…。我道歉,但我的计算机图形课程是几年前的。 OpenCV 是一个强大的计算机视觉库,具有校准功能:docs.opencv.org/doc/tutorials/calib3d/camera_calibration/… 您应该搜索的主要术语是:相机校准、投影矩阵、方程组。 嘿,我已经编辑了我的问题并且知道投影矩阵有问题。另外,我在这个问题上加了赏金;)。你能看看吗?谢谢:)

以上是关于如何计算图片内部的特定距离?的主要内容,如果未能解决你的问题,请参考以下文章

计算机网络-网络层-内部网关协议RIP

怎么判断某一点在一个不规则的图形内部

光模块传输距离如何计算?

Android 百度地图API 如何计算两个坐标之间的驾车距离?

如何链接 Laravel 模块内部的资产?

Kmeans