機器人視覺中有一項重要人物就是從場景中提取物體的位置,姿態。圖像處理算法藉助Deep Learning 的東風已經在圖像的物體標記領域耍的飛起了。而從三維場景中提取物體還有待研究。目前已有的思路是先提取關鍵點,再使用各類局部特徵描述子對關鍵點進行描述,最後與待檢測物體進行比對,獲得點-點的匹配。個別文章在以後還採起了ICP對匹配結果進行優化。算法
對於缺少表面紋理信息,或局部曲率變化很小,或點雲自己就很是稀疏的物體,採用局部特徵描述子很難有效的提取到匹配對。因此就有了所謂基於Point Pair 的特徵,該特徵使用了一些全局的信息來進行匹配,更神奇的是,最終的位姿估計結果並不會陷入局部最小值。詳細可參見論文:Model globally, match locally: Efficient and robust 3D object recognition. 與 Going further with point pair features。SLAM的重要研究方向object based Slam 也聲稱使用了Point Pair Feature進行匹配。ide
爲了更好的理解這種方法,而在pcl中也沒有找到現成的算法,因此我本身用matlab實現了一遍。優化
算法的思想很簡單:spa
0、ppf 特徵爲[d,<d,n1>,<d,n2>,<n1,n2>].code
一、針對目標模型,在兩兩點之間構造點對特徵F,若是有N個點,那麼就有N*N個特徵(說明此算法是O(N2)的),N*N個特徵造成特徵集F_Setorm
二、在場景中任意取1定點a,再任意取1動點b,構造ppf特徵,並從F_set中尋找對應的,那麼理想狀況下,若是找到了徹底匹配的特徵,則可得到點雲匹配的結果。blog
三、此算法是一種投票算法,每次匹配都能獲得一個旋轉角度,若是m個b都投票給了某一旋轉角度則可認爲匹配成功ci
這個算法最大的問題就是不停的採樣會致使極大的計算量。不過算法自己確實能夠匹配物體和場景。rem
ppf 特徵的構建it
1 function obj = ppf(point1,point2) 2 d = point1.Location - point2.Location; 3 d_unit = d/norm(d); 4 apha1 = acos(point1.Normal*d_unit'); 5 apha2 = acos(point2.Normal*d_unit'); 6 apha3 = acos(point1.Normal*point2.Normal'); 7 obj = [norm(d),apha1,apha2,apha3]; 8 end
ppf 特徵集的構建
1 classdef modelFeatureSet < handle 2 %MODELFEATURESET 此處顯示有關此類的摘要 3 % 此處顯示詳細說明 4 5 properties 6 FeatureTree 7 ModelPointCloud 8 Pairs 9 end 10 11 methods 12 function obj = modelFeatureSet(pt) 13 obj.ModelPointCloud = copy(pt.removeInvalidPoints()); 14 end 15 function growTree(self) 16 self.ModelPointCloud = pcdownsample(self.ModelPointCloud,'GridAverage',.1); 17 pt_size = self.ModelPointCloud.Count; 18 idx = repmat(1:pt_size,pt_size,1); 19 tmp1 = reshape(idx,pt_size*pt_size,1); 20 tmp2 = reshape(idx',pt_size*pt_size,1); 21 pairs = [tmp1,tmp2]; 22 rnd = randseed(1,1000,1,1,pt_size*pt_size); 23 pairs = pairs(rnd,:); 24 Features = zeros(size(pairs,1),4); 25 for i = 1:size(pairs,1) 26 Features(i,:) = ppf(self.ModelPointCloud.select(pairs(i,1)),... 27 self.ModelPointCloud.select(pairs(i,2))); 28 end 29 self.FeatureTree = createns(Features); 30 self.Pairs = pairs; 31 end 32 end 33 end