美文网首页大数据,机器学习,人工智能
使用双目相机进行三维重建 第二部分:姿态估计

使用双目相机进行三维重建 第二部分:姿态估计

作者: AI研习社 | 来源:发表于2019-05-08 10:43 被阅读3次
    image

    本文为 AI 研习社编译的技术博客,原标题 :

    3D Reconstruction with Stereo Images - Part 2: Pose Estimation

    作者 |* Keenan James*

    翻译 | 酱番梨、Hasekiel_learn

    校对 | 酱番梨 审核 | 酱番梨 整理 | 立鱼王

    原文链接:

    https://medium.com/@dc.aihub/3d-reconstruction-with-stereo-images-part-2-pose-estimation-1bcfbba61b26

    image

    引言:在上一篇文章中我们讲了相机的特征以及这些信息与我们做3D重建有什么关系。通过相机校正,我们确认了一些我们程序要用的相机属性数据,即相机矩阵(camera matrix)和扭曲系数(distortion coefficients)。利用这些信息,我们可以从拍摄的模式图像(patterned image)中计算出现实空间中物体的位置。在我们的例子中,我们会用象棋棋盘图像,并通过3D立方的绘制方向来可视化平面物体的相对位置。

    image

    开始

    这个练习的目的是给我们的图像画上x,y,z轴,放在棋盘的底部角落。按惯例,3D空间中X坐标轴用蓝色、Y用绿色、Z用红色。这个例子里,我们让Z轴垂直于物体(即Z轴是从棋盘2D平面指向相机的)。

    我们首先取出之前练习保存的相机矩阵和扭曲系数。

    import cv2
    import numpy as np
    import glob
    
    # Load previously saved data
    with np.load('B.npz') as X:
        mtx, dist, _, _ = [X[i] for i in ('mtx','dist','rvecs','tvecs')]
    

    接下来要写一个函数来绘制3D坐标轴。这个函数的输入是:棋盘图像、棋盘四个角(坐标)、三个分别代表三坐标轴方向终点的点(坐标)。

    棋盘的角落可以用之前的cv2.findChessboardCorner()函数,返回的是一个含有4个角位置的数组。这里我们只需要注意底部左手角落,它是数组的第一个元素,如下图corner[0]。得到该坐标后,我们就可以利用之前定义的3个终点展开我们的坐标轴了。

    def draw(img, corners, imgpts):
        corner = tuple(corners[0].ravel())
        img = cv2.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 5)
        img = cv2.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 5)
        img = cv2.line(img, corner, tuple(imgpts[2].ravel()), (0,0,255), 5)
        return img
    

    下一步我们要在3D空间中定义一些点帮助我们绘制坐标轴。回忆一下在上一个练习中,我们令棋盘一个方块的边长等于一个单位。在这个例子中,我们在三个方向上画了长3个单位的坐标轴。Z轴需要标负值,因为这样可以保证轴线面朝相机。

    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
    objp = np.zeros((6*7,3), np.float32)
    objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)
    
    axis = np.float32([[3,0,0], [0,3,0], [0,0,-3]]).reshape(-1,3)
    

    现在我们可以用上我们的绘制函数了。第一步先读取图片,寻找7x6的格子(译者注:指棋盘)。找到之后,我们可以利用cv2.solvePnPRansac()计算其旋转角和平移距离(rotation and translation)。现在把3D空间的轴点(axis points)投影到2D图像平面去。识别出坐标轴后,就用绘制函数可视化其方向。

    for fname in glob.glob('left*.jpg'):
        img = cv2.imread(fname)
        gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
        ret, corners = cv2.findChessboardCorners(gray, (7,6),None)
    
        if ret == True:
            corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
    
            # Find the rotation and translation vectors.
            rvecs, tvecs, inliers = cv2.solvePnPRansac(objp, corners2, mtx, dist)
    
            # project 3D points to image plane
            imgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)
    
            img = draw(img,corners2,imgpts)
            cv2.imshow('img',img)
            k = cv2.waitKey(0) & 0xff
            if k == 's':
                cv2.imwrite(fname[:6]+'.png', img)
    
    cv2.destroyAllWindows()
    

    如下图,我们看到四张不同棋盘图像被我们程序处理后的结果。

    image

    渲染一个立方体

    为了描画一个立方体,我们可以按照下文所述修改绘图函数。首先绘制一个3 x 3的正方形,朝向左下角并与我们的棋盘平行。然后我们将添加从该正方形延伸的线,以在面向相机的方向上完成立方体。

    def draw(img, corners, imgpts):
        imgpts = np.int32(imgpts).reshape(-1,2)
    
        # draw ground floor in green
        img = cv2.drawContours(img, [imgpts[:4]],-1,(0,255,0),-3)
    
        # draw pillars in blue color
        for i,j in zip(range(4),range(4,8)):
            img = cv2.line(img, tuple(imgpts[i]), tuple(imgpts[j]),(255),3)
    
        # draw top layer in red color
        img = cv2.drawContours(img, [imgpts[4:]],-1,(0,0,255),3)
    
        return img
    

    我们必须修改轴点,并以此来囊括立方体的每个角。

    axis = np.float32([[0,0,0], [0,3,0], [3,3,0], [3,0,0],
                       [0,0,-3],[0,3,-3],[3,3,-3],[3,0,-3] ])
    

    下面的两幅图片已将结果显示出来:

    image

    结论

    在上述练习之后,我们可以考虑增强现实(AR)的应用。在这里,我们成功地将3D对象包含在真实世界图像中,该图像与所描绘的对象相互作用,允许真实世界和虚拟世界之间的动态链接。

    image

    作者:Keenan James,导师:Amit Maraj教授

    想要继续查看该篇文章相关链接和参考文献?

    点击使用双目相机进行三维重建 第二部分:姿态估计即可访问:

    【译者招募】伯克利《深度无监督学习》

    很高兴我们又拿到了2019 春季伯克利 深度无监督学习这门课程的授权,现在开始招募译者了噢!
    如果你对此感兴趣的话,可以点击链接加入课程小组:
    https://ai.yanxishe.com/page/groupDetail/70

    同时你想报名参与课程翻译的话,请私聊字幕君,字幕君会将你拉入译者群,准备开始翻译噢!

    相关文章

      网友评论

        本文标题:使用双目相机进行三维重建 第二部分:姿态估计

        本文链接:https://www.haomeiwen.com/subject/iqapoqtx.html