1.點雲分割的精度
在之前的兩個章節里介紹了基於采樣一致的點雲分割和基於臨近搜索的點雲分割算法。基於采樣一致的點雲分割算法顯然是意識流的,它只能割出大概的點雲(可能是杯子的一部分,但杯把兒肯定沒分割出來)。基於歐式算法的點雲分割面對有牽連的點雲就無力了(比如風箏和人,在不用三維形態學去掉中間的線之前,是無法分割風箏和人的)。基於法線等信息的區域生長算法則對平面更有效,沒法靠它來分割桌上的碗和杯子。也就是說,上述算法更關注能不能分割,除此之外,我們還需要一個方法來解決分割的“好不好”這個問題。也就是說,有沒有哪種方法,可以在一個點不多,一個點不少的情況下,把目標和“其他”分開。
答案是有,也就是這篇博文要解決的最小割算法。
2.最小割算法
最小割(min-cut)並不是一個什么很新鮮的東西。它早就用在網絡規划,求解橋問題,圖像分割等領域,被移植到點雲分割上也不足為奇。最小割算法是圖論中的一個概念,其作用是以某種方式,將兩個點分開,當然這兩個點中間可能是通過無數的點再相連的。如圖所示。
如果要分開最左邊的點和最右邊的點,紅綠兩種割法都是可行的,但是紅線跨過了三條線,綠線只跨過了兩條。單從跨線數量上來論可以得出綠線這種切割方法更優的結論。但假設線上有不同的權值,那么最優切割則和權值有關了。它到底是怎么找到那條綠線的暫且不論。總而言之,就是有那么一個算法,當你給出了點之間的 “圖” (廣義的),以及連線的權值時,最小割算法就能按照你的要求把圖分開。
3.點雲 “圖”
顯而易見,切割有兩個非常重要的因素,第一個是獲得點與點之間的拓撲關系,也就是生成一張“圖”。第二個是給圖中的連線賦予合適的權值。只要這兩個要素合適,最小割算法就會辦好剩下的事情。點雲是一種非常適合分割的對象(我第三次強調這個事情了),點雲有天然分開的點。有了點之后,只要把點雲中所有的點連起來就可以了。連接算法如下:
- 找到每個點最近的n個點
- 將這n個點和父點連接
- 找到距離最小的兩個塊(A塊中某點與B塊中某點距離最小),並連接
- 重復3,直至只剩一個塊
現在已經有了“圖”,只要給圖附上合適的權值,就完成了所有任務。物體分割給人一個直觀印象就是屬於該物體的點,應該相互之間不會太遠。也就是說,可以用點與點之間的歐式距離來構造權值。所有線的權值可映射為線長的函數。
貌似我們現在已經搞定一切了,其實不然。分割總是有一個目標的,而這種精准打擊的算法,顯然你要告訴我打擊對象是誰,打擊范圍多大——目標需要人為指定(center),尺寸需要提前給出(radius)。
OK,我們現在有了打擊對象了(指定了目標物體上的一個點),接下來要做的,就是讓除此對象之外的物體被保護起來,不受到打擊。保護的方法就是認為加重目標范圍之外的權值(罰函數)
上述過程其實看起來還不夠智能,如果有辦法讓我只需要點一下鼠標,選中要分割的物體,接下來電腦替我操心其他事情,那就太好了。這其實是可以實現的,稱為AutoMatic Regime.但PCL並沒有封裝這個算法,忽略不表。
4.PCL對最小割算法的實現
//生成分割器 pcl::MinCutSegmentation<pcl::PointXYZ> seg; //分割輸入分割目標 seg.setInputCloud (cloud); //指定打擊目標(目標點) pcl::PointCloud<pcl::PointXYZ>::Ptr foreground_points(new pcl::PointCloud<pcl::PointXYZ> ()); pcl::PointXYZ point; point.x = 68.97; point.y = -18.55; point.z = 0.57; foreground_points->points.push_back(point); seg.setForegroundPoints (foreground_points); //指定權函數sigma seg.setSigma (0.25); //物體大概范圍 seg.setRadius (3.0433856); //用多少生成圖 seg.setNumberOfNeighbours (14); //和目標點相連點的權值(至少有14個) seg.setSourceWeight (0.8); //分割結果 std::vector <pcl::PointIndices> clusters; seg.extract (clusters);
顯然,最小割算法更注重分割的精確性而不是分割自動進行。最小割算法用於半自動分割識別有着巨大的優勢,適合用於計算機視覺,城市場景點雲分析一類。但對機器人來說,或許和特征點檢測算法聯合起來能獲得較好的效果。
圖中顯示,最小割算法成功找到了靠的很近的汽車。顯然歐式算法r取太大則無法區分左右汽車,r取太小則無法區分車頭和車身(玻璃不反光,是沒有點雲的)。