使用opencv C ++,SolvePnP函数估计相机姿态

时间:2017-07-28 14:55:55

标签: computer-vision opencv

我正在尝试测量相机的姿势,我已完成以下操作。

  1. Mark world 3-D(假设z = 0,因为它是平的)指向平面上正方形的角上并假设一个世界坐标系。(以厘米为单位)
  2. 将方块的左上角作为我的原点,并按以下顺序(x,y)或(col,row)给出世界点: (0,0),(12.8,0),(12.8,12.8),(0,12.8) - in cms

    1. 检测图像中的这些点。(以像素为单位) 图像点和世界点的顺序相同。

    2. 我已经为内在矩阵失真系数校准了相机。

    3. 我使用 SolvePnP 函数获取rvec和tvec。

    4. 我使用 Rodrigues 函数来获取旋转矩阵。

    5. 要检查rvec和tvec是否正确,我使用 ProjectPoints 将三维点(z = 0)投影到图像平面中,并在图像上正确获取点X轴上的误差为3像素。

    6. 现在我继续使用公式计算我在世界框架中的相机位置:

    7. cam_worl_pos = - inverse(R)* tvec 。 (这个公式我已在许多博客中验证过,这也很有意义)

      1. 但我的 cam_worl_pos cms中的x,y和z似乎不正确。
      2. 我怀疑的是,如果我能够使用rvec和tvec将3-D世界点投影回图像平面(X轴上 3像素误差,Y轴几乎没有误差,希望它是不是太糟糕),那么为什么我没有在世界框架中获得相机位置。

        另外,我对SolvPnP rvec和tvec解决方案有疑问,它们可能是多种解决方案之一,但不是我想要的解决方案之一。

        如何从SolvPnp获得正确的rvec和tvec或任何其他建议来获得rvec和tvec也会有所帮助。

        编辑

        图片尺寸 - 720(行)* 1280(col)

        相机参数

        cameraMatrix_Front=[908.65   0     642.88
                             0     909.28   364.95
                             0        0        1]
        
        distCoeffs_Front=[-0.4589, 0.09462, -1.46*10^-3, 1.23*10^-3]
        

        OpenCV C ++代码

        vector<Point3f> front_object_pts;
        Mat rvec_front;
        Mat tvec_front;
        Mat rotation_front;
        Mat world_position_front_cam;
        
        
        //Fill front object points(x-y-z order in cms)
        //It is square of side 12.8cms on Z=0 plane
        front_object_pts.push_back(Point3f(0, 0, 0));
        front_object_pts.push_back(Point3f(12.8, 0, 0));
        front_object_pts.push_back(Point3f(12.8,12.8,0));
        front_object_pts.push_back(Point3f(0, 12.8, 0));
        
        
        //Corresponding Image points detected in the same order as object points
        front_image_pts.push_back(points_front[0]);
        front_image_pts.push_back(points_front[1]);
        front_image_pts.push_back(points_front[2]);
        front_image_pts.push_back(points_front[3]);
        
        //Detected points in image matching the 3-D points in the same order
        //(467,368)
        //(512,369)
        //(456,417)
        //(391,416)
        
        //Get rvec and tvec using Solve PnP
        solvePnP(front_object_pts, front_image_pts, cameraMatrix_Front,
                 Mat(4,1,CV_64FC1,Scalar(0)), rvec_front, tvec_front, false, CV_ITERATIVE);
        
        //Output of SolvePnP
        //tvec=[-26.951,0.6041,134.72]  (3 x 1 matrix)
        //rvec=[-1.0053,0.6691,0.3752]  (3 x 1 matrix)
        
        
        //Check rvec and tvec is correct or not by projecting the 3-D object points to image
        vector<Point2f>check_front_image_pts
        projectPoints(front_object_pts, rvec_front, tvec_front, 
                     cameraMatrix_Front, distCoeffs_Front, check_front_image_pts);
        
        
        //Here to note that I have made **distCoefficents**, 
        //a 0 vector since my   image points are detected after radial distortion is removed
        
        //Get rotation matrix
        Rodrigues(rvec_front, rotation_front);
        
        //Get rotation matrix inverse
        Mat rotation_inverse;
        transpose(rotation_front, rotation_inverse);
        
        //Get camera position in world cordinates
        world_position_front_cam = -rotation_inverse * tvec_front;
        
          

        //摄像机的实际位置(手动测量)

             

        X =47厘米

             

        Y =18厘米

             

        Z =25厘米

             

        //获得位置

             

        X =110厘米

             

        Y =71厘米

             

        Z = -40cm

0 个答案:

没有答案
相关问题