作者 | aipiano @CSDN

编辑 | 3D视觉开发者社区

导读

Kinect作为微软推出的XBOX360体感周边外设,具有获取深度信息的能力。但由于Kinect自身RGB摄像头分辨率有限,其清晰度也略低,对于较高要求的开发者来说不够适用。因此,很多开发者都会使用第三方摄像头代替Kinect摄像头,但是二者之间如何配准一直是个问题。本篇就“如何将Kinect的深度图与第三方摄像头的RGB图像对准”的问题进行了详细地讲解与手把手地教学,简单易懂,十分推荐阅读。

自从有了Kinect,根据深度图提取前景就非常方便了。因此出现了很多虚拟现实、视频融合等应用。但是,Kinect自身的RGB摄像头分辨率有限,清晰度也不及一些专业摄像头,因此有了用第三方摄像头代替Kinect摄像头的想法。现在的问题是,如何将Kinect的深度图与第三方摄像头的RGB图像对准?

当使用Kinect的RGB时,有方便的MapColorCoordinatesToDepth和MapDepthCoordinatesToColor方法可以使用,这些函数将深度图和RGB对准到一起,从而可根据深度图准确地提取出RGB中的前景。但打算使用第三方摄像头时,这些函数都没有用了,它们不可能知道我们所用摄像头的参数以及空间位置,因此只能靠自己标定的方法解决这一问题。

在标定之前,先要固定好Kinect和摄像头的位置,让深度摄像头和RGB摄像头的像平面尽量平行,距离也不要隔得太远,就像下面这样:

一、RGB摄像头的标定

RGB摄像头的标定想必大家都很熟悉,最常用的就是棋盘法。用待标定的摄像头拍摄多幅不同视角下的棋盘图片,将这些图片扔给OpenCV或Matlab,从而计算出该摄像头的内参以及对应于每一幅图像的外参。这里就写写我在标定过程中的一些感受和经验吧。

1、标定所用的棋盘要尽量大,至少要有A3纸的大小;

2、棋盘平面与摄像头像平面之间的夹角不要太大,控制在45度以下;

3、棋盘的姿势与位置尽可能多样化,但相互平行的棋盘对结果没有贡献;

4、用于标定的图片要多于10张;

5、注意设置好摄像头的分辨率,长宽比最好和深度图的相同,比如1280x960(4:3)。

以下是一些用于标定的样图:

二、深度摄像头的标定

深度摄像头看起来和RGB摄像头差别很大,实际上有很多相似之处。就Kinect而言,其通过一个红外散斑发射器发射红外光束,光束碰到障碍物后反射回深度摄像头,然后通过返回散斑之间的几何关系计算距离。其实,Kinect的深度摄像头就是一个装了滤波片的普通摄像头,只对红外光成像的摄像头(可以这么认为)。

因此要对其标定,只需用红外光源照射物体即可,LED红外光源在淘宝上就20元一个。还有一点必须注意,在拍摄红外照片时,要用黑胶带(或其他东西)将Kinect的红外发射器完全挡住,否则其发出的散斑会在红外照片中产生很多亮点,不利于棋盘角点的检测。以下是对应于上面RGB图像的红外图:

三、计算内参

得到以上图片之后,就可以分别对RGB摄像头和深度摄像头计算内参了。可以使用OpenCV,自己写一小段程序,然后把图片扔进去。也可以使用著名的Matlab Camera Calibration Toolbox。

自己写代码累,Matlab我没装,因此我使用 GML Calibration Toolbox,可以在这里下载:http://graphics.cs.msu.ru/en/node/909 。这是一个C++写的标定程序,有友好的用户界面,精度也不错,使用非常方便。

分别将RGB和红外的照片扔进去,得到RGB摄像头的内参(包括畸变参数):

=== Intrinsic ===

554.952628      0.000000           327.545377

0.000000           555.959694      248.218614

0.000000           0.000000           1.000000

=== Distortion ===

0.025163          -0.118850          -0.006536          -0.001345

和Kinect深度摄像头的内参(这个对所有Kinect应该都是差不多的):

