Esempio n. 1
0
    parser = argparse.ArgumentParser('Generate 2D bbox GroundTruth from frame-level instance segmentation annotation')
    parser.add_argument('--data_dir', type=str, default='/mnt/Data/Datasets/ScanNet_v2/scans/',
                        help='The path to annotations')
    parser.add_argument('--frame_skip', type=int, default=15,
                        help='the number of frames to skip in extracting instance annotation images')
    parser.add_argument('--scene_name', type=str, default=None, help='specific scene name to process')
    parser.add_argument('--min_ratio', type=int, default=10, help='The minimum ratio between the object dimension '
                                                                  'and the image dimension to filter objects')
    parser.add_argument('--to_visu', type=bool, default=True, help='Visualize 2D bboxes')
    parser.add_argument('--to_save', type=bool, default=True, help='Save the 2D bbox into files..')

    opt = parser.parse_args()

    # map original class name into nyu40 class ids, and extract 18 target classes
    LABEL_MAP_FILE = '/mnt/Data/Datasets/ScanNet_v2/scannetv2-labels.combined.tsv'
    LABEL_MAP = scannet_utils.read_label_mapping(LABEL_MAP_FILE, label_from='raw_category', label_to='nyu40class')
    TARGET_CLASS_NAMES = cfg.SCANNET.CLASSES

    if opt.scene_name is None:
        SCAN_NAMES = [line.rstrip() for line in open('/mnt/Data/Datasets/ScanNet_v1/sceneid_sort.txt')]
    else:
        SCAN_NAMES = [opt.scene_name]

    for scan_id, scan_name in enumerate(SCAN_NAMES):
        print('====== Process {0}-th scan [{1}] ======'.format(scan_id, scan_name))
        scan_path = os.path.join(opt.data_dir, scan_name)

        if not os.path.exists(os.path.join(scan_path, 'instance-filt')): unzip_instace_file(scan_path, scan_name)
        objectID2label, colour_code = get_objectID2label_and_color(scan_path, scan_name)

        frame_names = os.listdir(os.path.join(scan_path, 'color'))
Esempio n. 2
0
def collect_point_data(scene_name):
    # read label mapping file
    label_map = scannet_utils.read_label_mapping(opt.label_map_file,
                                                 label_from='raw_category',
                                                 label_to='nyu40id')

    # Over-segmented segments: maps from segment to vertex/point IDs
    data_folder = os.path.join(opt.scannet_path, scene_name)
    # Read segmentation label
    seg_filename = os.path.join(
        data_folder, '%s_vh_clean_2.0.010000.segs.json' % (scene_name))
    seg_to_verts, num_verts = scannet_utils.read_segmentation(seg_filename)
    # Read Instances segmentation label
    agg_filename = os.path.join(data_folder,
                                '%s.aggregation.json' % (scene_name))
    object_id_to_segs, label_to_segs = scannet_utils.read_aggregation(
        agg_filename)
    # Raw points in XYZRGBA
    ply_filename = os.path.join(data_folder,
                                '%s_vh_clean_2.ply' % (scene_name))
    #points = pc_util.read_ply_rgba(ply_filename)
    points = pc_utils.read_ply_rgba_normal(ply_filename)

    label_ids = np.zeros(shape=(num_verts), dtype=np.uint32)  # 0: unannotated
    for label, segs in label_to_segs.items():
        # convert scannet raw label to nyu40 label (1~40), 0 for unannotated, 41 for unknown
        label_id = label_map[label]

        # only evaluate 20 class in nyu40 label
        # map nyu40 to 1~21, 0 for unannotated, unknown and not evalutated
        if label_id in g_label_ids:  # IDS for 20 classes in nyu40 for evaluation (1~21)
            eval_label_id = g_label_ids.index(label_id)
        else:  # IDS unannotated, unknow or not for evaluation go to unannotate label (0)
            eval_label_id = g_label_names.index('unannotate')
        for seg in segs:
            verts = seg_to_verts[seg]
            label_ids[verts] = eval_label_id
    #for i in range(20):
    #    print(label_ids[i])

    instance_ids = np.zeros(shape=(num_verts),
                            dtype=np.uint32)  # 0: unannotated
    for object_id, segs in object_id_to_segs.items():
        for seg in segs:
            verts = seg_to_verts[seg]
            instance_ids[verts] = object_id

    points = np.delete(points, 6, 1)  #  only RGB, ignoring A
    label_ids = np.expand_dims(label_ids, 1)
    instance_ids = np.expand_dims(instance_ids, 1)
    #print(points.shape, label_ids.shape, instance_ids.shape)
    # order is critical, do not change the order
    data = np.concatenate((points, instance_ids, label_ids), 1)
    #print(data.shape)
    #for i in range(20):
    #    print(data[i, 10])
    out_filename = os.path.join(data_folder, scene_name +
                                '.npy')  # scene0000_00/scene0000_00.npy
    np.save(out_filename, data)

    print(scene_name, ' points shape:', data.shape)
