如何基于Open3D在点云边界框上方显示带置信度的标签文本并控制文本属性
如何基于Open3D在点云边界框上方显示带置信度的标签文本并控制文本属性
嗨Abbas,我来帮你搞定这个需求!要在Open3D可视化的边界框上方添加包含置信度的标签文本,并且自定义它的位置、字体大小、样式和颜色,我们可以用Open3D内置的Text3D类来实现。下面是修改后的完整代码,我会给你拆解关键的改动点:
核心思路
我们要给每个预测的边界框创建一个3D文本对象,把它放置在边界框的顶部中心位置,然后通过Text3D的参数来控制文本的各种属性,最后把文本添加到可视化窗口中即可。
修改后的完整代码
import open3d import torch import matplotlib import numpy as np import time from . import common_utils, box_utils box_colormap = { 'Car': (0, 1, 0), } # RGB k=0 def draw_scenes(points, gt_boxes=None, ref_boxes=None, ref_labels=None, ref_scores=None, point_colors=None, point_size=1.0, window_name='Open3D'): global k if isinstance(points, torch.Tensor): points = points.cpu().numpy() if isinstance(gt_boxes, torch.Tensor): gt_boxes = gt_boxes.cpu().numpy() if isinstance(ref_boxes, torch.Tensor): ref_boxes = ref_boxes.cpu().numpy() if isinstance(point_colors, torch.Tensor): point_colors = point_colors.cpu().numpy() if isinstance(ref_scores, torch.Tensor): ref_scores = ref_scores.cpu().numpy() vis = open3d.visualization.Visualizer() vis.create_window(window_name=window_name, width=1280, height=720, visible=False) vis.get_render_option().point_size = point_size vis.get_render_option().background_color = np.asarray([0.4, 0.4, 0.4]) pts = open3d.geometry.PointCloud() pts.points = open3d.utility.Vector3dVector(points[:, :3]) vis.add_geometry(pts) if point_colors is not None: pts.colors = open3d.utility.Vector3dVector(point_colors) else: pts.colors = open3d.utility.Vector3dVector(np.ones((points.shape[0], 3)) * 0.9) if gt_boxes is not None: vis = draw_box(vis, gt_boxes, color=(1, 0, 0)) if ref_boxes is not None: if ref_labels is not None: vis = draw_box(vis, ref_boxes, ref_labels, ref_scores) else: vis = draw_box(vis, ref_boxes, color=(0, 1, 0), scores=ref_scores) # save the images of pointcloud with predicted bounding boxes vis.update_geometry(pts) vis.poll_events() vis.update_renderer() im_path = "/home/user/Predicted_images/{:06d}.png".format(k) vis.capture_screen_image(im_path) vis.destroy_window() k=k+1 def draw_box(vis, boxes, labels=None, scores=None, color=(1, 0, 0)): """ 7 -------- 4 /| /| 6 -------- 5 . | | | | . 3 -------- 0 |/ |/ 2 -------- 1 Args: boxes: [x, y, z, dx, dy, dz, heading], (x, y, z) is the box center labels: [name] Returns: """ for i in range(boxes.shape[0]): corners3d = box_utils.boxes_to_corners_3d(np.array([boxes[i]]))[0] edges = np.array([ [0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7], [7, 4], [0, 4], [1, 5], [2, 6], [3, 7], [0, 5], [1, 4], # heading ]) line_set = open3d.geometry.LineSet() line_set.points = open3d.utility.Vector3dVector(corners3d) line_set.lines = open3d.utility.Vector2iVector(edges) if labels is not None: line_set.paint_uniform_color(box_colormap[labels[i]]) else: line_set.paint_uniform_color(color) vis.add_geometry(line_set) # ========== 新增:添加带置信度的标签文本 ========== if labels is not None and scores is not None: # 1. 计算文本位置:边界框中心的正上方(y轴方向加上半高) box_center = boxes[i][:3] box_height = boxes[i][4] # dy是y方向的高度 text_position = (box_center[0], box_center[1] + box_height/2 + 0.1, box_center[2]) # 0.1是额外的偏移量,避免文本贴在盒子上,可根据需要调整 # 2. 拼接标签和置信度文本(保留两位小数更美观) text_content = f"{labels[i]} {scores[i]:.2f}" # 3. 创建3D文本对象,设置属性 text_3d = open3d.geometry.Text3D( text=text_content, position=text_position, font_size=0.3, # 字体大小,可调整 color=(1, 1, 0), # 文本颜色,RGB格式,这里是黄色 # font="/path/to/your/font.ttf" # 如果需要自定义字体,取消注释并填写字体路径 ) # 4. 将文本添加到可视化窗口 vis.add_geometry(text_3d) return vis
关键改动说明
- 文本位置控制:
- 我们取边界框的中心坐标
box_center,然后在y轴方向加上边界框高度的一半(box_height/2),再额外加0.1的偏移量,确保文本在边界框正上方且不遮挡盒子。你可以根据自己的点云尺度调整这个偏移量。
- 我们取边界框的中心坐标
- 文本内容定制:
- 用f-string拼接标签和置信度,
scores[i]:.2f是把置信度保留两位小数,让显示更整洁。
- 用f-string拼接标签和置信度,
- 文本属性控制:
font_size:控制文本的大小,数值越大文本越大;color:用RGB三元组设置文本颜色,比如(1,0,0)是红色,(1,1,1)是白色;font:如果需要自定义字体样式,只需要填写字体文件的路径即可(比如系统字体或者自定义字体的ttf文件)。
- 兼容性处理:
- 只有当
labels和scores都存在时才添加文本,避免空值报错;同时调整了draw_scenes里调用draw_box的参数,确保scores传递正确。
- 只有当
这样修改后,你就可以在每个预测边界框的上方看到带置信度的标签文本,并且完全控制它的各种显示属性啦!
备注:内容来源于stack exchange,提问作者Abbas
相关产品推荐
相关产品推荐

