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.pswp.cn/news/458131.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458131.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458131.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

臺北到淡水版Firefox無法播放視頻

臺北到淡水版的Firefox所有的視頻都無法播放,禁用了各種插件也還是沒法播放,最后才確定是SWF的問題,大家有同樣問題的,可以下載我的放到SWF文件夾下,目錄結構如下圖: ?Firefox的SWF下載地址1 ?Firefox的S…

最詳細、最完整的相機標定講解

相機標定詳解 最近做項目要用到標定,因為是小白,很多東西都不懂,于是查了一堆的博客,但沒有一個博客能讓我完全能看明白整個過程,絕大多數都講的不全面,因此自己總結了一篇博客,給自己理一下思…

時間日志和缺陷日志

項目計劃總結: 日期&&任務 聽課 編寫程序 閱讀相關書籍 網上查找資料 日總計 周一 2 2 1 1 6 周二 2 1 3 周三 1 2 2 5 周四 2 2 1 5 周五 4 1 1 6 周六 3 1 1 4 周日 4 2 2 周總計 4 …

卷積與反卷積動圖

各種卷積與反卷積動態圖 反卷積: 詳細文字鏈接: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,卷積神經網絡的講解非常通俗易懂。 什么是卷積神經網絡?為什么它們很重要? 卷積神經…

線條的屬性

1.lineCap"butt“ /"round" /"square" 只能用于線段的結尾處 不能用于線段的銜接處 2.lineJoin:線條與線條相交時的形態 miter(default)/ bevel (斜接)/round(圓接) 1.后繪制的圖形,如果與前繪制的圖形區…

pcl里面使用KdTree來搜索

from:https://blog.csdn.net/qq_25491201/article/details/51135054 下面這個教程我們將學會怎么用KdTree找一個特殊點附近的K個最近鄰,然后我們也將復習怎么通過一個特殊的半徑來找里面所有的近鄰。 一個k-d樹,或者k維的樹是一個計算機科學里面的數據…

Linux英文全稱

su:Swith user 切換用戶,切換到root用戶cat: Concatenate 串聯uname: Unix name 系統名稱df: Disk free 空余硬盤du: Disk usage 硬盤使用率chown: Change owner 改變所有者chgrp: Change group 改變用戶組ps:Process Status 進程狀態ta…

caffe caffe.cpp 程序入口分析

from:https://blog.csdn.net/u014114990/article/details/47747025 caffe.cpp 程序入口分析, (1)main()函數中,輸入的train,test,device_query,time。 通過下面兩行進入程序。 …

php文件加密

1.在線加密 網址:http://www.phpjm.net/encode.html 本人測試過還可以,就是純加密,沒有解密。 轉載于:https://www.cnblogs.com/wuheng1991/p/5332617.html

樹莓派3 編譯驅動

分為本地編譯和交叉編譯,主要是Makefile的寫法: 本地編譯: obj-m : bcm2835-i2s.o KDIR : /lib/modules/$(shell uname -r)/build PWD : $(shell pwd) all:make -C $(KDIR) M$(PWD) modules clean:rm *.o *.ko *.mod.c modules.order Module.…

caffe common 程序分析 類中定義類

caffe中 有 common.hpp 和common.cpp // The main singleton of Caffe class and encapsulates the boost and CUDA random number // generation function, providing a unified interface. caffe的singleton 類, 封裝boost和cuda等操作。 提供一個統一的接口&am…

相機標定究竟在標定什么?

https://mp.weixin.qq.com/s/sWpVgwXmPvIEbObXvo1HRg

SpringMVC+Shiro權限管理

SpringMVCShiro權限管理 什么是權限呢?舉個簡單的例子: 我有一個論壇,注冊的用戶分為normal用戶,manager用戶。對論壇的帖子的操作有這些:添加,刪除,更新,查看,回復我們規…

Caffe源碼解析1:Blob

from:https://www.cnblogs.com/louyihang-loves-baiyan/p/5149628.html 轉載請注明出處,樓燚(y)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/ 首先看到的是Blob這個類,Blob是作為Caffe中數據流通的一個基本類,網絡…

學后感

今天上了構建之法,我加深了對軟件工程的了解,也明白了單元測試和回歸測試對軟件開發的重要性,然而在軟件開發的過程中, 一個團隊是需要一定的流程來管理開發活動,每個工程師在軟件生命周期所做的工作也應該有一個流程&…

Caffe源碼解析2:SycedMem

from:https://www.cnblogs.com/louyihang-loves-baiyan/p/5150554.html 轉載請注明出處,樓燚(y)航的blog,http://www.cnblogs.com/louyihang loves baiyan/ 看到SyncedMem就知道,這是在做內存同步的操作。這類個類的代碼比較少,…

REST學習

RPC架構與REST架構 RPC:RPC將服務器看作一些列動作的集合(需要做某件事) REST:將服務器看作分布式對象集合,客戶端通過調用這些對象上的方法來執行特定的任務,組件交互的可伸縮性、接口的通用性、組件的獨立部署、以及用來減少交互…

HI3559A和AI深度學習框架caffe

from:http://blog.sina.com.cn/s/blog_156e567660102ygdf.html 1、HI3559A支持深度學習框架caffe。其中的NNIE神經網絡加速單元是主要的屬性。 2、caffe是一種快速深度學習框架和TensorFlow一樣是一組標準深度學習開源框架。 3、對應想嘗試AI深度學習的朋友可以按照網上的流…