=== Intrinsic ===

597.599759      0.000000           322.978715

0.000000           597.651554      239.635289

0.000000           0.000000           1.000000

=== Distortion ===

-0.094718          0.284224           -0.005630          -0.001429

四、配准

现在说说怎么配准,由于Kinect可以得到真实点的三维坐标,因此深度图的配准可以用一些简单特殊的方法。

设P_ir为在深度摄像头坐标下某点的空间坐标,p_ir为该点在像平面上的投影坐标(x、y单位为像素,z等于深度值,单位为毫米),H_ir为深度摄像头的内参矩阵,由小孔成像模型可知,他们满足以下关系:

又设P_rgb为在RGB摄像头坐标下同一点的空间坐标,p_rgb为该点在RGB像平面上的投影坐标,H_rgb为RGB摄像头的内参矩阵。由于深度摄像头的坐标和RGB摄像头的坐标不同,他们之间可以用一个旋转平移变换联系起来,即:

其中R为旋转矩阵,T为平移向量。最后再用H_rgb对P_rgb投影,即可得到该点对应的RGB坐标:

需要注意的是,p_ir和p_rgb使用的都是齐次坐标,因此在构造p_ir时,应将原始的像素坐标(x,y)乘以深度值,而最终的RGB像素坐标必须将p_rgb除以z分量,即(x/z,y/z),且z分量的值即为该点到RGB摄像头的距离(单位为毫米)。

现在的问题是,如何求联系两个坐标系的旋转矩阵和平移向量。这就要用到摄像头的外参了。

外参矩阵实际上也是由一个旋转矩阵R_ir(R_rgb)和平移向量T_ir(T_rgb)构成的,它表示将一个全局坐标系下的点P变换到摄像头坐标系下,分别对深度摄像头和RGB摄像头进行变换,有以下关系:

在第一式中,将P用P_ir、R_ir和T_ir表示,并带入第二式,可得:

从上式可以看出,这是在将P_ir变换为P_rgb,对比之前的式子:

可得:

因此,我们只需在同一场景下,得到棋盘相对于深度摄像头和RGB摄像头的外参矩阵,即可算出联系两摄像头坐标系的变换矩阵(注意,所有旋转矩阵都是正交阵,因此可用转置运算代替求逆运算)。虽然不同场景下得到的外参矩阵都不同,计算得到的R和T也有一些变化,但根据实际实验结果来看,使用一个正面棋盘的标定图像就可达到较好的效果,如下图:

注意,这两幅图像必须来自于同一场景,否则没有意义。当然你也可以使用多个场景下的外参,然后使用OpenCV的StereoCalibration函数求得两个摄像头的最佳相对变换矩阵,由于时间关系,我没有做这个测试。

使用GML Calibration Toolbox得到以上两图的外参(在菜单栏的Calibration->Export Calibration Data菜单中选择导出),然后根据上式,扔进Mathematica里面去做矩阵运算,得到最终的R和T:

R={ {0.999853, -0.00340388, 0.0167495},

{0.00300206, 0.999708,  0.0239986},

{-0.0168257, -0.0239459, 0.999571}  }

T={  {15.2562}, {70.2212}, {-10.9926}  }

五、测试

最后写一个小程序测试一下,在此说一下这个测试程序的思路:

1、获取Kinect的深度图像;

2、获取RGB摄像头的图像;

3、为深度图像中的每一个像素附上对应的RGB颜色,比如你要给坐标为(x, y)的深度图像素附上颜色,具体步骤如下;

1)构造一个三维向量p_ir = (x, y, z),其中x,y是该点的像素坐标,z是该像素的深度值;

2)用Kinect内参矩阵H_ir的逆,乘以p_ir得到对应的空间点坐标P_ir,具体公式见上文第四部分(配准);

3)由于P_ir是该点在Kinect坐标系下的坐标,我们需要将其转换到RGB摄像头的坐标系下,具体的,就是乘以一个旋转矩阵R,再加上一个平移向量T,得到P_rgb;

