def pairsfile_fusion(input_path: List[str], output_path: str,
                     topk: Optional[int], method: LateFusionMethod,
                     additional_parameters: dict):
    """
    fuse pairsfile scores and write a pairsfile with the fused scores
    """
    assert len(input_path) > 1

    logger.info(f'pairsfile_fusion. loading {input_path}')

    similarity_dicts: List[dict] = []
    for file_path in input_path:
        loaded_pairs = get_ordered_pairs_from_file(file_path)
        similarity_dicts.append(loaded_pairs)

    if method == LateFusionMethod.round_robin:
        image_pairs = round_robin_from_similarity_dicts(similarity_dicts, topk)
    else:
        pairs = {}
        for loaded_pairs in similarity_dicts:
            for query_name, pairlist in loaded_pairs.items():
                for map_name, score in pairlist:
                    pairtuple = (query_name, map_name)
                    if pairtuple not in pairs:
                        pairs[pairtuple] = []
                    pairs[pairtuple].append(score)

        # keep entries with correct count
        similarity_dict = {}
        for pairtuple, scores in pairs.items():
            (query_name, map_name) = pairtuple
            if len(scores) != len(similarity_dicts):
                logger.warning(
                    f'pair {pairtuple} did not have a line in all pairsfile, skipped'
                )
                continue
            scores_as_matrices = [
                np.array([[score]], dtype=np.float64) for score in scores
            ]
            final_score = fuse_similarities(scores_as_matrices, method,
                                            additional_parameters)[0, 0]
            if query_name not in similarity_dict:
                similarity_dict[query_name] = []
            similarity_dict[query_name].append((map_name, final_score))
        image_pairs = get_image_pairs(similarity_dict, topk)

    logger.info('saving to file ...')
    os.umask(0o002)
    p = pathlib.Path(output_path)
    os.makedirs(str(p.parent.resolve()), exist_ok=True)
    with open(output_path, 'w') as fid:
        table_to_file(fid,
                      image_pairs,
                      header='# query_image, map_image, score')
    logger.info('all done')
def _image_retrieval_late_fusion_from_loaded_data(
        input_path: str, map_tar_handlers: TarCollection,
        kdata_map: kapture.Kapture, query_path: str,
        query_tar_handlers: TarCollection, kdata_query: kapture.Kapture,
        global_features_types: List[str], output_path: str,
        topk: Optional[int], method: LateFusionMethod,
        additional_parameters: dict):
    image_list_map = [
        name for _, _, name in kapture.flatten(kdata_map.records_camera,
                                               is_sorted=True)
    ]
    image_list_query = [
        name for _, _, name in kapture.flatten(kdata_query.records_camera,
                                               is_sorted=True)
    ]

    if len(global_features_types) == 0:
        global_features_types = list(
            set(kdata_map.global_features.keys()).intersection(
                kdata_query.global_features.keys()))

    similarity_matrices = []
    stacked_query_index = None
    stacked_map_index = None

    for global_features_type in global_features_types:
        if global_features_type not in kdata_map.global_features:
            logger.warning(
                f'could not use {global_features_type}, it was missing in kdata_map'
            )
            continue
        if global_features_type not in kdata_query.global_features:
            logger.warning(
                f'could not use {global_features_type}, it was missing in kdata_query'
            )
            continue
        mapping_gfeats = kdata_map.global_features[global_features_type]
        query_gfeats = kdata_query.global_features[global_features_type]
        assert mapping_gfeats.dtype == query_gfeats.dtype
        assert mapping_gfeats.dsize == query_gfeats.dsize
        assert mapping_gfeats.metric_type == query_gfeats.metric_type

        global_features_config = GlobalFeaturesConfig(
            mapping_gfeats.type_name, mapping_gfeats.dtype,
            mapping_gfeats.dsize, mapping_gfeats.metric_type)

        # force the same order for all global features
        mapping_global_features_to_filepaths = [
            (image_filename,
             get_features_fullpath(kapture.GlobalFeatures,
                                   global_features_type, input_path,
                                   image_filename, map_tar_handlers))
            for image_filename in image_list_map
        ]
        mapping_stacked_features = stack_global_features(
            global_features_config, mapping_global_features_to_filepaths)

        if input_path == query_path:
            query_stacked_features = mapping_stacked_features
        else:
            query_global_features_to_filepaths = [
                (image_filename,
                 get_features_fullpath(kapture.GlobalFeatures,
                                       global_features_type, query_path,
                                       image_filename, query_tar_handlers))
                for image_filename in image_list_query
            ]
            query_stacked_features = stack_global_features(
                global_features_config, query_global_features_to_filepaths)

        # additional step to really make sure the order or the matrix is the same, and to remember it
        if stacked_map_index is None:
            stacked_map_index = mapping_stacked_features.index
        else:
            assert stacked_map_index.tolist(
            ) == mapping_stacked_features.index.tolist()

        if stacked_query_index is None:
            stacked_query_index = query_stacked_features.index
        else:
            assert stacked_query_index.tolist(
            ) == query_stacked_features.index.tolist()

        similarity_matrices.append(
            get_similarity_matrix(query_stacked_features,
                                  mapping_stacked_features))

    if method == LateFusionMethod.round_robin:
        logger.info('Compute fused similarity from round_robin')
        similarity_dicts = [
            get_similarity_dict_from_similarity_matrix(similarity,
                                                       stacked_query_index,
                                                       stacked_map_index)
            for similarity in similarity_matrices
        ]
        image_pairs = round_robin_from_similarity_dicts(similarity_dicts, topk)
    else:
        logger.info(f'Compute fused similarity from {method.value} ...')
        similarity = fuse_similarities(similarity_matrices, method,
                                       additional_parameters)
        similarity_dict = get_similarity_dict_from_similarity_matrix(
            similarity, stacked_query_index, stacked_map_index)
        image_pairs = get_image_pairs(similarity_dict, topk)

    logger.info('saving to file ...')
    os.umask(0o002)
    p = pathlib.Path(output_path)
    os.makedirs(str(p.parent.resolve()), exist_ok=True)
    with open(output_path, 'w') as fid:
        table_to_file(fid,
                      image_pairs,
                      header='# query_image, map_image, score')
    logger.info('all done')
