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

标签 python opencv computer-vision opticalflow

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

这里的整体流程是这样的:

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

  2. 使用 cv2 goodfeaturestotrack 从两幅图像中提取特征。

  3. 使用 cv2 calcOpticalFlowPyrLK 寻找匹配点。
  4. 将所有点的 z 都设置为 0,将 p1 点(起始图像)转换为 (x,y,z)。
  5. 解析cv2 PnPRansac得到旋转和平移向量。
  6. 将角度从弧度转换为度数。
    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]]

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

手头的问题是我的方法合理吗?我是否正确地解决了这个问题?我是否正确匹配了这些点?这种噪音水平是正常的还是我可以做些什么?

最佳答案

如果您不知道3D结构,即您匹配的点的3D坐标,您将无法使用PnP。

但是,如果您了解相机内在原理,则可以估计单应性(对于平面场景)或基本矩阵(对于一般场景),然后将其分解以获得按比例旋转和平移。然后,您可以进行捆绑调整以优化由此找到的姿势。

如果这是一次性项目,使用 Blender 等图形环境可能比编写自己的解决方案更快。请参阅 matchmove 教程 herehere

关于python - 使用 OpenCV 和 Python 进行相机姿态估计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47658365/

相关文章:

python 字典设置最小大小

java - 如何使用Runtime在java中调用python程序

opencv - 如何从 OpenCV 中的欧几里德变换中的 2x3 矩阵中找到枢轴点

opencv - 如何实时减去非平稳背景

Python 拓扑排序使用列表指示边

python - fillna() 使用第三个多个 pandas 列

c++ - 如何使用openCV的SphericalWarper?

video - 如何使用 ffmpeg 从视频文件中提取高质量的 JPEG 图像?

c++ - 过时 - OpenCV 的错误模式

opencv - 使用用户定义的目标跟踪视频序列