示例#1
0
def property_reference(run_name="property_reference"):
    """Produces identical visualization to small_scale, but does not store
    repeated properties of ``vertex_positions`` and ``vertex_normals``.
    """
    logdir = os.path.join(BASE_LOGDIR, run_name)
    writer = SummaryWriter(logdir)

    cube = o3d.geometry.TriangleMesh.create_box(1, 2, 4)
    cube.compute_vertex_normals()
    cylinder = o3d.geometry.TriangleMesh.create_cylinder(radius=1.0,
                                                         height=2.0,
                                                         resolution=20,
                                                         split=4)
    cylinder.compute_vertex_normals()
    colors = [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)]
    for step in range(3):
        cube.paint_uniform_color(colors[step])
        cube_summary = to_dict_batch([cube])
        if step > 0:
            cube_summary['vertex_positions'] = 0
            cube_summary['vertex_normals'] = 0
        writer.add_3d('cube', cube_summary, step=step)
        cylinder.paint_uniform_color(colors[step])
        cylinder_summary = to_dict_batch([cylinder])
        if step > 0:
            cylinder_summary['vertex_positions'] = 0
            cylinder_summary['vertex_normals'] = 0
        writer.add_3d('cylinder', cylinder_summary, step=step)
def small_scale(run_name="small_scale"):
    """Basic demo with cube and cylinder with normals and colors.
    """
    logdir = os.path.join(BASE_LOGDIR, run_name)
    writer = tf.summary.create_file_writer(logdir)

    cube = o3d.geometry.TriangleMesh.create_box(1, 2, 4, create_uv_map=True)
    cube.compute_vertex_normals()
    cylinder = o3d.geometry.TriangleMesh.create_cylinder(radius=1.0,
                                                         height=2.0,
                                                         resolution=20,
                                                         split=4,
                                                         create_uv_map=True)
    cylinder.compute_vertex_normals()
    colors = [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)]
    with writer.as_default():
        for step in range(3):
            cube.paint_uniform_color(colors[step])
            summary.add_3d('cube',
                           to_dict_batch([cube]),
                           step=step,
                           logdir=logdir)
            cylinder.paint_uniform_color(colors[step])
            summary.add_3d('cylinder',
                           to_dict_batch([cylinder]),
                           step=step,
                           logdir=logdir)
def large_scale(n_steps=16,
                batch_size=1,
                base_resolution=200,
                run_name="large_scale"):
    """Generate a large scale summary. Geometry resolution increases linearly
    with step. Each element in a batch is painted a different color.
    """
    logdir = os.path.join(BASE_LOGDIR, run_name)
    writer = tf.summary.create_file_writer(logdir)
    colors = []
    for k in range(batch_size):
        t = k * np.pi / batch_size
        colors.append(((1 + np.sin(t)) / 2, (1 + np.cos(t)) / 2, t / np.pi))
    with writer.as_default():
        for step in range(n_steps):
            resolution = base_resolution * (step + 1)
            cylinder_list = []
            moebius_list = []
            cylinder = o3d.geometry.TriangleMesh.create_cylinder(
                radius=1.0, height=2.0, resolution=resolution, split=4)
            cylinder.compute_vertex_normals()
            moebius = o3d.geometry.TriangleMesh.create_moebius(
                length_split=int(3.5 * resolution),
                width_split=int(0.75 * resolution),
                twists=1,
                raidus=1,
                flatness=1,
                width=1,
                scale=1)
            moebius.compute_vertex_normals()
            for b in range(batch_size):
                cylinder_list.append(copy.deepcopy(cylinder))
                cylinder_list[b].paint_uniform_color(colors[b])
                moebius_list.append(copy.deepcopy(moebius))
                moebius_list[b].paint_uniform_color(colors[b])
            summary.add_3d('cylinder',
                           to_dict_batch(cylinder_list),
                           step=step,
                           logdir=logdir,
                           max_outputs=batch_size)
            summary.add_3d('moebius',
                           to_dict_batch(moebius_list),
                           step=step,
                           logdir=logdir,
                           max_outputs=batch_size)
