def parse_MVS_colmap_file(mvs_colmap_ifp, file_name_to_camera_id, with_nxnynz=True, n_th_point=1): """ :param mvs_colmap_ifp: :return: """ logger.info('parse_MVS_colmap_file: ...') logger.vinfo('mvs_colmap_ifp', mvs_colmap_ifp) logger.vinfo('n_th_point', n_th_point) camera_index_to_current_feature_index = defaultdict(int) points = [] with open(mvs_colmap_ifp, 'r') as input_file: remaining_content = input_file.readlines() remaining_content = [x.strip() for x in remaining_content] # first line is a comment remaining_content = remaining_content[1:] # skipp 1 line dense_index_to_image_name = dict() num_dense_images = int(remaining_content[0]) remaining_content = remaining_content[1:] # skipp 1 line for index in range(num_dense_images): dense_index_and_image_name = remaining_content[index].split() assert len(dense_index_and_image_name) == 2 dense_index_to_image_name[int(dense_index_and_image_name[0])] = \ dense_index_and_image_name[1] remaining_content = remaining_content[ num_dense_images:] # skipp lines #logger.info(dense_index_to_image_name) # next 3 lines are comments #logger.info(remaining_content[0]) #logger.info(remaining_content[1]) #logger.info(remaining_content[2]) remaining_content = remaining_content[3:] dense_index_to_camera_index = {} if file_name_to_camera_id is not None: for dense_index, image_name in dense_index_to_image_name.items( ): camera_id = file_name_to_camera_id[image_name] dense_index_to_camera_index[dense_index] = camera_id #logger.info(dense_index_to_camera_index) # DENSE_IMAGE_ID != CAMERA_ID and DENSE_IMAGE_ID != IMAGE_ID # POINT3D_ID, X, Y, Z, NX, NY, NZ, R, G, B, TRACK[] as (DENSE_IMAGE_ID, DENSE_COL, DENSE_ROW) remaining_content = remaining_content[::n_th_point] num_points = len(remaining_content) for index, point_line in enumerate(remaining_content): if index % 100000 == 0: logger.pinfo(index, num_points) point_line_elements = (point_line.rstrip()).split() current_point = Point() # Adjust the point_3d id w.r.t n_th_point point_3d_id = index # int(point_line_elements[0]) current_point.id = point_3d_id xyz_vec = list(map(float, point_line_elements[1:4])) current_point.set_coord(xyz_vec) if with_nxnynz: nxnynz_vec = list(map(float, point_line_elements[4:7])) current_point.set_normal(nxnynz_vec) rgb_vec = list(map(int, point_line_elements[7:10])) current_point.set_color(rgb_vec) img_id_col_row_triples_as_str = point_line_elements[10:] else: rgb_vec = list(map(int, point_line_elements[4:7])) current_point.set_color(rgb_vec) img_id_col_row_triples_as_str = point_line_elements[7:] assert len(img_id_col_row_triples_as_str) % 3 == 0 dense_image_ids = list( map(int, img_id_col_row_triples_as_str[0::3])) cols = list(map(float, img_id_col_row_triples_as_str[1::3])) rows = list(map(float, img_id_col_row_triples_as_str[2::3])) measurements = [] # for dense_image_id, col, row in zip(dense_image_ids, cols, rows): if file_name_to_camera_id is not None: camera_id = dense_index_to_camera_index[dense_image_id] else: camera_id = dense_image_id measurement = Measurement( camera_index=camera_id, # Adding None here would create parsing problems feature_index=camera_index_to_current_feature_index[ camera_id], x=col, y=row, x_y_are_image_coords=True) measurements.append(measurement) camera_index_to_current_feature_index[camera_id] += 1 current_point.measurements = measurements points.append(current_point) # Detect bad point ids point_ids = [point.id for point in points] assert len(list(set(point_ids))) == len(point_ids) # Compute REAL 2D image coordinates (the one of colmap are probably not correct) #cameras_background logger.info('parse_MVS_colmap_file: Done') return points
def parse_points(json_data, image_index_to_camera_index, path_to_input_files=None, view_index_to_file_name=None): compute_color = (not path_to_input_files is None) and (not view_index_to_file_name is None) structure = json_data['structure'] if compute_color: logger.info('Computing color information from files: ...') view_index_to_image = {} for view_index, file_name in view_index_to_file_name.items(): image_path = os.path.join(path_to_input_files, file_name) pil_image = Image.open(image_path) view_index_to_image[view_index] = pil_image logger.info('Computing color information from files: Done') logger.vinfo('view_index_to_image.keys()', view_index_to_image.keys()) points = [] for json_point in structure: custom_point = Point() position = json_point['value']['X'] custom_point.set_coord(np.array(position)) custom_point.id = int(json_point['key']) custom_point.measurements = [] r = g = b = 0 # color information can only be computed if input files are provided if compute_color: for observation in json_point['value']['observations']: view_index = int(observation['key']) # REMARK: The order of ndarray.shape (first height, then width) is complimentary to # pils image.size (first width, then height). # That means # height, width = segmentation_as_matrix.shape # width, height = image.size # Therefore: x_in_openmvg_file == x_image == y_ndarray # and y_in_openmvg_file == y_image == x_ndarray x_in_json_file = float(observation['value']['x'][0]) # x has index 0 y_in_json_file = float(observation['value']['x'][1]) # y has index 1 current_image = view_index_to_image[view_index] current_r, current_g, current_b = current_image.getpixel((x_in_json_file, y_in_json_file)) r += current_r g += current_g b += current_b # Measurements is a list of < Measurement > # < Measurement > = < Image index > < Feature Index > < xy > custom_point.measurements.append( Measurement( camera_index= image_index_to_camera_index[view_index], feature_index=int(observation['value']['id_feat']), x=x_in_json_file, y=y_in_json_file, x_y_are_image_coords=True)) # normalize the rgb values amount_observations = len(json_point['value']['observations']) r /= amount_observations g /= amount_observations b /= amount_observations custom_point.set_color(np.array([r, g, b], dtype=int)) points.append(custom_point) return points