4)用RGB摄像头的内参矩阵H_rgb乘以P_rgb,得到p_rgb,p_rgb也是一个三维向量,其x和y坐标即为该点在RGB图像中的像素坐标,取出该像素的颜色,作为深度图像中对应像素的颜色;

5)对深度图像中的每一个像素都做上述操作,得到配准后的深度图。

看看配准前(左)和配准后(右)的区别:

从图像上看,配准已经很精确了。若还要更好,可以手动微调一下两个摄像头的平移向量T,主要改x分量和y分量,这样可以控制RGB和深度图的左右对齐和上下对齐。另外,还可以加入对畸变系数的处理,不过由于Kinect的摄像头以及我使用的RGB摄像头本身质量较高,畸变影响不大,这里就全部忽略了。

版权声明:本文为作者授权转载,由3D视觉开发者社区编辑整理发布,仅做学术分享,未经授权请勿二次传播,版权归原作者所有,图片来源于网络,若涉及侵权内容请联系删文。

本文仅做学术分享,如有侵权,请联系删文。

干货下载与学习

后台回复:巴塞罗自治大学课件,即可下载国外大学沉淀数年3D Vison精品课件

后台回复:计算机视觉书籍,即可下载3D视觉领域经典书籍pdf

后台回复:3D视觉课程,即可学习3D视觉领域精品课程

3D视觉精品课程推荐:

1.面向自动驾驶领域的多传感器数据融合技术

2.面向自动驾驶领域的3D点云目标检测全栈学习路线!(单模态+多模态/数据+代码)
3.彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进
4.国内首个面向工业级实战的点云处理课程
5.激光-视觉-IMU-GPS融合SLAM算法梳理和代码讲解
6.彻底搞懂视觉-惯性SLAM:基于VINS-Fusion正式开课啦
7.彻底搞懂基于LOAM框架的3D激光SLAM: 源码剖析到算法优化
8.彻底剖析室内、室外激光SLAM关键算法原理、代码和实战(cartographer+LOAM +LIO-SAM)

9.从零搭建一套结构光3D重建系统[理论+源码+实践]

10.单目深度估计方法:算法梳理与代码实现

11.自动驾驶中的深度学习模型部署实战

12.相机模型与标定(单目+双目+鱼眼)

13.重磅!四旋翼飞行器:算法与实战

14.ROS2从入门到精通:理论与实战

15.国内首个3D缺陷检测教程:理论、源码与实战

重磅!3DCVer-学术论文写作投稿 交流群已成立

扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。

同时也可申请加入我们的细分方向交流群,目前主要有3D视觉CV&深度学习SLAM三维重建点云后处理自动驾驶、多传感器融合、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、求职交流、ORB-SLAM系列源码交流、深度估计等微信群。

一定要备注:研究方向+学校/公司+昵称,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,可快速被通过且邀请进群。原创投稿也请联系。

▲长按加微信群或投稿

▲长按关注公众号

3D视觉从入门到精通知识星球:针对3D视觉领域的视频课程(三维重建系列三维点云系列结构光系列手眼标定相机标定、激光/视觉SLAM、自动驾驶等)、知识点汇总、入门进阶学习路线、最新paper分享、疑问解答五个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近5000星球成员为创造更好的AI世界共同进步,知识星球入口:

学习3D视觉核心技术,扫描查看介绍,3天内无条件退款

圈里有高质量教程资料、答疑解惑、助你高效解决问题

觉得有用,麻烦给个赞和在看~  

