2013-05-03 256 views
3

我在猜測這是兩個3D點雲之間的剛性變換矩陣。 這兩點雲是那些:兩個3D點雲變換矩陣

  • 來自kinect(kinect_keypoints)的關鍵點。
  • 來自3D對象(盒子)(object_keypoints)的關鍵點。

我曾嘗試兩種選擇:

[1]。執行該算法以找到剛性變換。

**1.Calculate the centroid of each point cloud.** 

**2.Center the points according to the centroid.** 

**3. Calculate the covariance matrix** 
cvSVD(&_H, _W, _U, _V, CV_SVD_U_T); 
cvMatMul(_V,_U, &_R); 
**4. Calculate the rotartion matrix using the SVD descomposition of the covariance matrix** 

float _Tsrc[16] = { 1.f,0.f,0.f,0.f, 
    0.f,1.f,0.f,0.f, 
    0.f,0.f,1.f,0.f, 
    -_gc_src.x,-_gc_src.y,-_gc_src.z,1.f }; // 1: src points to the origin 
float _S[16] = { _scale,0.f,0.f,0.f, 
    0.f,_scale,0.f,0.f, 
    0.f,0.f,_scale,0.f, 
    0.f,0.f,0.f,1.f }; // 2: scale the src points 
float _R_src_to_dst[16] = { _Rdata[0],_Rdata[3],_Rdata[6],0.f, 
    _Rdata[1],_Rdata[4],_Rdata[7],0.f, 
    _Rdata[2],_Rdata[5],_Rdata[8],0.f, 
    0.f,0.f,0.f,1.f }; // 3: rotate the scr points 
float _Tdst[16] = { 1.f,0.f,0.f,0.f, 
    0.f,1.f,0.f,0.f, 
    0.f,0.f,1.f,0.f, 
    _gc_dst.x,_gc_dst.y,_gc_dst.z,1.f }; // 4: from scr to dst 

// _Tdst * _R_src_to_dst * _S * _Tsrc 
mul_transform_mat(_S, _Tsrc, Rt); 
mul_transform_mat(_R_src_to_dst, Rt, Rt); 
mul_transform_mat(_Tdst, Rt, Rt);  

[2]。使用opencv中的estimateAffine3D。

 float _poseTrans[12]; 
     std::vector<cv::Point3f> first, second;    
     cv::Mat aff(3,4,CV_64F, _poseTrans); 
     std::vector<cv::Point3f> first, second; (first-->kineckt_keypoints and second-->object_keypoints) 
     cv::estimateAffine3D(first, second, aff, inliers); 

     float _poseTrans2[16]; 

     for (int i=0; i<12; ++i) 
     { 
      _poseTrans2[i] = _poseTrans[i]; 
     } 

     _poseTrans2[12] = 0.f; 
     _poseTrans2[13] = 0.f; 
     _poseTrans2[14] = 0.f; 
     _poseTrans2[15] = 1.f; 

中的第一個問題是,它是不正確的,並在第二個中,如果與所得的矩陣相乘Kinect的點雲的轉變,一些值是無限的。

是否有任何解決方案從這些選項中的任何一個?或者,除了PCL之外,還有其他選擇嗎?

預先感謝您。

+0

你在兩個雲層之間會發生什麼類型的變換,他們有什麼不同? – denver 2013-05-03 13:30:44

+0

kineckt_keypoints列表中的第一個點是否與object_keypoints中的第一個點相對應,第二個點是否與第二個相對應?如果不是,那麼大多數仿射變換估計算法將無法工作(我對openCV中的算法一無所知)。 – denver 2013-05-03 13:33:47

+0

是的,我需要的是第一個濁點(第一個對應於kineckt點)和第二個濁點(第二個對應於第二個清單)之間的仿射(剛性)變換。我已經爲第二個列表(手動)選擇了關鍵點,並在圖像中進行了投影,我猜測它是來自kinect的關鍵點列表。所以第一個列表點對應於第二個列表點。 – punta 2013-05-03 15:07:32

回答

2

編輯:這是一個古老的職位,但答案可能是有用的人......

你的第一個方法能夠工作在非常特殊的情況下(橢圓點雲或很長條形),但不適合由kinect獲取點雲。關於第二種方法,我對OpenCV函數estimateAffine3D不熟悉,但我懷疑它假定兩個輸入點雲對應相同的物理點,如果使用了kinect點雲(包含噪聲測量)並且不是這種情況,並且從理想的3D模型(這是完美的)點。

您提到您瞭解點雲庫(PCL)並且不想使用它。如果可能的話,我想你可能想重新考慮這一點,因爲PCL比你想要做的更適合OpenCV(查看教程列表,其中一個包含,正好是你想要做的事情:將對象模板對齊到點雲)。

然而,這裏是你的問題的一些替代方案:

  1. 如果你的兩個點雲正好對應於同一個物理點,你的第二個方法應該可行,但你還可以檢查出絕對定向(例如,Matlab implementation

  2. 如果你的兩個點雲不對應於同一個物理點,你居然要註冊(或對齊)他們,你可以使用:

    • 迭代最接近點(ICP)算法的衆多變體之一,如果您大概知道對象的位置。Wikipedia Entry

    • 3D特徵點,如3D SIFT,3D SURF或NARF特徵點,如果您不知道對象的位置。

同樣,所有這些辦法PCL中已經實施。