def compute_image_pairs(mapping_path: str,
                        query_path: str,
                        output_path: str,
                        topk: int):
    """
    compute image pairs between query -> mapping from global features, and write the result in a text file

    :param mapping_path: input path to kapture input root directory
    :type mapping_path: str
    :param query_path: input path to a kapture root directory
    :type query_path: str
    :param output_path: output path to pairsfile
    :type output_path: str
    :param topk: the max number of top retained images
    :type topk: int
    """
    logger.info(f'compute_image_pairs. loading mapping: {mapping_path}')
    kdata_mapping = kapture_from_dir(mapping_path, None, skip_list=[kapture.Keypoints,
                                                                    kapture.Descriptors,
                                                                    kapture.Matches,
                                                                    kapture.Observations,
                                                                    kapture.Points3d])
    assert kdata_mapping.sensors is not None
    assert kdata_mapping.records_camera is not None
    assert kdata_mapping.global_features is not None

    if mapping_path == query_path:
        kdata_query = kdata_mapping
    else:
        logger.info(f'compute_image_pairs. loading query: {query_path}')
        kdata_query = kapture_from_dir(query_path, None, skip_list=[kapture.Keypoints,
                                                                    kapture.Descriptors,
                                                                    kapture.Matches,
                                                                    kapture.Observations,
                                                                    kapture.Points3d])
        assert kdata_query.sensors is not None
        assert kdata_query.records_camera is not None
        assert kdata_query.global_features is not None

    assert kdata_mapping.global_features is not None
    assert kdata_query.global_features is not None
    assert kdata_mapping.global_features.type_name == kdata_query.global_features.type_name
    assert kdata_mapping.global_features.dtype == kdata_query.global_features.dtype
    assert kdata_mapping.global_features.dsize == kdata_query.global_features.dsize
    global_features_config = ImageFeatureConfig(kdata_mapping.global_features.type_name,
                                                kdata_mapping.global_features.dtype,
                                                kdata_mapping.global_features.dsize)

    logger.info(f'computing pairs from with {kdata_mapping.global_features.type_name}...')

    mapping_global_features_to_filepaths = global_features_to_filepaths(kdata_mapping.global_features,
                                                                        mapping_path)
    mapping_list = list(kapture.flatten(mapping_global_features_to_filepaths, is_sorted=True))
    mapping_stacked_features = stack_global_features(global_features_config, mapping_list)

    if mapping_path == query_path:
        query_stacked_features = mapping_stacked_features
    else:
        query_global_features_to_filepaths = global_features_to_filepaths(kdata_query.global_features,
                                                                          query_path)
        query_list = list(kapture.flatten(query_global_features_to_filepaths, is_sorted=True))
        query_stacked_features = stack_global_features(global_features_config, query_list)

    similarity = get_similarity(query_stacked_features, mapping_stacked_features)

    # get list of image pairs
    image_pairs = get_image_pairs(similarity, topk)

    logger.info('saving to file  ...')
    p = pathlib.Path(output_path)
    os.makedirs(str(p.parent.resolve()), exist_ok=True)
    with open(output_path, 'w') as fid:
        table_to_file(fid, image_pairs, header='# query_image, map_image, score')
    logger.info('all done')
