双目视觉(1) -- 坐标系变换

Stereo vision summary

相机坐标系与像素坐标系之间的关系

  • 通过内参矩阵
    z ( u v 1 ) = K ( X Y Z ) z \begin{pmatrix} u\\ v\\ 1 \end{pmatrix} = K \begin{pmatrix} X\\ Y\\ Z\\ \end{pmatrix} zuv1=KXYZ
    其中 K K K为内参矩阵, ( X , Y , Z ) T (X, Y, Z)^T (X,Y,Z)T为相机坐标系下的点, ( u , v , 1 ) T (u,v,1)^T (u,v,1)T为像素坐标系下的点。 z z z为深度。
    反过来:
    Z = z Z = z Z=z
    Y = ( v − c y ) Z f y Y = \frac{(v-c_y)Z}{f_y} Y=fy(vcy)Z
    X = ( u − c x ) Z f x X = \frac{(u-c_x)Z}{f_x} X=fx(ucx)Z
    如果是双目,深度可以由以下公式求出:
    z = f b d z = \frac{fb}{d} z=dfb

  • 像素坐标系到相机坐标系的转换也可以通过Q矩阵得到

    • Q矩阵的具体形式
      Q = [ 1 0 0 − c x 0 1 0 − c y 0 0 0 f 0 0 − 1 T x c x − c x ′ T x ] Q= \begin{bmatrix} 1 & 0 & 0 & -c_x \\ 0 & 1 & 0 & -c_y \\ 0 & 0 & 0 & f \\ 0 & 0 & \frac{-1}{T_x} & \frac{c_x-c_{x}^{'}}{T_x} \end{bmatrix} Q=10000100000Tx1cxcyfTxcxcx
  • 由Q矩阵转换到相机坐标系
    Q [ u v d 1 ] = [ X Y Z W ] Q \begin{bmatrix} u\\ v \\ d \\ 1 \end{bmatrix} = \begin{bmatrix} X\\ Y\\ Z\\ W \end{bmatrix} Quvd1=XYZW
    最终将到的向量 ( X , Y , Z , W ) T (X, Y, Z, W)^T (X,Y,Z,W)T W W W归一化就得到三维的点。
    opecv中可以直接调用reprojectImageTo3D函数:

void reprojectImageTo3D(InputArray disparity,
                        OutputArray _3dImage,
                        InputArray Q, 
                        bool handleMissingValues=false, 
                        int ddepth=-1 ) 

stereoRectify

  • R1 – Output 3x3 rectification transform (rotation matrix) for the first camera.
  • R2 – Output 3x3 rectification transform (rotation matrix) for the second camera.
  • P1 – Output 3x4 projection matrix in the new (rectified) coordinate systems for the first camera.
  • P2 – Output 3x4 projection matrix in the new (rectified) coordinate systems for the second camera.
  • Alpha - Free scaling parameter, -1 or absent means the default scaling. alpha = 0 means that the rectified image are zoomed and shifted.
void stereoRectify(InputArray cameraMatrix1,
                   InputArray distCoeffs1,
                   InputArray cameraMatrix2,
                   InputArray distCoeffs2,
                   Size imageSize, 
                   InputArray R, 
                   InputArray T,
                   OutputArray R1,
                   OutputArray R2,
                   OutputArray P1,
                   OutputArray P2, 
                   OutputArray Q,
                   int flags=CALIB_ZERO_DISPARITY,
                   double alpha=-1,
                   Size newImageSize=Size(),
                   Rect* validPixROI1=0, 
                   Rect* validPixROI2=0 
                  )

解释一下,对于双目相机,由左相机到右相机有一个旋转 R R R和一个平移 t t t,OpenCv标定后的坐相机坐标系中,左相机和右相机各自旋转一半使得内参一致。这样在rectify的时候就可以使用同一套内参参数。
Rectify生成remap矩阵的过程如下(针对左摄像头):

  1. ( u , v ) (u, v) (u,v)是rectify后像素坐标系中的点
  2. ( x , y , z ) T = R 1. i n v ( ) ∗ P 1. c o l R a n g e ( 0 , 3 ) . i n v ( ) ∗ ( u , v , 1 ) T (x, y, z)^T = R1.inv() * P1.colRange(0,3).inv() * (u, v, 1)^T (x,y,z)T=R1.inv()P1.colRange(0,3).inv()(u,v,1)T 将像素坐标系中的点重映射到世界坐标系中,现由旋转矩阵的逆转到以前的位置。
  3. 由distCoeffs1矩阵对 ( x , y , z ) T (x, y, z)^T (x,y,z)T进行undistortion得到 ( x ′ , y ′ , z ′ ) T (x', y', z')^T (x,y,z)T
  4. 由cameraMatrix1将 ( x ′ , y ′ , z ′ ) T (x', y', z')^T (x,y,z)T映射到像素坐标系中,得到 ( u ′ , v ′ ) (u', v') (u,v)
  5. 所以 ( u , v ) (u,v) (u,v)对应 ( u ′ , v ′ ) (u',v') (u,v), 这里得到的 u ′ u' u v ′ v' v都是float, 并非整像素点,rectify后的值可以用bilinear插值得到。
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值