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

作者原文地址:http://blog.csdn.net/aichipmunk/article/details/9264703

 

自从有了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}  }

 

五、测试

最后写一个小程序测试一下,看看配准前(左)和配准后(右)的区别:

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

 

说一下这个测试程序的思路。

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)对深度图像中的每一个像素都做上述操作,得到配准后的深度图。

 

作者原文地址:http://blog.csdn.net/aichipmunk/article/details/9264703

知乎上网友代码:https://www.zhihu.com/question/29631310

 

国外的标定:

http://rgbdemo.org/index.php/Documentation/Calibration

http://burrus.name/index.php/Research/KinectCalibration#tocLink5

 

Kinect彩色图深度图配准(分辨率不一样时的处理方式):http://blog.csdn.net/shihz_fy/article/details/43602393

ROS下的驱动与图像序列保存及opencv显示深度坐标:http://blog.csdn.net/sunbibei/article/details/51594824

 

================================分割线=====================================

============================================

2017.09.08

SDK获取出厂内参数代码,MATLAB 标定Kinect v2等

http://blog.csdn.net/jiaojialulu/article/details/77430563

 ================================分割线====================================SaveSave

彩色图和深度图配准的事,我目前是不推荐自己做配准,很繁琐。如果要自己来做配准,目前我认为的三个配的比较好的(暂且不说Kinect 2的SDK了,需要安装SDK 2.0 +Visual studio + opencv + PCL,很繁琐,Kinect C++资料较C#少很多),个人精力有限,源码没有深究。
1. PCL1.8里有个程序,pcl_openni2_viewer,在Linux下面直接接上相机华硕的Xtion Pro live,输入上面代码可以看到效果;其他的相机我没试过,这个pcl的github有源码,调用的openni的东西

2. Kinect V2相机在Linux下的驱动freenect2,源码编译之后,bin文件夹有个Protonect的程序,效果也很好,github官网也可以看到源码https://github.com/OpenKinect/libfreenect2

3. Processing 3程序有个Kinect 插件kinect4WinSDK(Kinect 1代和2代都有对应插件),下图是Kinect1代的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458131.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

台北到淡水版Firefox无法播放视频

台北到淡水版的Firefox所有的视频都无法播放,禁用了各种插件也还是没法播放,最后才确定是SWF的问题,大家有同样问题的,可以下载我的放到SWF文件夹下,目录结构如下图: ​Firefox的SWF下载地址1 ​Firefox的S…

最详细、最完整的相机标定讲解

相机标定详解 最近做项目要用到标定,因为是小白,很多东西都不懂,于是查了一堆的博客,但没有一个博客能让我完全能看明白整个过程,绝大多数都讲的不全面,因此自己总结了一篇博客,给自己理一下思…

卷积与反卷积动图

各种卷积与反卷积动态图 反卷积: 详细文字链接:https://www.zhihu.com/question/43609045/answer/132235276(该链接中并没有下面的动态图) Deconvolution大致可以分为以下几个方面:(1)unsupervised learning,其实就…

ASP.NET-权限管理五张表

ASP.NET 权限管理五张表权限管理的表(5张表)每个表里面必有的一些信息序号名称 字段 类型 主键默认值是否为空备注1 用户ID ID INT 是 null 否用户ID2用户名称UserNamevarchar(100)否null否用户名称3用户密码UserPasswordvarchar(20)否null否用…

神经网络CNN解释

from:https://blog.csdn.net/ruiyiin/article/details/77113973 这篇文章原地址为An Intuitive Explanation of Convolutional Neural Networks,卷积神经网络的讲解非常通俗易懂。 什么是卷积神经网络?为什么它们很重要? 卷积神经…

pcl里面使用KdTree来搜索

from:https://blog.csdn.net/qq_25491201/article/details/51135054 下面这个教程我们将学会怎么用KdTree找一个特殊点附近的K个最近邻,然后我们也将复习怎么通过一个特殊的半径来找里面所有的近邻。 一个k-d树,或者k维的树是一个计算机科学里面的数据…

HI3559A和AI深度学习框架caffe

from:http://blog.sina.com.cn/s/blog_156e567660102ygdf.html 1、HI3559A支持深度学习框架caffe。其中的NNIE神经网络加速单元是主要的属性。 2、caffe是一种快速深度学习框架和TensorFlow一样是一组标准深度学习开源框架。 3、对应想尝试AI深度学习的朋友可以按照网上的流…

Google Protocol Buffer 的使用和原理

from: https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/index.html 简介 什么是 Google Protocol Buffer? 假如您在网上搜索,应该会得到类似这样的文字介绍: Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言…

常用的几种卷积神经网络介绍

常用的几种卷积神经网络介绍 标签(空格分隔): 深度学习 这是一篇基础理论的博客,基本手法是抄、删、改、查,毕竟介绍这几个基础网络的博文也挺多的,就算是自己的一个笔记吧,以后忘了多看看。主…

深度学习案例

1. neural-style:利用卷积神经网络将一幅图像的内容与另一幅图像的风格相结合 https://github.com/jcjohnson/neural-style 2.Nerual Doodles:把 2 位的 Doodle 转成精良的艺术品 https://github.com/alexjc/neural-doodle 3. srez:通过深度…

深度学习图像标注工具汇总

对于监督学习算法而言,数据决定了任务的上限,而算法只是在不断逼近这个上限。世界上最遥远的距离就是我们用同一个模型,但是却有不同的任务。但是数据标注是个耗时耗力的工作,下面介绍几个图像标注工具: Labelme Labe…

UIBarbuttonItem

APPDelegate: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds]; //创建主界面,导航栏的第一个页面 FirstViewContr…

