使用OpenCV和Python进行相机姿态估计

时间:2017-12-05 16:31:36

标签: python opencv computer-vision opticalflow

我尝试使用OpenCV和python来跟踪视频流中的相机姿势。我有一个代码示例,它确定两个图像之间的姿势作为测试环境。

这里的总体流程如下:

  1. 读入图片并转换为灰色/调整大小。

  2. 从两张图片中使用cv2 goodfeaturestotrack提取功能。

  3. 使用cv2 calcOpticalFlowPyrLK查找匹配点。
  4. 对于设置为0的所有点,将p1点(起始图像)转换为(x,y,z)为z。
  5. 解析cv2 PnPRansac以获取旋转和平移向量。
  6. 将角度从弧度转换为度数。
  7.     def function(mtx,dist):
    
                #feature dictionary
                feature_params = dict( maxCorners = 1000,
                                   qualityLevel = 0.3,
                                   minDistance = 7,
                                   blockSize = 7 )
                lk_params = dict( winSize  = (15,15),
                              maxLevel = 2,
                              criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
    
    
                #image 1
                image_1=cv2.imread("/Users/user/Desktop/Test_images/Test_image.jpg")
                image_1=cv2.resize(image_1,(640,480))
                gray_1=cv2.cvtColor(image_1,cv2.COLOR_BGR2GRAY)
                p1=cv2.goodFeaturesToTrack(gray, mask = None, **feature_params)
    
                #image read in
                image_2=cv2.imread("/Users/user/Desktop/Test_images/Test_image.jpg")
                image_2=cv2.resize(image_2,(640,480))
                gray_2 = cv2.cvtColor(image_2,cv2.COLOR_BGR2GRAY)
                p2, st, err = cv2.calcOpticalFlowPyrLK(gray_1, gray_2, p1, None, **lk_params)
    
                #convert the old points to 3d
                zeros=np.zeros([len(p1),1],dtype=np.float)
                old_3d=np.dstack((p1, zeros))
    
                #get rotational and translation vector
                blank,rvecs, tvecs, inliers = cv2.solvePnPRansac(old_3d, p2, mtx, dist)
    
                rad=180/math.pi
    
                roll=rvecs[0]*rad
                pitch=rvecs[1]*rad
                yaw=rvecs[2]*rad
    
                print(roll)
                print(pitch)
                print(yaw)
                print(tvecs)
    
            function(mtx,dist)
    
    
    
       rvec (roll, pitch and yaw)
        [ 0.35305807]
        [ 2.95965708]
        [ 0.10954427]
    
        tvec (x,y,x ???)
        [[ -668.42397254]
         [ -387.32180857]
         [ 1180.94652875]]
    

    鉴于我使用完全相同的图像来运行此样本计算,我期望旋转和平移向量非常接近于零。但是它们非常高,请看下面的示例输出。另外,对于具有已知平移的不同图像,矢量是非常错误的。

    手头的问题是我的方法声音?我接近过这个问题吗?我是否正确匹配了这些点?这种噪音水平是正常的还是我能做些什么呢?

1 个答案:

答案 0 :(得分:0)

如果您不了解3D结构,即您已匹配的点的3D坐标,则无法使用PnP。

如果您知道相机内在函数,则可以估计单应性(对于平面场景)或基本矩阵(对于一般场景),然后将其分解以获得旋转和按比例缩放。然后,您可以进行束调整以优化所找到的姿势。

如果这是一次性项目,使用像Blender这样的图形环境可能会更快,而不是编写自己的解决方案。查看matchmove教程herehere