3d segmentation
來自專欄 6D pose estimation
最近看到一個什麼博覽會上bin picking的演示,突然間發現bin picking的零件好像都是簡單幾何體或者簡單幾何體的組合,比如圓柱、彎管之類的。之前我一直以為現在bin picking已經能做到抓任意零件了,但是如果真的能做到,那這些公司肯定會重點展示。所以他們的演算法肯定利用了簡單幾何體的性質,跟linemod之流還不太一樣。
那簡單幾何體的什麼性質可以拿來用呢?經過我一周的調研跟思考,我發現最有可能的是凸。比如說現在一個正方體放在桌面上。首先,RGB的信息一般用不上,因為工業上的零件都是無紋理的。那為了識別出這個正方體,我們需要把正方體的點雲分割出來,之後用super4pcs或者icp都好處理了。由於正方體是凸的,正方體自己的邊可以認為是凸的邊,而正方體跟桌面的邊就不是凸的了。凸邊還是凹邊判斷起來也簡單,用一張圖說明:
如果零件本身不是完全凸的,有一大塊是凸的也行,匹配的時候相當於匹配零件的一部分。所以,零件的點雲凸的區域越大,分割出來的點雲越容易識別。
那麼,怎麼把一塊凸的點雲分割出來呢?
DASP
點雲分割的論文也挺多,我主要看的是PCL庫segmentation源碼里貼的論文,其中比較有代表性的是:
Object Partitioning using Local Convexity
這篇論文分割的主要思路是先把點雲聚類,處理成superpixel,一個superpixel可以看做一個小平面;然後計算平面之間是凸還是凹,把小平面聚起來:
這篇效果看上去不錯,不過第一步聚類成supervoxels是基於voxel的,我感覺比較慢。我找到另一篇直接基於pixel的演算法,演算法參考了SLIC圖像分割演算法,速度比較快,效果也不錯:
Depth-Adaptive Superpixels,代碼:Danvil/asp
原論文中也有聚類的部分,採用的是sPb,一篇11年經典的圖像分割論文的思路:
detection and hierarchical image segmentation
看上去效果還行,不過這一部分的代碼沒有開源,所以我簡單地用圖分割的方法寫了一個。也就是說,如果兩個superpixel是凹的關係就不合併,離得太遠也不合併,這樣一個連續的凸點雲就分割出來了。測試結果如下:
可以看到效果還是不錯的,第一張圖中兩個長方體合在一起,這是因為它們接觸的部分凹的不明顯,這個之後可以用一些方法進一步處理分開;第二張圖的結果就比較好了,可以清楚地看到每個杯子的輪廓。在圖像的邊邊角角的地方superpixel沒有合併起來,這是因為那一塊比較遠,而且拍攝角度幾乎垂直,superpixel之間的實際距離遠。演算法的速度非常快,開O3優化一張640x480的圖才0.2s。
代碼見 meiqua/6DPose
進一步測試發現,直接用這種greedy的方式不太好,因為兩個物體只要有一小部分凸連接連起來,那物體很容易全部聚成一塊,如圖:
為了解決這個問題,我採用了一個分階段的聚類方法:
第一階段聚類接近平面的超像素,也就是normal夾角接近0度:
第二階段聚類剩下的凸連接,聚類過程中不斷檢查凸點雲的性質,也就是任一平面都是凸點雲的切平面,每次合併兩個平面集都檢查是不是滿足這個條件。這樣操作跟原來相比考慮了全局凸點雲的性質,理論上分割地更好。最後聚類的結果:
可以看見原來一坨大點雲被分成了三坨小點雲,效果比較好。而且這個也能把原來挨著的長方體分割開:
又經過一段時間的測試改進,我發現第二階段按照邊的權重順序來融合不合理。更好的方式是按照第一階段得到近似平面的點雲大小來聚類,我們稱之為big brother first。
我們的核心假設是,零件有一大塊凸點雲,而由於干擾的存在,按照邊權重聚合+convex check的方式可能會把不同物體的一部分聚在一起。如果按照大點雲優先的方式,就算這個零件的分割侵佔了別的物體也無所謂,只要一坨大點雲有一個完整物體就好,反正bin picking抓走就沒了,再抓再識別就好。所以按照這個思路,這次的第二階段按照第一階段分割的大小來greedy聚類。
最後我們的big brother first版本結果如下:
測試了下複雜形狀的情況,果然把物體凸分割割開了:
推薦閱讀:
※《動畫製作現場》系列之二:3DCG的工作現場
※錯過直播、短視頻?下一個內容風口是什麼?
※C4D Neon Light海報分析與製作
※為什麼有的人玩第一人稱3D遊戲會頭暈噁心?如何緩解?
※一根長棍,替代整套家庭影院~