我目前正在开展一个项目,该项目将运动检测与玩具枪在(x,y)轴上的运动相结合。我已设法获取对象位置的坐标(使用OpenCV正确的命令)并将它们发送到Arduino以移动枪,但这不能正常工作。我正在使用的代码是:
session_start()
我根据水平和垂直摄像机角度(45o V,58o H)计算了每个伺服系统的垂直和水平移动的最小和最大程度。在这种情况下,水平伺服的(x)最小值是66度,最大值是112度。此外,垂直伺服的最小值为60度,最大值为120度。
此时我想询问是否有一个公式将对象的坐标转换为基于摄像机角度的度数。上面的代码不会将枪转到正确的位置。有人可以帮帮我吗?
我正在使用华硕Xtion Pro Live相机(45o V,58o H,70o D)和USB相机。
答案 0 :(得分:0)
您可以使用一些简单的三角函数来解决这个问题。
首先,让我们假设已经消除了由光学引起的任何失真,并且图像中心与光学中心相对应。我们可以独立处理每个平面(水平和垂直)以简化问题。
我们可以将图像视为透视投影。从上面看(即仅考虑水平面),它看起来像这样:
图像的宽度是已知的(根据您的代码为480像素),以及角度α(您说的水平FOV的一半是58°)。
因此:
a = w / 2 = 480/2 = 240像素
α= 58°/ 2 = 29°
基于三角学,我们有以下等式:
tan(α)= a / d
tan(β)= b / d
相当于
d = a / tan(α)
d = b / tan(β)
以d
为例,我们可以写
a / tan(α)= b / tan(β)
相当于
a * tan(β)= b * tan(α)
给我们
tan(β)= b * tan(α)/ a
最后
β= arctan(b * tan(α)/ a)
现在我们可以用已知的常数代替这个等式:
β= arctan(b * tan(29°)/ 240)
由于角度α是常数,因此它的切线也是如此。将其表达为
可能更方便K = tan(29°)/ 240
β= arctan(b * K)
现在,您可能不想在AVR上实际计算此值。更灵活的方式可能是使用查找表(每个轴一个),它将像素位置映射到角度(甚至更好的伺服目标值)。
您可以将它作为程序存储器中的静态数组,或者如果您有足够的空间,将其保存在SRAM中,并允许通过串行端口上传新的LUT。