print(opt)
''' 
    tools for export and conver label 
'''
label_map = None
g_label_names = None
g_label_ids = None
if opt.export_label_images:
    try:
        sys.path.append('../utils')
        import scannet_utils
    except:
        print('Failed to import ScanNet code toolbox util')
        sys.exit(-1)
    label_map = scannet_utils.read_label_mapping(opt.label_map_file,
                                                 label_from='id',
                                                 label_to='nyu40id')
    g_label_names = scannet_utils.g_label_names
    g_label_ids = scannet_utils.g_label_ids
''' 
    tools for export .sens
'''
try:
    from SensorData import SensorData
except:
    print('Failed to import SensorData (from ScanNet code toolbox)')
    sys.exit(-1)


def print_error(message):
    sys.stderr.write('ERROR: ' + str(message) + '\n')
Esempio n. 4
0
def export(mesh_file,
           agg_file,
           seg_file,
           meta_file,
           label_map_file,
           output_file=None):
    """Export original files to vert, ins_label, sem_label and bbox file.

    Args:
        mesh_file (str): Path of the mesh_file.
        agg_file (str): Path of the agg_file.
        seg_file (str): Path of the seg_file.
        meta_file (str): Path of the meta_file.
        label_map_file (str): Path of the label_map_file.
        output_file (str): Path of the output folder.
            Default: None.

    It returns a tuple, which containts the the following things:
        np.ndarray: Vertices of points data.
        np.ndarray: Indexes of label.
        np.ndarray: Indexes of instance.
        np.ndarray: Instance bboxes.
        dict: Map from object_id to label_id.
    """

    label_map = scannet_utils.read_label_mapping(label_map_file,
                                                 label_from='raw_category',
                                                 label_to='nyu40id')
    mesh_vertices = scannet_utils.read_mesh_vertices_rgb(mesh_file)

    # Load scene axis alignment matrix
    lines = open(meta_file).readlines()
    for line in lines:
        if 'axisAlignment' in line:
            axis_align_matrix = [
                float(x)
                for x in line.rstrip().strip('axisAlignment = ').split(' ')
            ]
            break
    axis_align_matrix = np.array(axis_align_matrix).reshape((4, 4))
    pts = np.ones((mesh_vertices.shape[0], 4))
    pts[:, 0:3] = mesh_vertices[:, 0:3]
    pts = np.dot(pts, axis_align_matrix.transpose())  # Nx4
    mesh_vertices[:, 0:3] = pts[:, 0:3]

    # Load semantic and instance labels
    object_id_to_segs, label_to_segs = read_aggregation(agg_file)
    seg_to_verts, num_verts = read_segmentation(seg_file)
    label_ids = np.zeros(shape=(num_verts), dtype=np.uint32)
    object_id_to_label_id = {}
    for label, segs in label_to_segs.items():
        label_id = label_map[label]
        for seg in segs:
            verts = seg_to_verts[seg]
            label_ids[verts] = label_id
    instance_ids = np.zeros(shape=(num_verts),
                            dtype=np.uint32)  # 0: unannotated
    num_instances = len(np.unique(list(object_id_to_segs.keys())))
    for object_id, segs in object_id_to_segs.items():
        for seg in segs:
            verts = seg_to_verts[seg]
            instance_ids[verts] = object_id
            if object_id not in object_id_to_label_id:
                object_id_to_label_id[object_id] = label_ids[verts][0]
    instance_bboxes = np.zeros((num_instances, 7))
    for obj_id in object_id_to_segs:
        label_id = object_id_to_label_id[obj_id]
        obj_pc = mesh_vertices[instance_ids == obj_id, 0:3]
        if len(obj_pc) == 0:
            continue
        xmin = np.min(obj_pc[:, 0])
        ymin = np.min(obj_pc[:, 1])
        zmin = np.min(obj_pc[:, 2])
        xmax = np.max(obj_pc[:, 0])
        ymax = np.max(obj_pc[:, 1])
        zmax = np.max(obj_pc[:, 2])
        bbox = np.array([(xmin + xmax) / 2, (ymin + ymax) / 2,
                         (zmin + zmax) / 2, xmax - xmin, ymax - ymin,
                         zmax - zmin, label_id])
        # NOTE: this assumes obj_id is in 1,2,3,.,,,.NUM_INSTANCES
        instance_bboxes[obj_id - 1, :] = bbox

    if output_file is not None:
        np.save(output_file + '_vert.npy', mesh_vertices)
        np.save(output_file + '_sem_label.npy', label_ids)
        np.save(output_file + '_ins_label.npy', instance_ids)
        np.save(output_file + '_bbox.npy', instance_bboxes)

    return mesh_vertices, label_ids, instance_ids,\
        instance_bboxes, object_id_to_label_id
