【问题标题】:Why is cv2.projectPoints not behaving as I expect?为什么 cv2.projectPoints 的行为不符合我的预期?
【发布时间】:2015-01-27 21:32:25
【问题描述】:

我有一个 3D 世界,我正在尝试使用 cv2.projectPoints 将其映射到 2D 视图,但它并没有像我预期的那样运行。我对 opencv、numpy 和矩阵运算的掌握很弱,所以我一定是在某个地方做出了错误的假设。这段代码:

src = np.ones((6, 3))
src[:,1] = 2
src[:,2] = range(6) # source points
rvec = np.array([0,0,0], np.float) # rotation vector
tvec = np.array([0,0,0], np.float) # translation vector
fx = fy = 1.0
cx = cy = 0.0
cameraMatrix = np.array([[fx,0,cx],[0,fy,cy],[0,0,1]])
result = cv2.projectPoints(src, rvec, tvec, cameraMatrix, None)
for n in range(len(src)):
    print src[n], '==>', result[0][n]

产生这个输出:

[ 1.  2.  0.] ==> [[ 1.  2.]]
[ 1.  2.  1.] ==> [[ 1.  2.]]
[ 1.  2.  2.] ==> [[ 0.5  1. ]]
[ 1.  2.  3.] ==> [[ 0.33333333  0.66666667]]
[ 1.  2.  4.] ==> [[ 0.25  0.5 ]]
[ 1.  2.  5.] ==> [[ 0.2  0.4]]

x 值和 y 值除以 z 值?!我认为由于我没有对 rvec 和 tvec 应用任何转换,因此输出应该与 src 的 [x,y] 值匹配。

【问题讨论】:

  • 这是正确的行为。随着 src 点远离相机针孔,它们被投影到更靠近原点的图像点。更远的物体在图像中看起来更小。换句话说,对象大小与距离成反比。来自 src 点 (x,y,z) 的图像点 (x',y') 的方程写在此 url openCV doc 的文档中

标签: python opencv numpy


【解决方案1】:

对于无操作,旋转矩阵应该是一个恒等式

1 0 0
0 1 0
0 0 1

编辑: 自己写一个非常简单的函数。

foreach input 3dpoint xyz
  3dpoint tmp = cameraintrinsic(3x3) * rotationvect(1x3) * xyz(3x1) + cameraintrinsic(3x3)*translation(3,1)
  2dpoint screen = tmp.x/tmp.z, tmp.y / tmp.z

/tmp.z 是因为结果以齐次坐标返回 = 本质上是带有缩放因子的二维坐标。

【讨论】:

  • 试过了,结果相同 :-( 我使用的是Rodrigues 的输出,它为输入 np.identity(3) 提供 [0,0,0]
【解决方案2】:

您的代码是正确的,但正如您所怀疑的那样,您的解释是错误的。函数 OpenCV::projectPoints() 不仅执行旋转和平移,还执行反向 z 距离缩放。

请注意,几何假设是相机位于 z=0 并沿 z 轴指向。考虑在距相机一定距离 Z 处,视场(即图像的宽度)为 Fx,Fy。例如,您可以以米为单位测量 Z 和 F,但可以使用任何距离单位。您还知道图像中的像素数沿 X 方向为 ncols,沿 Y 方向为 nrows。接下来考虑要投影的空间 (x,y,z) 中的 3D 点,其中 z 不为零。图片坐标如下:

u= x * ncols/Fx * Z/z
v= y * nrows/Fy * Z/z

从这里你可以看到fx= ncols/Fx*Z and fx=nrows/Fy*Z

【讨论】:

    猜你喜欢
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    相关资源
    最近更新 更多