PCL中分割方法的介紹(2)

2021-09-21 12:15:53 字數 3576 閱讀 8274

主要的缺點:該演算法沒有初始化種子系統,沒有過度分割或者分割不足的控制,還有就是從主迴圈運算中呼叫條件函式時,效率比較低,

看一下**吧,至於到底怎麼理解各個有個人的理解吧

#include #include 

#include

//如果此函式返回true,則將新增候選點到種子點的簇類中。

bool

customcondition(

const pcl::pointxyz& seedpoint, const pcl::pointxyz& candidatepoint, float

squareddistance)

intmain(

int argc, char**ar**)

//申明乙個條件聚類的物件

pcl::conditionaleuclideanclusteringclustering;

clustering.setclustertolerance(

0.02

); clustering.setminclustersize(

100);

clustering.setmaxclustersize(

25000

); clustering.setinputcloud(cloud);

//設定要檢查每對點的函式。

clustering.setconditionfunction(&customcondition);

std::vector

clusters;

clustering.segment(clusters);

//對於每乙個聚類結果

int currentclusternum = 1

;

for (std::vector::const_iterator i = clusters.begin(); i != clusters.end(); ++i)

}

上面執行的條件是檢查候選點的y座標是否小於種子的y座標,沒有什麼實際意義。所以我就再檢視結果了。

那麼同時我暫時也用不到,如果有想法的時候再回來研究吧

(2)最小分割演算法

該演算法是將一幅點雲影象分割為兩部分:前景點雲(目標物體)和背景物體(剩餘部分)

the min-cut (minimum cut) algorithm最小割演算法是圖論中的乙個概念,其作用是以某種方式,將兩個點分開,當然這兩個點中間可能是通過無數的點再相連的。如圖

如果要分開最左邊的點和最右邊的點,紅綠兩種割法都是可行的,但是紅線跨過了三條線,綠線只跨過了兩條。單從跨線數量上來論可以得出綠線這種切割方法更優 的結論。但假設線上有不同的權值,那麼最優切割則和權值有關了。當你給出了點之間的「圖」,以及連線的權值時,最小割演算法就能按照要求把圖分開。

所以那麼怎麼來理解點雲的圖呢?

顯而易見,切割有兩個非常重要的因素,第乙個是獲得點與點之間的拓撲關係,這種拓撲關係就是生成一張 「圖」。第二個是給圖中的連線賦予合適的權值。只要這兩個要素合適,最小割演算法就會正確的分割出想要的結果。點雲是分開的點。只要把點雲中所有的點連起來就可以了。連線演算法如下:

找到每個點臨近的n個點

將這n個點和父點連線

找到距離最小的兩個塊(a塊中某點與b塊中某點距離最小),並連線

重複3,直至只剩乙個塊

經過上面的步驟現在已經有了點雲的「圖」,只要給圖附上合適的權值,就滿足了最小分割的前提條件。物體分割比如影象分割給人乙個直觀印象就是屬於該物體的點,應該相互之間不會太遠。也就是說,可以用點與點之間的歐式距離來構造權值。所有線的權值可對映為線長的函式。

我們知道這種分割是需要指定物件的,也就是我們指定聚類的中心點(center)以及聚類的半徑(radius),當然我們指定了中心點和聚類的半徑,那麼就要被保護起來,保護的方法就是增加它的權值

接下來我們就來看看**

#include #include 

#include

#include

#include

#include

#include

intmain(

int argc, char**ar**)

//申明乙個min-cut的聚類物件

pcl::mincutsegmentationclustering;

clustering.setinputcloud(cloud);

//設定輸入

//建立乙個點雲,列出所知道的所有屬於物件的點

//(前景點)在這裡設定聚類物件的中心點(想想是不是可以可以使用滑鼠直接選擇聚類中心點的方法呢?)

pcl::pointcloud::ptr foregroundpoints(new pcl::pointcloud());

pcl::pointxyz point;

point.x = 100.0

; point.y = 100.0

; point.z = 100.0

; foregroundpoints->points.push_back(point);

clustering.setforegroundpoints(foregroundpoints);

//設定聚類物件的前景點

//設定sigma,它影響計算平滑度的成本。它的設定取決於點雲之間的間隔(解析度)

clustering.setsigma(0.02

);

//設定聚類物件的半徑.

clustering.setradius(0.01

);

//設定需要搜尋的臨近點的個數,增加這個也就是要增加邊界處圖的個數

clustering.setnumberofneighbours(20

);

//設定前景點的權重(也就是排除在聚類物件中的點,它是點雲之間線的權重,)

clustering.setsourceweight(0.6

); std::vector

clusters;

clustering.extract(clusters);

std::cout

<< "

maximum flow is

"<< clustering.getmaxflow() << "."

<<:endl>

int currentclusternum = 1

;

for (std::vector::const_iterator i = clusters.begin(); i != clusters.end(); ++i)

}

看一下實際執行的最小分割法的結果

原始的點雲

最小分割法的結果

對於實際應用中我們應該設定正確的引數這是最為關鍵的!

PCL濾波介紹(2)

1 使用statisticaloutlierremoval濾波器移除離群點 使用統計分析技術,從乙個點雲資料中集中移除測量雜訊點 也就是離群點 比如 雷射掃瞄通常會產生密度不均勻的點雲資料集,另外測量中的誤差也會產生稀疏的離群點,使效果不好,估計區域性點雲特徵 例如取樣點處法向量或曲率變化率 的運算...

VC中分割檔案路徑的分割類

ifndef splitpath h define splitpath h class csplitpath 進行分割 bool split lpctstr lpszpath 獲取全路徑 c temp foo.txt cstring getfullpath void 獲取驅動器碟符 c cstrin...

c 中分割字串的幾種方法

最近經常看到論壇中許多帖子詢問如何使用split來分割字串,我這裡對split做一些簡單的總結,希望能夠對大家有所幫助。下面介紹幾種方法 第一種方法 開啟vs.net新建乙個控制台專案。然後在main 方法下輸入下面的程式。string s abcdeabcdeabcde string sarray...