Esempio n. 5
0
def main(opt):

    def log_string(out_str):
        LOG_FOUT.write(out_str + '\n')
        LOG_FOUT.flush()
        print(out_str)

    def select_frames_for_one_scan(scan_path, objectID2label):
        # Round1: check invalid pose file (discard those frames contain inf) e.g., scene0067_02/pose/133.txx
        num_frames = len(os.listdir(os.path.join(scan_path, 'color')))
        selected_framenames_r1 = []
        for i in range(num_frames):
            if find_valid_pose(scan_path, i):
                selected_framenames_r1.append(i)
        log_string('\tAfter filtering invalid pose files, remain {0} [origin {1}] frames'.format(
                    len(selected_framenames_r1), num_frames))

        # Round2: check the 2D segmentation annotation (discard those frames without target classes)
        selected_framenames_r2 = []
        for frame_name in selected_framenames_r1:
            if find_valid_objects(scan_path, frame_name, objectID2label, LABEL_MAP, TARGET_CLASS_NAMES):
                selected_framenames_r2.append(frame_name)
        log_string('\tAfter filtering frames without the interested objects, remain {0} [origin {1}] frames'.format(
                       len(selected_framenames_r2), len(selected_framenames_r1)))

        # Round3: check the camera rotation angle between two consecutive frames
        # (discard those frames with small view change)
        selected_framenames_r3 = find_valid_rotation_angle(selected_framenames_r2, scan_path,
                                                           opt.min_angle, opt.visu_validRot)
        log_string('\tAfter filtering frames with small viewpoint change, remain {0} [origin {1}] frames'.format(
                    len(selected_framenames_r3), len(selected_framenames_r2)))

        return selected_framenames_r3

    LOG_FOUT = open(os.path.join(opt.data_dir, 'log_process_data.txt'), 'w')
    LOG_FOUT.write(str(opt) + '\n')

    # map original class name into nyu40 class ids, and extract target classes
    LABEL_MAP_FILE = os.path.join(opt.data_dir, 'scannetv2-labels.combined.tsv')
    LABEL_MAP = scannet_utils.read_label_mapping(LABEL_MAP_FILE, label_from='raw_category', label_to='nyu40class')
    TARGET_CLASS_NAMES = cfg.SCANNET.CLASSES

    if opt.scene_name is None:
        SCAN_NAMES = [line.rstrip() for line in open('/mnt/Data/Datasets/ScanNet_v1/sceneid_sort.txt')]
        # import random
        # random.shuffle(SCAN_NAMES)
    else:
        SCAN_NAMES = [opt.scene_name]

    valid_scannames = []
    for scan_id, scan_name in enumerate(SCAN_NAMES):
        log_string('\n====== Process {0}-th scan [{1}] ======'.format(scan_id, scan_name))
        scan_path = os.path.join(opt.data_dir, 'scans', scan_name)

        if not os.path.exists(os.path.join(scan_path, 'instance-filt')): unzip_instace_file(scan_path, scan_name)
        objectID2label, colour_code = get_objectID2label_and_color(scan_path, scan_name)

        sel_framenames = select_frames_for_one_scan(scan_path, objectID2label)

        if len(sel_framenames) >= opt.min_frames:
            # During 2D bboxes extraction, the boxes whose dimension ratio to the image dimension is less than
            # min_ratio will be removed. This may lead to invalid without bbox..
            valid_framenames = extract_bbox2d_for_one_scan(scan_path, scan_name, sel_framenames, objectID2label,
                                                           LABEL_MAP, TARGET_CLASS_NAMES, colour_code,
                                                           opt.min_ratio, opt.visu_box2d, opt.save_box2d)
            log_string('\tAfter filtering objects by checking its dimension ratio to the image dimension, '
                                 'remain {0} [origin {1}] frames'.format(len(valid_framenames), len(sel_framenames)))
            if len(valid_framenames) > opt.min_frames:
                valid_scannames.append(scan_name)

    log_string('=======================================================')
    log_string('{0} scans are kept after processing...'.format(len(valid_scannames)))
    # save the valid scans..
    with open(os.path.join(opt.data_dir, 'sceneid_valid.txt'), 'w') as f:
        for scanname in valid_scannames:
            f.write('%s\n' %scanname)

    LOG_FOUT.close()
