如何从像素坐标到光轴的角度(物体检测对齐)
how to go from pixel coordinates to angle off the optical axis (Object detection alignment)
我正在制作一个可以检测到球并去接球的机器人。
因为我在 raspberry pi 上进行检测,所以我认为使用图像而不是实时检测会更好。
机器人旋转45度并拍照。如果没有检测到球,它会再移动 45 度,直到检测到球。
这就是问题所在:检测到球后,球可能在图像上的任何位置,所以我需要制定一个算法,告诉机器人它应该转动多少度才能与球居中对齐。
机器人检测球的方式如下:
- Google 云视觉API,如果没有检测到球...
- 一个 TF-lite 模型检测将 运行。如果用这个没有检测到球...
- 旋转。
项目使用的相机:Raspberry pi Noir V2 (res HD)
语言:Python,但主要是我需要想法。
P.S.: 我是机器人技术的新手,所以任何帮助将不胜感激。
第一次在Whosebug上提问,遗漏了一些信息。
你问的是如何处理相机矩阵,如何使用相机的“内在”,以及一些线性代数。
specs for the "Raspberry pi Noir V2 (res HD)":
- 1.12 µm 像素尺寸(设计)
- 3.04 毫米焦距(设计)
- 全分辨率:3280 x 2464(设计)
- 全分辨率 FoV:H 62.28°,V 48.83°,D 74.16°(计算)
相机矩阵K
大体上是这样的
全分辨率焦距(以像素为单位)为f = (3.04 mm) / (1.12 µm/pixel) = 2714.3 [pixels]
“1920x1080”视频模式不合并,只裁剪。这意味着 f = 2714
也适用。这意味着视频模式的视野实际上是水平38.96°,垂直22.5°,对角线44.2°。
注意:对于合并模式,如果合并为 2x2,则 f
减半,即使用 1357。
我不知道静态图片是如何制作的。完整的传感器具有 4:3 纵横比。假设 1920x1080 的帧完全安装在那里(接触边,裁剪顶部和底部),比例因子为 0.585 和 f = 1589,FoV 为 62.28° x 37.54°,对角线为 69.46°。
焦距也可以根据分辨率和视野来计算,但像素间距和镜头焦距是标称设计参数,视野来自于此(以及镜头畸变等缺陷)。
然后我们有 cx = (width-1) / 2 = 959.5
和 cy = (height-1) / 2 = 539.5
。
现在你有了矩阵的值。
通过计算K p
将一个3D点p
投影到图像上,这是一个矩阵乘法。可以做相反的事情。您可以将图片上的一个点重新投影回世界。它现在是一个向量,一条射线,一个方向。
如果你有(x,y)
作为图片坐标,计算:
v_x = (x - cx) / f
# v_y = (y - cy) / f
最后是水平角:
alpha = atan(v_x) # radians, or
alpha = atan(v_x) * 180/pi # degrees
(与光轴的对角线角度为atan(hypot(v_x, v_y))
)
对于左边缘 (x=0) 上的点,这意味着向左转 19.5 度。
所有这些都假设图片没有被镜头扭曲。对于小角度,这无关紧要。一些相机具有几乎不会变形的特殊镜头。某些相机,尤其是运动相机,有意采用近鱼眼镜头(意味着严重失真)。
如果你需要处理镜头畸变,那就是另一个话题了。有一些常见的镜头畸变模型可以使用少至 4 个参数。 MATLAB和OpenCV都自带标定方法
我正在制作一个可以检测到球并去接球的机器人。
因为我在 raspberry pi 上进行检测,所以我认为使用图像而不是实时检测会更好。
机器人旋转45度并拍照。如果没有检测到球,它会再移动 45 度,直到检测到球。
这就是问题所在:检测到球后,球可能在图像上的任何位置,所以我需要制定一个算法,告诉机器人它应该转动多少度才能与球居中对齐。
机器人检测球的方式如下:
- Google 云视觉API,如果没有检测到球...
- 一个 TF-lite 模型检测将 运行。如果用这个没有检测到球...
- 旋转。
项目使用的相机:Raspberry pi Noir V2 (res HD)
语言:Python,但主要是我需要想法。
P.S.: 我是机器人技术的新手,所以任何帮助将不胜感激。 第一次在Whosebug上提问,遗漏了一些信息。
你问的是如何处理相机矩阵,如何使用相机的“内在”,以及一些线性代数。
specs for the "Raspberry pi Noir V2 (res HD)":
- 1.12 µm 像素尺寸(设计)
- 3.04 毫米焦距(设计)
- 全分辨率:3280 x 2464(设计)
- 全分辨率 FoV:H 62.28°,V 48.83°,D 74.16°(计算)
相机矩阵K
大体上是这样的
全分辨率焦距(以像素为单位)为f = (3.04 mm) / (1.12 µm/pixel) = 2714.3 [pixels]
“1920x1080”视频模式不合并,只裁剪。这意味着 f = 2714
也适用。这意味着视频模式的视野实际上是水平38.96°,垂直22.5°,对角线44.2°。
注意:对于合并模式,如果合并为 2x2,则 f
减半,即使用 1357。
我不知道静态图片是如何制作的。完整的传感器具有 4:3 纵横比。假设 1920x1080 的帧完全安装在那里(接触边,裁剪顶部和底部),比例因子为 0.585 和 f = 1589,FoV 为 62.28° x 37.54°,对角线为 69.46°。
焦距也可以根据分辨率和视野来计算,但像素间距和镜头焦距是标称设计参数,视野来自于此(以及镜头畸变等缺陷)。
然后我们有 cx = (width-1) / 2 = 959.5
和 cy = (height-1) / 2 = 539.5
。
现在你有了矩阵的值。
通过计算K p
将一个3D点p
投影到图像上,这是一个矩阵乘法。可以做相反的事情。您可以将图片上的一个点重新投影回世界。它现在是一个向量,一条射线,一个方向。
如果你有(x,y)
作为图片坐标,计算:
v_x = (x - cx) / f
# v_y = (y - cy) / f
最后是水平角:
alpha = atan(v_x) # radians, or
alpha = atan(v_x) * 180/pi # degrees
(与光轴的对角线角度为atan(hypot(v_x, v_y))
)
对于左边缘 (x=0) 上的点,这意味着向左转 19.5 度。
所有这些都假设图片没有被镜头扭曲。对于小角度,这无关紧要。一些相机具有几乎不会变形的特殊镜头。某些相机,尤其是运动相机,有意采用近鱼眼镜头(意味着严重失真)。
如果你需要处理镜头畸变,那就是另一个话题了。有一些常见的镜头畸变模型可以使用少至 4 个参数。 MATLAB和OpenCV都自带标定方法