OpenCV:计算相机和物体之间的角度

Posted

技术标签:

【中文标题】OpenCV:计算相机和物体之间的角度【英文标题】:OpenCV: Calculate Angle between camera and object 【发布时间】:2019-03-09 18:42:34 【问题描述】:

如何计算相机前物体的角度?我的相机分辨率为1280x1024,镜头焦距为8mm,CMOS上每个像素的像素尺寸为4.8微米。当然,必须有可能从中计算出角度。我还计算了物体到相机的距离,一切都在一个层次上。所以只有 X 坐标是有趣的,对吧?

我正在使用 OpenCV 和 Python 进行处理。

我的想法是结合使用镜头的焦距和从传感器中间检测到的物体的 X-Offset,但我确实从中得到了奇怪的角度。

这是角度估计的代码:

首先是点 X 坐标,其次是整个传感器的宽度(1280 像素 * 4.8um),单位为毫米,第三个是焦距,单位为毫米。

角度 = (pointInterpolatedX*6.144)/8

有人可以在这里给我一些帮助吗?谢谢!

另外,我看过这个话题here,但我不太明白。我有更多关于我的相机的信息,而且我的对象只能在 2 维而不是 3 维中移动。所以可能有一种聪明的方法来估计它在相机前地面上的位置。 OpenCV 有什么我可以使用的功能吗?

【问题讨论】:

【参考方案1】:

要获得真正的准确度,您需要校准相机。下面的内容对于第一个近似值就足够了。

下图描绘了我将在此响应中使用的图像 (Xi, Yi) 和相机 (Xc, Yc, Zc) 坐标系 - 它们是OpenCV 使用的那些。它还显示了两个图像点p1p2,它们可能是您感兴趣的物体图像的边界,以及对应的光线r1 r2 将它们投影到相机中心。

首先,让我们将您的焦距镜头转换为像素以简化计算。在 4.8 um 点间距下,传感器的宽度为 4.8 * 1280 um = 6.14 mm。因此,按比例,f_pix : 8 mm = 1280 pix : 6.14 mm,因此 f_pix = 1667 像素。我们现在可以编写最简单的针孔相机矩阵,它假设相机的焦轴与图像正交,并在图像中心与它相交。在 numpy 的表示法中:

K = np.array([[1667, 0, 640], [0, 1667, 512], [0, 0, 1]])

给定这个矩阵,以及相机坐标中的任何 3D 点 P = (X,Y,Z),其投影到的图像坐标 (x, y)图像计算为:

p = K.dot(P)
x, y = p[0]/p[2], p[1]/p[2]

相反,给定一对像素坐标 (x, y),将该像素反向投影到 3D 空间的 3D 射线 r 由下式给出:

Ki = np.linalg.inv(K)
r = Ki.dot([x, y, 1.0])

这是一条“射线”,所有 3D 点 R = s * r,通过乘以任意数 s 获得,将位于同一条线穿过相机中心和像素(x, y)

因此,给定您的边界图像点 p1 = (x1, y1)p2 = (x2, y2),您可以像上面一样计算射线 r1r2 将它们反向投影到 3D 空间中。它们之间的角度很容易通过点积公式计算出来:

cos_angle = r1.dot(r2) / (np.linalg.norm(r1) * np.linalg.norm(r2))
angle_radians = np.acos(cos_angle)

重申一下,上述公式只是一个初步的近似值。真实的相机会有一些非线性镜头失真,您必须对其进行校正才能获得准确的结果,并且焦轴相对于图像会略微偏离中心。所有这些问题都可以通过校准相机来解决。

【讨论】:

最后一个公式给出了两条光线之间的角度,对吧?不是从焦轴到其中一条光线。 正确。如果你想要来自中心的光线,只需计算 r = Ki.dot([x, y, 1]) for x = width/2 and y = height/2 @FrancescoCallari 我尝试了相同的代码来查找距离,但它并不准确。 :(***.com/questions/58709062/… @FrancescoCallari 我使用这种方法找到了两点之间的角度。我试图找到这两点之间的距离 @Roger 如果您知道它们与相机中心的距离,答案很简单,只需将余弦定理应用于相机中心和点形成的三角形,使用如上计算的射线之间的角度.如果您不知道它们离相机有多远,除非您有关于场景的其他信息,否则无法完成。【参考方案2】:

不,你需要知道你的相机角度拿一个量角器并测量它而不是你可以使用这样的东西

x,y=my_coordinates
angle_per_pix=my_cam_angle/1280
angle_vertical=(x-640)*angle_per_pix #-640 beacuse you want angle between middle of camera
angle_horizontal=(x-512)*angle_per_pix

my_cam_angle 示例:

【讨论】:

所以 my_cam_angle 是垂直/水平视野? 在这个例子中垂直如果你测量水平你需要除以 h 像素

以上是关于OpenCV:计算相机和物体之间的角度的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenCV 查找图像中两点之间的角度

如何在 OpenCV 中计算点的 3D 坐标

OpenCV相机标定与畸变校正

OpenCV轮廓检测,计算物体旋转角度

在 OpenCV 中检测对象然后计算对象/相机的位姿

如何测量相机与物体之间的距离