Esempio n. 6
0
def export(mesh_file,
           agg_file,
           seg_file,
           meta_file,
           label_map_file,
           output_file=None):
    """ points are XYZ RGB (RGB in 0-255),
    semantic label as nyu40 ids,
    instance label as 1-#instance,
    box as (cx,cy,cz,dx,dy,dz,semantic_label)
    """
    label_map = scannet_utils.read_label_mapping(label_map_file,
                                                 label_from='raw_category',
                                                 label_to='nyu40id')
    # mesh_vertices = scannet_utils.read_mesh_vertices_rgb(mesh_file)
    mesh_vertices = scannet_utils.read_mesh_vertices_rgb_normal(mesh_file)

    # Load scene axis alignment matrix
    lines = open(meta_file).readlines()
    axis_align_matrix = None
    for line in lines:
        if 'axisAlignment' in line:
            axis_align_matrix = [
                float(x)
                for x in line.rstrip().strip('axisAlignment = ').split(' ')
            ]

    if axis_align_matrix != None:
        axis_align_matrix = np.array(axis_align_matrix).reshape((4, 4))
        pts = np.ones((mesh_vertices.shape[0], 4))
        pts[:, 0:3] = mesh_vertices[:, 0:3]
        pts = np.dot(pts, axis_align_matrix.transpose())  # Nx4
        aligned_vertices = np.copy(mesh_vertices)
        aligned_vertices[:, 0:3] = pts[:, 0:3]
    else:
        print("No axis alignment matrix found")
        aligned_vertices = mesh_vertices

    # Load semantic and instance labels
    if os.path.isfile(agg_file):
        object_id_to_segs, label_to_segs = read_aggregation(agg_file)
        seg_to_verts, num_verts = read_segmentation(seg_file)

        label_ids = np.zeros(shape=(num_verts),
                             dtype=np.uint32)  # 0: unannotated
        object_id_to_label_id = {}
        for label, segs in label_to_segs.items():
            label_id = label_map[label]
            for seg in segs:
                verts = seg_to_verts[seg]
                label_ids[verts] = label_id
        instance_ids = np.zeros(shape=(num_verts),
                                dtype=np.uint32)  # 0: unannotated
        num_instances = len(np.unique(list(object_id_to_segs.keys())))
        for object_id, segs in object_id_to_segs.items():
            for seg in segs:
                verts = seg_to_verts[seg]
                instance_ids[verts] = object_id
                if object_id not in object_id_to_label_id:
                    object_id_to_label_id[object_id] = label_ids[verts][0]

        instance_bboxes = np.zeros(
            (num_instances, 8))  # also include object id
        aligned_instance_bboxes = np.zeros(
            (num_instances, 8))  # also include object id
        for obj_id in object_id_to_segs:
            label_id = object_id_to_label_id[obj_id]

            # bboxes in the original meshes
            obj_pc = mesh_vertices[instance_ids == obj_id, 0:3]
            if len(obj_pc) == 0: continue
            # Compute axis aligned box
            # An axis aligned bounding box is parameterized by
            # (cx,cy,cz) and (dx,dy,dz) and label id
            # where (cx,cy,cz) is the center point of the box,
            # dx is the x-axis length of the box.
            xmin = np.min(obj_pc[:, 0])
            ymin = np.min(obj_pc[:, 1])
            zmin = np.min(obj_pc[:, 2])
            xmax = np.max(obj_pc[:, 0])
            ymax = np.max(obj_pc[:, 1])
            zmax = np.max(obj_pc[:, 2])
            bbox = np.array([(xmin + xmax) / 2, (ymin + ymax) / 2,
                             (zmin + zmax) / 2, xmax - xmin, ymax - ymin,
                             zmax - zmin, label_id,
                             obj_id - 1])  # also include object id
            # NOTE: this assumes obj_id is in 1,2,3,.,,,.NUM_INSTANCES
            instance_bboxes[obj_id - 1, :] = bbox

            # bboxes in the aligned meshes
            obj_pc = aligned_vertices[instance_ids == obj_id, 0:3]
            if len(obj_pc) == 0: continue
            # Compute axis aligned box
            # An axis aligned bounding box is parameterized by
            # (cx,cy,cz) and (dx,dy,dz) and label id
            # where (cx,cy,cz) is the center point of the box,
            # dx is the x-axis length of the box.
            xmin = np.min(obj_pc[:, 0])
            ymin = np.min(obj_pc[:, 1])
            zmin = np.min(obj_pc[:, 2])
            xmax = np.max(obj_pc[:, 0])
            ymax = np.max(obj_pc[:, 1])
            zmax = np.max(obj_pc[:, 2])
            bbox = np.array([(xmin + xmax) / 2, (ymin + ymax) / 2,
                             (zmin + zmax) / 2, xmax - xmin, ymax - ymin,
                             zmax - zmin, label_id,
                             obj_id - 1])  # also include object id
            # NOTE: this assumes obj_id is in 1,2,3,.,,,.NUM_INSTANCES
            aligned_instance_bboxes[obj_id - 1, :] = bbox
    else:
        # use zero as placeholders for the test scene
        print("use placeholders")
        num_verts = mesh_vertices.shape[0]
        label_ids = np.zeros(shape=(num_verts),
                             dtype=np.uint32)  # 0: unannotated
        instance_ids = np.zeros(shape=(num_verts),
                                dtype=np.uint32)  # 0: unannotated
        instance_bboxes = np.zeros((1, 8))  # also include object id
        aligned_instance_bboxes = np.zeros((1, 8))  # also include object id

    if output_file is not None:
        np.save(output_file + '_vert.npy', mesh_vertices)
        np.save(output_file + '_aligned_vert.npy', aligned_vertices)
        np.save(output_file + '_sem_label.npy', label_ids)
        np.save(output_file + '_ins_label.npy', instance_ids)
        np.save(output_file + '_bbox.npy', instance_bboxes)
        np.save(output_file + '_aligned_bbox.npy', instance_bboxes)

    return mesh_vertices, aligned_vertices, label_ids, instance_ids, instance_bboxes, aligned_instance_bboxes
