天天看點

open3d最大平面檢測,平面分割

1.點雲讀入

  • 讀入檔案(配套點雲下載下傳連結)
# 讀取點雲
pcd = o3d.io.read_point_cloud("point_cloud_00000.ply")
           
  • 配套點雲顔色為白色,open3d的點雲顯示預設背景為白色,是以将點雲顔色更改為黑色
  • 顯示點雲
open3d最大平面檢測,平面分割

2.平面分割

  • RANSAC方法尋找最大平面(RANSAC方法可以在幹擾點存在的情況下拟合資料,需要給定拟合方程,通過在資料中随機選取指定個數的點來求解方程參數,然後看所有資料中有多少資料滿足所求解得到的方程,如果數量超過設定門檻值,就完成拟合)
  • 注意,RANSAC方法随機選點,是以結果會具有一定的随機性,特别是幹擾點較多的時候,兩次運作可能會得到不一樣的結果
plane_model, inliers = pcd.segment_plane(distance_threshold=1 * 1e-3,
                                         ransac_n=3,
                                         num_iterations=1000)
           
  • 關鍵參數:
    • distance_threshold:點到平面的最小距離,越小結果越精準
    • ransac_n:求解平面方程所需的随機點個數
    • num_iterations:随機平面被采樣和驗證的次數(随機選取點的次數,越大越可能得到正确結果,但會越慢)
  • 傳回參數:
    • plane_model:平面标準方程參數(将平面傳回為(a,b,c,d),使得對于平面上的每個點(x,y,z))
    • inliers:内點(滿足平面方程的點)的索引清單
[a, b, c, d] = plane_model
print(f"Plane equation: {a:.2f}x + {b:.2f}y + {c:.2f}z + {d:.2f} = 0")
           

3.内點提取與可視化顯示

  • 提取内點并塗色:
inlier_cloud = pcd.select_by_index(inliers)
inlier_cloud.paint_uniform_color([1.0, 0, 0])
           
  • 保留外點:(通過内點索引取反)
  • 内點外點同時可視化:
open3d最大平面檢測,平面分割

4.整體代碼

import open3d as o3d
import numpy as np

pcd = o3d.io.read_point_cloud('duanmian/1/point_cloud_00000.ply')
points = np.array(pcd.points)
colors = np.zeros(np.array(pcd.points).shape[0])
pcd.colors = o3d.utility.Vector3dVector(np.zeros(np.array(pcd.colors).shape))
#o3d.visualization.draw_geometries([pcd])

plane_model, inliers = pcd.segment_plane(distance_threshold=1 * 1e-3,
                                         ransac_n=3,
                                         num_iterations=1000)
[a, b, c, d] = plane_model
print(f"Plane equation: {a:.2f}x + {b:.2f}y + {c:.2f}z + {d:.2f} = 0")

inlier_cloud = pcd.select_by_index(inliers)
inlier_cloud.paint_uniform_color([1.0, 0, 0])
outlier_cloud = pcd.select_by_index(inliers, invert=True)
o3d.visualization.draw_geometries([inlier_cloud, outlier_cloud])
           

繼續閱讀