open3d_ros_pointcloud_conversion
open3d_ros_pointcloud_conversion copied to clipboard
Fixes on FLOAT32 for open3d to ros msg conversion
Although it seems that this repo is not maintained for a while, hopefully this is still helpful for ppl who wish to quickly find the solution to convert open3d pcd to ros pointcloud2 msg.
Fixes to make convertCloudFromOpen3dToRos
works:
Tested on open3d 0.17.0
, ros noetic
# The data structure of each point in ros PointCloud2: 16 bits = x + y + z + rgb
FIELDS_XYZ = [
PointField(name='x', offset=0, datatype=PointField.FLOAT32, count=1),
PointField(name='y', offset=4, datatype=PointField.FLOAT32, count=1),
PointField(name='z', offset=8, datatype=PointField.FLOAT32, count=1),
]
FIELDS_XYZRGB = FIELDS_XYZ + \
[PointField(name='rgb', offset=12, datatype=PointField.FLOAT32, count=1)]
# Bit operations
BIT_MOVE_16 = 2**16
BIT_MOVE_8 = 2**8
convert_rgbUint32_to_tuple = lambda rgb_uint32: (
(rgb_uint32 & 0x00ff0000)>>16, (rgb_uint32 & 0x0000ff00)>>8, (rgb_uint32 & 0x000000ff)
)
convert_rgbFloat_to_tuple = lambda rgb_float: convert_rgbUint32_to_tuple(
int(cast(pointer(c_float(rgb_float)), POINTER(c_uint32)).contents.value)
)
# Convert the datatype of point cloud from Open3D to ROS PointCloud2 (XYZRGB only)
def convertCloudFromOpen3dToRos(open3d_cloud, frame_id="map"):
# Set "header"
header = Header()
header.stamp = rospy.Time.now()
header.frame_id = frame_id
# Set "fields" and "cloud_data"
points=np.asarray(open3d_cloud.points)
if not open3d_cloud.colors: # XYZ only
fields=FIELDS_XYZ
cloud_data=points
else: # XYZ + RGB
fields=FIELDS_XYZRGB
# -- Change rgb color from "three float" to "one 24-byte int"
# 0x00FFFFFF is white, 0x00000000 is black.
colors = np.floor(np.asarray(open3d_cloud.colors)*255)
colors = colors.astype(np.uint32)
colors = colors[:,2] * BIT_MOVE_16 +colors[:,1] * BIT_MOVE_8 + colors[:,1]
colors = colors.view(np.float32)
cloud_data = [tuple((*p, c)) for p, c in zip(points, colors)]
# create ros_cloud
return pc2.create_cloud(header, fields, cloud_data)
when viz on rviz, show it in RGB8