OpenCV中的摄像机位移估计 - 不正确的姿势输出

时间:2014-08-06 01:51:57

标签: python opencv camera position translation

我目前正在使用一个朝下的相机拍摄,棋盘图案位于地面上的固定位置。我正在使用带有OpenCV的python来跟踪摄像机的位移,并使用输出根据x,y,z方向绘制位移。最后,我想将摄像机安装在悬停式多旋翼无人机的底部,以便校准GPS精度。

我使用的基本方法是:

  1. 定义对象点
  2. 打开视频
  3. 基于已保存的相机矩阵的Undistort帧(已执行相机校准)
  4. 查找棋盘角落
  5. 如果发现角落,请修改角落
  6. 查找旋转和平移向量(cv2.pnpransac)
  7. 项目3D指向图像平面(cv2.projectpoints)
  8. 按照this answer:

    将旋转矢量转换为旋转矩阵
    np_rodrigues = np.asarray(rvecs_new[:,:],np.float64)
    rmatrix = cv2.Rodrigues(np_rodrigues)[0]
    
  9. 根据this answer:

    计算相机姿势
    cam_pos = -np.matrix(rmatrix).T * np.matrix(tvecs_new)
    
  10. 存储值

    camx.append(cam_pos.item(0))
    camy.append(cam_pos.item(1))
    camz.append(cam_pos.item(2))
    
  11. 然而当我使用应该是恒定高度的直线的视频运行此代码时,绘制的x,y图表给出了弯曲的x,y图,并且z不是常数,如图所示通过x,z图:http://imgur.com/QIY3wgQ,pDM5T0x,HEDJtAt#1

    有什么理由不应该在图表上给出一条直线?步骤9中的相机姿势计算可能出错?


    完整的代码如下:

        # Criteria, defining object points
        import cv2
        import numpy as np
        import time
        import matplotlib.pyplot as plt
    
        #IMPORTANT: Enter chess board dimensions 
        chw = 9
        chh = 6
    
        #Defining draw functions for lines
        def draw(img, corners, imgpts):
            corner = tuple(corners[0].ravel())
            cv2.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 5)
            cv2.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 5)
            cv2.line(img, corner, tuple(imgpts[2].ravel()), (0,0,255), 5)
            return img
    
        # Load previously saved data
        with np.load('camera_calib.npz') as X:
            mtx, dist, _, _, _ = [X[i] for i in ('mtx','dist','rvecs','tvecs','imgpts')]
    
        # Criteria, defining object points
        criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
        objp = np.zeros((chh*chw,3), np.float32)
        objp[:,:2] = np.mgrid[0:chw,0:chh].T.reshape(-1,2)
    
        # Setting axis
        axis = np.float32([[9,0,0], [0,6,0], [0,0,-10]]).reshape(-1,3)
    
        cap = cv2.VideoCapture('Calibration\\video_chess2.MP4')
        count = 0
        fcount = 0
        while(cap.isOpened()):
            ret1, img = cap.read()
            if ret1 == False or count==lim:
                print('Video analysis complete.')
                break
            if count > 0:
                h,  w = img.shape[:2]
                newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))
                # Undistorting
                img2 = cv2.undistort(img, mtx, dist, None, newcameramtx)
    
                gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
                ret2, corners = cv2.findChessboardCorners(gray, (chw,chh),None)
                if ret2 == True:
                    fcount = fcount+1
                    # Refining corners
                    cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
    
                    # Find the rotation and translation vectors
                    rvecs_new, tvecs_new, inliers = cv2.solvePnPRansac(objp, corners, mtx, dist)
    
                    # Project 3D points to image plane
                    imgpts, jac = cv2.projectPoints(axis, rvecs_new, tvecs_new, mtx, dist)
                    draw(img2,corners,imgpts)
                    cv2.imshow('img',img2)
                    cv2.waitKey(1)
    
    
                    # Converting rotation vector to rotation matrix
                    np_rodrigues = np.asarray(rvecs_new[:,:],np.float64)
                    rmatrix = cv2.Rodrigues(np_rodrigues)[0]
    
                    # Pose (According to https://stackoverflow.com/questions/16265714/camera-pose-estimation-opencv-pnp)
                    cam_pos = -np.matrix(rmatrix).T * np.matrix(tvecs_new)
    
                    camx.append(cam_pos.item(0))
                    camy.append(cam_pos.item(1))
                    camz.append(cam_pos.item(2))
    
                else:
                    print 'Board not found'
    
            count += 1
            print count
        cv2.destroyAllWindows()
        plt.plot(camx,camy)
        plt.show()
    

0 个答案:

没有答案