深度残差网络ResNet解析

ResNet在2015年被提出,在ImageNet比赛classification任务上获得第一名,因为它“简单与实用”并存,之后很多方法都建立在ResNet50或者ResNet101的基础上完成的,检测,分割,识别等领域都纷纷使用ResNet&#x…

基于深度学习的目标检测技术演进:R-CNN、Fast R-CNN、Faster R-CNN

object detection我的理解,就是在给定的图片中精确找到物体所在位置,并标注出物体的类别。object detection要解决的问题就是物体在哪里,是什么这整个流程的问题。然而,这个问题可不是那么容易解决的,物体的尺寸变化范…

CNN的发展历史(LeNet,Alexnet,VGGNet,GoogleNet,ReSNet)

欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld。 关于卷积神经网络CNN,网络和文献中有非常多的资料,我在工作/研究中也用了好一段时间各种常见的model了,就想着简单整理一下,以备查阅之需…

如何在VMWare的Ubuntu虚拟机中设置共享文件夹

亲测有效:Ubuntu18.04 LTS、虚拟机VMware Workstation 14 Pro 14.1.3 build-9474260、Window7 自己的第一篇博文,由于时(shuǐ)间(png)原(yǒu)因(xin)&…

容器+AOP实现动态部署(四)

上篇咱们介绍了容器和AOP的结合,结合后怎样将对象增强服务并没有过多的说明,这里将详细说明怎样将对象 进行增强 ,达到一个一对多和多对多的增强方式 先从简单的方式说起 /** *JDK代理类,实现动态调用对象方法 */ public class JD…

深入理解卷积层,全连接层的作用意义

有部分内容是转载的知乎的,如有侵权,请告知,删除便是,但由于是总结的,所以不一一列出原作者是who。 再次感谢,也希望给其他小白受益。 首先说明:可以不用全连接层的。 理解1: 卷…

用ionic快速开发hybird App(已附源码,在下面+总结见解)

用ionic快速开发hybird App(已附源码,在下面总结见解) 1.ionic简介 ionic 是用于敏捷开发APP的解决方案。核心思路是:利用成熟的前端开发技术,来写UI和业务逻辑。也就是说,就是一个H5网站,这个区别于react-…

40 个重要的 HTML5 面试问题及答案

2019独角兽企业重金招聘Python工程师标准>>> 介绍 我是一个ASP.NET MVC开发人员。最近当我找工作的时候,我发现很多问题都是围绕HTML 5和它的新功能展开的。所以,下面我将列出40个有助于你提高相关HTML 5知识的重要问题。 这些问题并不能保证…