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

8
我该如何计算相机前方物体的角度?我的相机分辨率为1280x1024,镜头的焦距为8mm,CMOS上每个像素的像素大小为4.8微米。从这些参数中肯定可以计算出角度。同时,我已经计算出了物体到相机的距离,并且一切都在同一平面上。因此,只有X坐标是有用的,对吗?
我正在使用OpenCV和Python进行处理。
我的想法是使用镜头的焦距与检测到的物体从传感器中心的X偏移量相结合,但是我从中得到的角度很奇怪。
这是角度估计的代码:
首先是点的X坐标,第二个是整个传感器的宽度(1280像素* 4.8um)以毫米为单位,第三个是以毫米为单位的焦距。 角度=(pointInterpolatedX * 6.144)/ 8
能否有人给我帮助?谢谢!
此外,我看了看这里的主题,但我无法完全理解它。我对我的相机有更多信息,而且我的物体只能在2个维度上移动,而不是3个维度。因此,可能有一种聪明的方式来估计它在相机前方地面上的位置。OpenCV有任何我可以使用的功能吗?
2个回答

6
为了获得更准确的结果,您需要校准相机。以下内容足以进行初步近似。
下面的图像描述了我在此回应中使用的图像(Xi,Yi)和相机(Xc、Yc、Zc)坐标系统 - 这些是OpenCV使用的坐标系统。它还显示了两个图像点p1和p2,它们可能是您感兴趣的对象的图像边界,以及将它们投影到相机中心的对应射线r1和r2。

Image axes

首先,让我们将您的焦距转换为像素,以简化计算。在4.8微米的点距下,传感器的宽度为4.8 * 1280微米= 6.14毫米。因此,按比例计算,f_pix:8毫米= 1280像素:6.14毫米,因此f_pix = 1667像素。现在我们可以编写最简单的针孔相机矩阵,假设相机的焦轴垂直于图像,并在图像中心相交。在numpy的符号中:
K = np.array([[1667, 0, 640], [0, 1667, 512], [0, 0, 1]])

给定这个矩阵,以及相机坐标系中的任意三维点 P = (X,Y,Z),其在图像上的投影的图像坐标 (x, y) 计算如下:
p = K.dot(P)
x, y = p[0]/p[2], p[1]/p[2]

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

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


这是一个“光线”,因为通过将其与任意数字 s 相乘得到的所有3D点R = s * r,都将位于通过摄像机中心和像素(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)

再次强调,上述公式仅是第一次近似。真实相机会存在一些非线性镜头畸变问题,您需要进行校正才能获得准确的结果,并且对焦轴略微偏离图像中心。所有这些问题都可以通过校准相机来解决。

@FrancescoCallari 我尝试了相同的代码来查找距离,但它并不精确。 :( https://stackoverflow.com/questions/58709062/backprojecting-to-find-the-distance-of-pixel-from-camera - user6092898
@FrancescoCallari 我使用这种方法找到了两点之间的角度。我正在尝试找到这两点之间的距离。 - user6092898
@Roger 如果你知道它们距离相机中心的距离,答案就很简单了,只需将余弦定理应用于由相机中心和点形成的三角形,使用上面计算出的射线之间的角度。如果你不知道它们距离相机有多远,除非你有关于场景的其他信息,否则无法完成。 - Francesco Callari
我有两个点P1和P2。我知道点P1到相机的距离。另一个点的距离是未知的,因为它在不断移动。在这种情况下能否找到距离? - user6092898
@Roger,请提出一个单独的问题,并尽可能提供详细信息。这是一个比本答案涵盖的更大的话题。 - Francesco Callari
显示剩余2条评论

0

不,你需要知道你的摄像机角度,拿一个量角器测量它,然后你可以使用类似这样的东西。

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的示例:

cam view

angle


那么my_cam_angle是垂直/水平视野角度吗? - KalvinB
在这个例子中,如果你测量的是水平的话,你需要除以h像素。 - Rifat Alptekin Çetin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接