def export(mesh_file,
           agg_file,
           seg_file,
           meta_file,
           label_map_file,
           output_file=None,
           test_mode=False):
    """Export original files to vert, ins_label, sem_label and bbox file.

    Args:
        mesh_file (str): Path of the mesh_file.
        agg_file (str): Path of the agg_file.
        seg_file (str): Path of the seg_file.
        meta_file (str): Path of the meta_file.
        label_map_file (str): Path of the label_map_file.
        output_file (str): Path of the output folder.
            Default: None.
        test_mode (bool): Whether is generating test data without labels.
            Default: False.

    It returns a tuple, which containts the the following things:
        np.ndarray: Vertices of points data.
        np.ndarray: Indexes of label.
        np.ndarray: Indexes of instance.
        np.ndarray: Instance bboxes.
        dict: Map from object_id to label_id.
    """

    label_map = scannet_utils.read_label_mapping(label_map_file,
                                                 label_from='raw_category',
                                                 label_to='nyu40id')
    mesh_vertices = scannet_utils.read_mesh_vertices_rgb(mesh_file)

    # Load scene axis alignment matrix
    lines = open(meta_file).readlines()
    # test set data doesn't have align_matrix
    axis_align_matrix = np.eye(4)
    for line in lines:
        if 'axisAlignment' in line:
            axis_align_matrix = [
                float(x)
                for x in line.rstrip().strip('axisAlignment = ').split(' ')
            ]
            break
    axis_align_matrix = np.array(axis_align_matrix).reshape((4, 4))

    # perform global alignment of mesh vertices
    pts = np.ones((mesh_vertices.shape[0], 4))
    pts[:, 0:3] = mesh_vertices[:, 0:3]
    pts = np.dot(pts, axis_align_matrix.transpose())  # Nx4
    aligned_mesh_vertices = np.concatenate([pts[:, 0:3], mesh_vertices[:, 3:]],
                                           axis=1)

    # Load semantic and instance labels
    if not test_mode:
        object_id_to_segs, label_to_segs = read_aggregation(agg_file)
        seg_to_verts, num_verts = read_segmentation(seg_file)
        label_ids = np.zeros(shape=(num_verts), dtype=np.uint32)
        object_id_to_label_id = {}
        for label, segs in label_to_segs.items():
            label_id = label_map[label]
            for seg in segs:
                verts = seg_to_verts[seg]
                label_ids[verts] = label_id
        instance_ids = np.zeros(shape=(num_verts),
                                dtype=np.uint32)  # 0: unannotated
        for object_id, segs in object_id_to_segs.items():
            for seg in segs:
                verts = seg_to_verts[seg]
                instance_ids[verts] = object_id
                if object_id not in object_id_to_label_id:
                    object_id_to_label_id[object_id] = label_ids[verts][0]
        unaligned_bboxes = extract_bbox(mesh_vertices, object_id_to_segs,
                                        object_id_to_label_id, instance_ids)
        aligned_bboxes = extract_bbox(aligned_mesh_vertices, object_id_to_segs,
                                      object_id_to_label_id, instance_ids)
    else:
        label_ids = None
        instance_ids = None
        unaligned_bboxes = None
        aligned_bboxes = None
        object_id_to_label_id = None

    if output_file is not None:
        np.save(output_file + '_vert.npy', mesh_vertices)
        if not test_mode:
            np.save(output_file + '_sem_label.npy', label_ids)
            np.save(output_file + '_ins_label.npy', instance_ids)
            np.save(output_file + '_unaligned_bbox.npy', unaligned_bboxes)
            np.save(output_file + '_aligned_bbox.npy', aligned_bboxes)
            np.save(output_file + '_axis_align_matrix.npy', axis_align_matrix)

    return mesh_vertices, label_ids, instance_ids, unaligned_bboxes, \
        aligned_bboxes, object_id_to_label_id, axis_align_matrix