超强实操!手把手教学Kinect深度图与RGB摄像头的标定与配准相关推荐

  1. Kinect深度图与摄像头RGB的标定与配准(文末总结不容错过)

    作者原文地址:Kinect深度图与RGB摄像头的标定与配准_aipiano的博客-CSDN博客_深度摄像头标定 自从有了Kinect,根据深度图提取前景就非常方便了.因此出现了很多虚拟现实.视频融合等 ...

  2. Kinect深度图与摄像头RGB的标定与配准(转载文章)

    作者原文地址:http://blog.csdn.net/aichipmunk/article/details/9264703 自从有了Kinect,根据深度图提取前景就非常方便了.因此出现了很多虚拟现 ...

  3. RecyclerView的超强辅助Graywater——综合实操篇

    关于Graywater的系列文章 RecyclerView的超强辅助Graywater--理论篇 RecyclerView的超强辅助Graywater--基础实操篇 RecyclerView的超强辅助 ...

  4. RecyclerView的超强辅助Graywater——基础实操篇

    关于Graywater的系列文章 RecyclerView的超强辅助Graywater--理论篇 RecyclerView的超强辅助Graywater--基础实操篇 RecyclerView的超强辅助 ...

  5. UnrealEngine5实操--基础概念(持续补充)

    UnrealEngine5实操--基础概念 Unreal 术语 UE5 上手指南 关卡快速搭建 视口标准按键操作 Editor 视角移动速度调节 Unreal Editor 快速测距 Actor 操作 ...

  6. 弹性布局案例实操(京东网页制作的草稿)

    CSS3的弹性布局_星辰镜的博客-CSDN博客 上面的文章弹性布局的详细介绍: Css3的页面布局之定位_星辰镜的博客-CSDN博客 上面的文章是定位的介绍 Day02 了解Html+CSS的学习内容 ...

  7. 2021年焊工(初级)免费试题及焊工(初级)实操考试视频

    题库来源:安全生产模拟考试一点通公众号小程序 安全生产模拟考试一点通:焊工(初级)免费试题是安全生产模拟考试一点通总题库中生成的一套焊工(初级)实操考试视频,安全生产模拟考试一点通上焊工(初级)作业手 ...

  8. 计算机视觉之姿态识别(原理+代码实操)

    一.姿态识别整体过程 基于图像视频 基于mems传感器(高性能三维运动姿态测量系统) 二.人体分割 •人体分割使用的方法可以大体分为人体骨骼关键点检测.语义分割等方式实现.这里主要分析与姿态相关的人体 ...

  9. 计算机高级调试员操作网络题,计算机高级操作员实操步骤

    计算机高级操作员实操步骤 (5页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 试题仁计算机安装.连接.调试a) 点我的电脑T右键T屈性T高级 ...

最新文章

  1. 知乎热帖:Qt 这么强大为什么火不起来?
  2. CondaHTTPError: HTTP 404 NOT FOUND for url https://pypi.tuna.tsinghua.edu.cn/simple/ 错误
  3. 干货整理 Unity3D资源汇总
  4. 关于Unity中NGUI的Pivot和锚点
  5. Spring(十二)Spring之事务
  6. HTML+CSS制作3D旋转相册
  7. Curl+Postman+Python,自动化构造测试数据
  8. jupyter notebook 多行输出
  9. SqlServer日常积累(二)
  10. 【图解深度学习】【章节:1-1.2 | 神经网络输入输出】连小学生都能看懂的深度学习基础总结
  11. php pdf转为word,免费pdf转word软件汇总
  12. C语言蓝桥杯刷题:等差素数列
  13. VM安装windows server 2008
  14. 论文作业(1):VOIP 中Speex/ILBCISAC/SILK比较
  15. 12C GDS安装简记
  16. linux下bluetooth编程(一)基础概念
  17. build.gradle文件详解
  18. 美丽诗文背诵-未完待续
  19. 码率控制(一):理解码率控制模式(x264,x264,vpx)
  20. {0}:{1:.4f}“.format(是什么意思 Python字符串格式化 (%占位操作符)

热门文章

  1. 20180320作业1:源代码管理工具调查
  2. #HTTP协议学习# (二)基本认证
  3. Maven学习-项目对象模型
  4. 5分钟教你Windows 10中将“运行”固定到开始菜单
  5. [Java基础]Scanner的使用(秋招在线笔试高频使用)版本:Java™ Platform Standard Ed. 8...
  6. JQUERY知识总结
  7. 构建根文件系统启动(1)
  8. Scala Trait详解
  9. js、PHP将分数字符串转换为小数
  10. 修改模拟器的IMEI号