Beispiel #4
0
def compute_image_pairs(mapping_path: str, query_path: str, output_path: str,
                        global_features_type: Optional[str], topk: int):
    """
    compute image pairs between query -> mapping from global features, and write the result in a text file

    :param mapping_path: input path to kapture input root directory
    :type mapping_path: str
    :param query_path: input path to a kapture root directory
    :type query_path: str
    :param output_path: output path to pairsfile
    :type output_path: str
    :param global_features_type: type of global_features, name of the global_features subfolder
    :param topk: the max number of top retained images
    :type topk: int
    """
    logger.info(f'compute_image_pairs. loading mapping: {mapping_path}')
    with get_all_tar_handlers(mapping_path) as mapping_tar_handlers:
        kdata_mapping = kapture_from_dir(mapping_path,
                                         None,
                                         skip_list=[
                                             kapture.Keypoints,
                                             kapture.Descriptors,
                                             kapture.Matches,
                                             kapture.Observations,
                                             kapture.Points3d
                                         ],
                                         tar_handlers=mapping_tar_handlers)
        assert kdata_mapping.sensors is not None
        assert kdata_mapping.records_camera is not None
        assert kdata_mapping.global_features is not None
        if global_features_type is None:
            global_features_type = try_get_only_key_from_collection(
                kdata_mapping.global_features)
        assert global_features_type is not None
        assert global_features_type in kdata_mapping.global_features

        global_features_config = GlobalFeaturesConfig(
            kdata_mapping.global_features[global_features_type].type_name,
            kdata_mapping.global_features[global_features_type].dtype,
            kdata_mapping.global_features[global_features_type].dsize,
            kdata_mapping.global_features[global_features_type].metric_type)

        logger.info(f'computing pairs with {global_features_type}...')

        mapping_global_features_to_filepaths = global_features_to_filepaths(
            kdata_mapping.global_features[global_features_type],
            global_features_type, mapping_path, mapping_tar_handlers)
        mapping_list = list(
            sorted(mapping_global_features_to_filepaths.items()))
        mapping_stacked_features = stack_global_features(
            global_features_config, mapping_list)

    if mapping_path == query_path:
        kdata_query = kdata_mapping
        query_stacked_features = mapping_stacked_features
    else:
        logger.info(f'compute_image_pairs. loading query: {query_path}')
        with get_all_tar_handlers(query_path) as query_tar_handlers:
            kdata_query = kapture_from_dir(query_path,
                                           None,
                                           skip_list=[
                                               kapture.Keypoints,
                                               kapture.Descriptors,
                                               kapture.Matches,
                                               kapture.Observations,
                                               kapture.Points3d
                                           ],
                                           tar_handlers=query_tar_handlers)
            assert kdata_query.sensors is not None
            assert kdata_query.records_camera is not None
            assert kdata_query.global_features is not None
            assert global_features_type in kdata_query.global_features

            kdata_mapping_gfeat = kdata_mapping.global_features[
                global_features_type]
            kdata_query_gfeat = kdata_query.global_features[
                global_features_type]
            assert kdata_mapping_gfeat.type_name == kdata_query_gfeat.type_name
            assert kdata_mapping_gfeat.dtype == kdata_query_gfeat.dtype
            assert kdata_mapping_gfeat.dsize == kdata_query_gfeat.dsize

            query_global_features_to_filepaths = global_features_to_filepaths(
                kdata_query_gfeat, global_features_type, query_path,
                query_tar_handlers)
            query_list = list(
                sorted(query_global_features_to_filepaths.items()))
            query_stacked_features = stack_global_features(
                global_features_config, query_list)

    similarity = get_similarity(query_stacked_features,
                                mapping_stacked_features)

    # get list of image pairs
    image_pairs = get_image_pairs(similarity, topk)

    logger.info('saving to file  ...')
    p = pathlib.Path(output_path)
    os.makedirs(str(p.parent.resolve()), exist_ok=True)
    with open(output_path, 'w') as fid:
        table_to_file(fid,
                      image_pairs,
                      header='# query_image, map_image, score')
    logger.info('all done')