def test_tensorflow_summary(geometry_data, tmp_path):
    """Test writing summary from TensorFlow
    """

    tf = pytest.importorskip("tensorflow")
    logdir = str(tmp_path)
    writer = tf.summary.create_file_writer(logdir)

    rng = np.random.default_rng()
    tensor_converter = (tf.convert_to_tensor, o3d.core.Tensor.from_numpy,
                        np.array)

    cube, material = geometry_data['cube'], geometry_data['material']
    cube_ls, material_ls = geometry_data['cube_ls'], geometry_data[
        'material_ls']
    colors = geometry_data['colors']
    max_outputs = geometry_data['max_outputs']
    with writer.as_default():
        for step in range(3):
            cube[0].paint_uniform_color(colors[step][0])
            cube[1].paint_uniform_color(colors[step][1])
            cube_summary = to_dict_batch(cube)
            cube_summary.update(material)
            # Randomly convert to TF, Open3D, Numpy tensors, or use property
            # reference
            if step > 0:
                cube_summary['vertex_positions'] = 0
                cube_summary['vertex_normals'] = 0
                cube_summary['vertex_colors'] = rng.choice(tensor_converter)(
                    cube_summary['vertex_colors'])
            else:
                for prop, tensor in cube_summary.items():
                    # skip material scalar and vector props
                    if (not prop.startswith("material_")
                            or prop.startswith("material_texture_map_")):
                        cube_summary[prop] = rng.choice(tensor_converter)(
                            tensor)
            summary.add_3d('cube',
                           cube_summary,
                           step=step,
                           logdir=logdir,
                           max_outputs=max_outputs)
            for key in tuple(cube_summary):  # Convert to PointCloud
                if key.startswith(('triangle_', 'material_texture_map_')):
                    cube_summary.pop(key)
            summary.add_3d('cube_pcd',
                           cube_summary,
                           step=step,
                           logdir=logdir,
                           max_outputs=max_outputs)
            cube_ls[0].paint_uniform_color(colors[step][0])
            cube_ls[1].paint_uniform_color(colors[step][1])
            cube_ls_summary = to_dict_batch(cube_ls)
            cube_ls_summary.update(material_ls)
            for prop, tensor in cube_ls_summary.items():
                if (not prop.startswith("material_")
                        or prop.startswith("material_texture_map_")):
                    cube_ls_summary[prop] = rng.choice(tensor_converter)(
                        tensor)
            summary.add_3d('cube_ls',
                           cube_ls_summary,
                           step=step,
                           logdir=logdir,
                           max_outputs=max_outputs)

    sleep(0.25)  # msgpack writing disk flush time
    dirpath_ref = [
        logdir,
        os.path.join(logdir, 'plugins'),
        os.path.join(logdir, 'plugins/Open3D')
    ]
    filenames_ref = [['events.out.tfevents.*'], [], ['cube.*.msgpack']]

    dirpath, filenames = [], []
    for dp, unused_dn, fn in os.walk(logdir):
        dirpath.append(dp)
        filenames.append(fn)

    assert (dirpath[:2] == dirpath_ref[:2]
            and dirpath[2][0][:20] == dirpath_ref[2][0][:20])
    assert filenames[0][0][:20] == filenames_ref[0][0][:20]
    assert set(x.split('.')[0] for x in filenames[2]) == set(
        ('cube', 'cube_pcd', 'cube_ls'))
    assert filenames_ref[2][0][-8:] == '.msgpack'

    # Note: The event file written during this test cannot be reliably verified
    # in the same Python process, since it's usually buffered by GFile / Python
    # / OS and written to disk in increments of the filesystem blocksize.
    # Complete write is guaranteed after Python has exited.
    shutil.rmtree(logdir)
示例#5
0
def test_pytorch_summary(geometry_data, tmp_path):
    """Test writing summary from PyTorch"""

    torch = pytest.importorskip("torch")
    torch_tb = pytest.importorskip("torch.utils.tensorboard")
    SummaryWriter = torch_tb.SummaryWriter
    logdir = str(tmp_path)
    writer = SummaryWriter(logdir)

    rng = np.random.default_rng()
    tensor_converter = (torch.from_numpy, o3d.core.Tensor.from_numpy, np.array)

    cube, material = geometry_data['cube'], geometry_data['material']
    cube_custom_prop = geometry_data['cube_custom_prop']
    cube_ls, material_ls = geometry_data['cube_ls'], geometry_data[
        'material_ls']
    colors = geometry_data['colors']
    cube_labels = geometry_data['cube_labels']
    label_to_names = geometry_data['label_to_names']
    max_outputs = geometry_data['max_outputs']
    bboxes = geometry_data['bboxes']
    for step in range(3):
        cube[0].paint_uniform_color(colors[step][0])
        cube[1].paint_uniform_color(colors[step][1])
        cube_summary = to_dict_batch(cube)
        cube_summary.update(material)
        # Randomly convert to PyTorch, Open3D, Numpy tensors, or use property
        # reference
        if step > 0:
            cube_summary['vertex_positions'] = 0
            cube_summary['vertex_normals'] = 0
            cube_summary['vertex_colors'] = rng.choice(tensor_converter)(
                cube_summary['vertex_colors'])
        else:
            for prop, tensor in cube_summary.items():
                # skip material scalar and vector props
                if (not prop.startswith("material_")
                        or prop.startswith("material_texture_map_")):
                    cube_summary[prop] = rng.choice(tensor_converter)(tensor)
        writer.add_3d('cube', cube_summary, step=step, max_outputs=max_outputs)
        for key in tuple(cube_summary):  # Convert to PointCloud
            if key.startswith(('triangle_', 'material_texture_map_')):
                cube_summary.pop(key)
        cube_summary['vertex_custom'] = tuple(
            rng.choice(tensor_converter)(tensor)
            for tensor in cube_custom_prop[step])  # Add custom prop
        cube_summary['vertex_labels'] = tuple(
            rng.choice(tensor_converter)(tensor)
            for tensor in cube_labels[step])  # Add labels
        writer.add_3d('cube_pcd',
                      cube_summary,
                      step=step,
                      max_outputs=max_outputs,
                      label_to_names=label_to_names)
        cube_ls[0].paint_uniform_color(colors[step][0])
        cube_ls[1].paint_uniform_color(colors[step][1])
        cube_ls_summary = to_dict_batch(cube_ls)
        cube_ls_summary.update(material_ls)
        for prop, tensor in cube_ls_summary.items():
            if (not prop.startswith("material_")
                    or prop.startswith("material_texture_map_")):
                cube_ls_summary[prop] = rng.choice(tensor_converter)(tensor)
        writer.add_3d('cube_ls',
                      cube_ls_summary,
                      step=step,
                      max_outputs=max_outputs)
        if len(bboxes) > 0:
            writer.add_3d('bboxes', {'bboxes': bboxes[step]},
                          step=step,
                          logdir=logdir,
                          max_outputs=max_outputs,
                          label_to_names=label_to_names)

    sleep(0.25)  # msgpack writing disk flush time

    tags_ref = geometry_data['tags']
    dirpath_ref = [
        logdir,
        os.path.join(logdir, 'plugins'),
        os.path.join(logdir, 'plugins/Open3D')
    ]
    filenames_ref = geometry_data['filenames']
    dirpath, filenames = [], []
    for dp, unused_dn, fn in os.walk(logdir):
        dirpath.append(dp)
        filenames.append(fn)

    assert dirpath == dirpath_ref
    assert filenames[0][0].startswith(filenames_ref[0][0][:20])
    assert sorted(x.split('.')[0] for x in filenames[2]) == tags_ref
    assert all(fn.endswith('.msgpack') for fn in filenames[2])

    # Note: The event file written during this test cannot be reliably verified
    # in the same Python process, since it's usually buffered by GFile / Python
    # / OS and written to disk in increments of the filesystem blocksize.
    # Complete write is guaranteed after Python has exited.
    shutil.rmtree(logdir)
