如何在Rviz中可视化PC2转换点云并解决HDBSCAN聚类报错
问题解决与实现方案
报错原因
你触发报错的核心问题是numpy_msg()的入参要求是ROS消息类,但你传入了pcl点云对象p,类属性不匹配触发了AttributeError。
另外你定义的自定义msg也不合理:cluster.msg仅定义了单个float32字段,无法存储点云的x/y/z三维坐标信息,也不能直接在RViz中可视化。
最优实现方案
不需要自定义msg,直接发布 sensor_msgs/PointCloud2类型的带色点云即可,RViz原生支持该类型的可视化,还可以给不同聚类分配不同颜色,直观验证聚类效果。
修改后可运行代码
import hdbscan import rospy from sensor_msgs.msg import PointCloud2 import numpy as np import ros_numpy import time rospy.init_node('hdbscan') # 提前初始化发布者,不要放在回调里重复创建 pub_clusters = rospy.Publisher('cluster_pointcloud', PointCloud2, queue_size=1) def callback(data): tstart = time.time() # 把输入的PointCloud2转numpy数组 pc = ros_numpy.numpify(data) points = np.zeros((pc.shape[0], 3)) points[:, 0] = pc['x'] points[:, 1] = pc['y'] points[:, 2] = pc['z'] # HDBSCAN聚类 clusterer = hdbscan.HDBSCAN(min_cluster_size=15, min_samples=1, alpha=1.3).fit(points) cluster_labels = clusterer.fit_predict(points) # 构建带RGB的点云数组 # 随机生成不同聚类的颜色,噪声点(label=-1)设为灰色 n_clusters = cluster_labels.max() + 1 colors = np.random.randint(0, 255, size=(n_clusters, 3)) rgba = np.zeros((points.shape[0], 4), dtype=np.uint8) for i, label in enumerate(cluster_labels): if label == -1: rgba[i] = [128, 128, 128, 255] # 噪声点灰色 else: rgba[i, :3] = colors[label] rgba[i, 3] = 255 # 构造符合ros_numpy要求的结构化数组 cloud_arr = np.zeros(points.shape[0], dtype=[ ('x', np.float32), ('y', np.float32), ('z', np.float32), ('rgb', np.uint32) ]) cloud_arr['x'] = points[:, 0] cloud_arr['y'] = points[:, 1] cloud_arr['z'] = points[:, 2] # 把rgba转成uint32格式 cloud_arr['rgb'] = rgba.view(np.uint32) # 转成PointCloud2消息发布 ros_msg = ros_numpy.msgify(PointCloud2, cloud_arr, frame_id=data.header.frame_id) pub_clusters.publish(ros_msg) tstop = time.time() rospy.loginfo(f"聚类耗时: {tstop - tstart:.4f}s, 聚类数: {n_clusters}") def listener(): rospy.Subscriber('/wamv/sensors/lidars/lidar_wamv/points', PointCloud2, callback) rospy.spin() if __name__ == '__main__': listener()
RViz可视化操作步骤
- 运行你的ROS节点和rosbag
- 启动RViz,在左侧面板点击
Add,选择PointCloud2 - 把PointCloud2插件的
Topic选为/cluster_pointcloud - 把
Color Transformer选为RGB8,即可看到不同颜色区分的聚类结果,噪声点为灰色。
内容的提问来源于stack exchange,提问作者Drizzy23
相关产品推荐
相关产品推荐

