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

2019 年 5 月 7 日 AI研习社

本文为 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

注:本文的相关链接请访问文末【阅读原文】

查看第一部分,请点击:使用双目相机进行三维重建 第一部分:相机校准

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


  开始

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

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

import cv2import numpy as npimport glob
# Load previously saved datawith 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()

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

  渲染一个立方体

为了描画一个立方体,我们可以按照下文所述修改绘图函数。首先绘制一个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] ])

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


  结论

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

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

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

点击底部【阅读原文】即可访问:

https://ai.yanxishe.com/page/TextTranslation/1420

相关文章:

使用双目相机进行三维重建 第一部分:相机校准


AI求职百题斩 · 每日一题


每天进步一点点,长按扫码参与每日一题!



AI 研习社 设置星标,快速查看最新内容


点击
阅读原文
,查看更多内容
登录查看更多
12

相关内容

在计算机视觉中, 三维重建是指根据单视图或者多视图的图像重建三维信息的过程. 由于单视频的信息不完全,因此三维重建需要利用经验知识. 而多视图的三维重建(类似人的双目定位)相对比较容易, 其方法是先对摄像机进行标定, 即计算出摄像机的图象坐标系与世界坐标系的关系.然后利用多个二维图象中的信息重建出三维信息。 物体三维重建是计算机辅助几何设计(CAGD)、计算机图形学(CG)、计算机动画、计算机视觉、医学图像处理、科学计算和虚拟现实、数字媒体创作等领域的共性科学问题和核心技术。在计算机内生成物体三维表示主要有两类方法。一类是使用几何建模软件通过人机交互生成人为控制下的物体三维几何模型,另一类是通过一定的手段获取真实物体的几何形状。前者实现技术已经十分成熟,现有若干软件支持,比如:3DMAX、Maya、AutoCAD、UG等等,它们一般使用具有数学表达式的曲线曲面表示几何形状。后者一般称为三维重建过程,三维重建是指利用二维投影恢复物体三维信息(形状等)的数学过程和计算机技术,包括数据获取、预处理、点云拼接和特征分析等步骤。
CVPR 2020 最佳论文与最佳学生论文!
专知会员服务
35+阅读 · 2020年6月17日
【开放书】SLAM 中的几何与学习方法,62页pdf
专知会员服务
109+阅读 · 2020年6月5日
 【SIGGRAPH 2020】人像阴影处理,Portrait Shadow Manipulation
专知会员服务
28+阅读 · 2020年5月19日
MIT新书《强化学习与最优控制》
专知会员服务
275+阅读 · 2019年10月9日
已删除
将门创投
5+阅读 · 2019年10月29日
【泡泡读者来稿】VINS 论文推导及代码解析(三)
泡泡机器人SLAM
30+阅读 · 2019年3月16日
【泡泡一分钟】视觉(-惯性)里程计定量轨迹评估教程
泡泡机器人SLAM
35+阅读 · 2019年1月27日
强化学习的未来——第一部分
AI研习社
9+阅读 · 2019年1月2日
重磅!头部姿态估计「原理详解 + 实战代码」来啦!
计算机视觉life
56+阅读 · 2018年11月29日
Learning Implicit Fields for Generative Shape Modeling
Arxiv
10+阅读 · 2018年12月6日
Viewpoint Estimation-Insights & Model
Arxiv
3+阅读 · 2018年7月3日
VIP会员
相关资讯
已删除
将门创投
5+阅读 · 2019年10月29日
【泡泡读者来稿】VINS 论文推导及代码解析(三)
泡泡机器人SLAM
30+阅读 · 2019年3月16日
【泡泡一分钟】视觉(-惯性)里程计定量轨迹评估教程
泡泡机器人SLAM
35+阅读 · 2019年1月27日
强化学习的未来——第一部分
AI研习社
9+阅读 · 2019年1月2日
重磅!头部姿态估计「原理详解 + 实战代码」来啦!
计算机视觉life
56+阅读 · 2018年11月29日
Top
微信扫码咨询专知VIP会员