基于标签影像裁剪后的点云存在植被等噪声点,因此需要进行剔除。
首先进行初次DBSCAN聚类,剔除明显离群点:
#初次DBSCAN剔除离群点
with open3d.utility.VerbosityContextManager(open3d.utility.VerbosityLevel.Debug) as cm:
labels = np.array(sel_pcd.cluster_dbscan(eps=2, min_points=100, print_progress=True))
sel_pcd2=sel_pcd.select_by_index(np.array(range(points.shape[0]))[labels>=0])
再利用法向量,剔除大部分树木点:
#法向量筛选提取屋顶面
sel_pcd2.estimate_normals(
search_param=open3d.geometry.KDTreeSearchParamHybrid(radius=2, max_nn=3000)
)
points2 = np.array(sel_pcd2.points)
normals = np.array(sel_pcd2.normals)
jiaoduall=np.ones(points2.shape[0])
for index in range(points2.shape[0]):
jiaodi=abs(atan(sqrt(pow(normals[index,0],2)+pow(normals[index,1],2))/normals[index,2]))
jiaoduall[index]=jiaodi
sel_ind4=np.array(range(points2.shape[0]))[jiaoduall<0.6][:]
points = np.array(pcd.points)
pt_color=np.zeros(points.shape)
pt_color[:,1]=255
sel_pcd3=sel_pcd2.select_by_index(sel_ind4)
最后将树木点中法向量也在阈值的剔除:
#第二次DBSCAN剔除杂点
points3=np.array(sel_pcd3.points)
labels = np.array(sel_pcd3.cluster_dbscan(eps=6, min_points=200, print_progress=True))
sel_ind2=np.array(range(points3.shape[0]))[labels>=0]
sel_pcd4=sel_pcd3.select_by_index(sel_ind2)
sel_ind3=np.array(sel_ind)[sel_ind4[sel_ind2]]
pt_color[sel_ind3,0]=255
pcd.colors = open3d.utility.Vector3dVector(pt_color)
#open3d.visualization.draw_geometries([sel_pcd2])
open3d.io.write_point_cloud("dbs_sel_pcd.pcd", pcd)
open3d.io.write_point_cloud("dbs_sel_pcd_house.pcd", sel_pcd4)