示例#6
0
def test_pytorch_summary(geometry_data):
    """Test writing summary from PyTorch"""

    torch = pytest.importorskip("torch")
    torch_tb = pytest.importorskip("torch.utils.tensorboard")
    SummaryWriter = torch_tb.SummaryWriter
    logdir = tempfile.mkdtemp(prefix='open3d_tb_plugin_test')
    writer = SummaryWriter(logdir)

    rng = np.random
    tensor_converter = (torch.from_numpy, o3d.core.Tensor.from_numpy, np.array)

    cube = geometry_data['cube']
    cube_ls = geometry_data['cube_ls']
    colors = geometry_data['colors']
    max_outputs = geometry_data['max_outputs']
    for step in range(3):
        cube[0].paint_uniform_color(colors[step][0])
        cube[1].paint_uniform_color(colors[step][1])
        cube_summary = to_dict_batch(cube)
        # Randomly convert to PyTorch, Open3D, Numpy tensors, or use property
        # reference
        if step > 0:
            cube_summary['vertex_positions'] = 0
            cube_summary['vertex_normals'] = 0
            cube_summary['vertex_colors'] = rng.choice(tensor_converter)(
                cube_summary['vertex_colors'])
        else:
            for prop, tensor in cube_summary.items():
                cube_summary[prop] = rng.choice(tensor_converter)(tensor)
        writer.add_3d('cube', cube_summary, step=step, max_outputs=max_outputs)
        cube_summary.pop('triangle_indices')  # Convert to PointCloud
        writer.add_3d('cube_pcd',
                      cube_summary,
                      step=step,
                      max_outputs=max_outputs)
        cube_ls[0].paint_uniform_color(colors[step][0])
        cube_ls[1].paint_uniform_color(colors[step][1])
        cube_ls_summary = to_dict_batch(cube_ls)
        for prop, tensor in cube_ls_summary.items():
            cube_ls_summary[prop] = rng.choice(tensor_converter)(tensor)
        writer.add_3d('cube_ls',
                      cube_ls_summary,
                      step=step,
                      max_outputs=max_outputs)

    sleep(0.25)  # msgpack writing disk flush time
    dirpath_ref = [
        logdir,
        os.path.join(logdir, 'plugins'),
        os.path.join(logdir, 'plugins/Open3D')
    ]
    filenames_ref = [['events.out.tfevents.*'], [], ['cube.*.msgpack']]

    dirpath, filenames = [], []
    for dp, unused_dn, fn in os.walk(logdir):
        dirpath.append(dp)
        filenames.append(fn)

    assert (dirpath[:2] == dirpath_ref[:2] and
            dirpath[2][0][:20] == dirpath_ref[2][0][:20])
    assert filenames[0][0][:20] == filenames_ref[0][0][:20]
    assert set(x.split('.')[0] for x in filenames[2]) == set(
        ('cube', 'cube_pcd', 'cube_ls'))
    assert filenames_ref[2][0][-8:] == '.msgpack'

    # Note: The event file written during this test cannot be reliably verified
    # in the same Python process, since it's usually buffered by GFile / Python
    # / OS and written to disk in increments of the filesystem blocksize.
    # Complete write is guaranteed after Python has exited.
    shutil.rmtree(logdir)