HF-Net(三)基于NetVLAD及superpoint构建的sfm场景模型的查询图像位姿解算

本文介绍了一种结合NetVLAD全局描述符和SuperPoint局部描述符进行图像定位的方法,详细展示了如何在Aachen数据集上进行特征提取、位姿解算及评估流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:HF-Net git地址

0.数据准备

0.1NetVLAD预训练权重,存放在编译hfnet后生成的$DATA_PATH/weights/路径下

0.2aachen数据下载,存放在编译hfnet后生成的$DATA_PATH/路径下

0.3基于superpoint生成的aachen三维点云场景

0.4aachen数据对应的每张图像相机内参文件

1.基于NetVLAD生成aachen所有图像的global descriptors

参考HF-Net(一)基于NetVLAD的global descriptor的特征提取

2.基于superpoint的local descriptors生成

2.1执行代码

#对底库图像的superpoint特征提取
python3 hfnet/export_predictions.py hfnet/configs/superpoint_export_aachen_db.yaml superpoint/aachen --keys keypoints,scores,local_descriptor_map
#对查询图像的superpoint特征提取
python3 hfnet/export_predictions.py hfnet/configs/superpoint_export_aachen_queries.yaml superpoint/aachen --keys keypoints,scores,local_descriptor_map

2.2结果生成
在这里插入图片描述

3.基于NetVLAD及superpoint构建的sfm场景模型的查询图像位姿解算

3.1核心代码

import logging
from pathlib import Path
import argparse
from pprint import pformat
import yaml
import numpy as np
from pyquaternion import Quaternion

from hfnet.evaluation.localization import Localization, evaluate
from hfnet.evaluation.loaders import export_loader
from hfnet.settings import EXPER_PATH


configs_global = {
    'netvlad': {
        'db_name': 'globaldb_netvlad.pkl',
        'experiment': 'netvlad/aachen',
        'predictor': export_loader,
        'has_keypoints': False,
        'has_descriptors': False,
        'pca_dim': 1024,
        'num_prior': 10,
    },
    'hfnet': {
        'db_name': 'globaldb_hfnet.pkl',
        'experiment':  'hfnet/aachen',
        'predictor': export_loader,
        'has_keypoints': False,
        'has_descriptors': False,
        'pca_dim': 1024,
        'num_prior': 10,
    },
}

configs_local = {
    'superpoint': {
        'db_name': 'localdb_superpoint.pkl',
        'experiment': 'superpoint/aachen',
        'predictor': export_loader,
        'has_keypoints': True,
        'has_descriptors': True,
        'binarize': False,
        # 'do_nms': True,
        # 'nms_thresh': 4,
        'num_features': 2000,
        'ratio_thresh': 0.9,
    },
    'hfnet': {
        'db_name': 'localdb_hfnet.pkl',
        'experiment':  'hfnet/aachen',
        'predictor': export_loader,
        'has_keypoints': True,
        'has_descriptors': True,
        # 'do_nms': True,
        # 'nms_thresh': 4,
        'num_features': 2000,
        'ratio_thresh': 0.9,
    },
    'sift': {
        'db_name': 'localdb_sift.pkl',
        'colmap_db': 'aachen.db',
        'root': False,
        'ratio_thresh': 0.7,
        'fast_matching': False,
    },
    'doap': {
        'db_name': 'localdb_doap_kpts-sp-nms4.pkl',
        'experiment': 'doap/aachen_resize-960',
        'predictor': export_loader,
        'keypoint_predictor': export_loader,
        'keypoint_config': {
            'experiment': 'superpoint/aachen',
            # 'do_nms': True,
            # 'nms_thresh': 4,
        },
        'num_features': 2000,
        'ratio_thresh': 0.9,
    },
    'netvlad': {
        'db_name': 'localdb_netvlad_kpts-sp-nms4.pkl',
        'experiment': 'netvlad/aachen',
        'predictor': export_loader,
        'keypoint_predictor': export_loader,
        'keypoint_config': {
            'experiment': 'superpoint/aachen',
            # 'do_nms': True,
            # 'nms_thresh': 4,
        },
        'num_features': 1000,
        'ratio_thresh': 0.7,
    }
}

config_pose = {
    'reproj_error': 10,
    'min_inliers': 12,
}

config_aachen = {
    'resize_max': 960,
}


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('model', type=str)
    parser.add_argument('eval_name', type=str)
    parser.add_argument('--local_method', type=str)
    parser.add_argument('--global_method', type=str)
    parser.add_argument('--build_db', action='store_true')
    parser.add_argument('--queries', type=str, default='day_time')
    parser.add_argument('--max_iter', type=int)
    parser.add_argument('--export_poses', action='store_true')
    parser.add_argument('--cpp_backend', action='store_true')
    args = parser.parse_args()

    config = {
        'global': configs_global[args.global_method],
        'local': configs_local[args.local_method],
        'aachen': config_aachen,
        'pose': config_pose,
        'model': args.model,
        'max_iter': args.max_iter,
        'queries': args.queries,
        'use_cpp': args.cpp_backend,
    }
    logging.info(f'Configuration: \n'+pformat(config))

    logging.info('Evaluating Aachen with configuration: ')
    loc = Localization('aachen', args.model, config, build_db=args.build_db)

    query_file = f'{args.queries}_queries_with_intrinsics.txt'
    queries, query_dataset = loc.init_queries(query_file, config_aachen)

    logging.info('Starting evaluation')
    metrics, results = evaluate(
        loc, queries, query_dataset, max_iter=args.max_iter)
    logging.info('Evaluation metrics: \n'+pformat(metrics))

    output = {'config': config, 'metrics': metrics}
    output_dir = Path(EXPER_PATH, 'eval/aachen')
    output_dir.mkdir(exist_ok=True, parents=True)
    eval_path = Path(output_dir, f'{args.eval_name}.yaml')
    with open(eval_path, 'w') as f:
        yaml.dump(output, f, default_flow_style=False)

    if args.export_poses:
        poses_path = Path(output_dir, f'{args.eval_name}_poses.txt')
        with open(poses_path, 'w') as f:
            for query, result in zip(queries, results):
                query_T_w = np.linalg.inv(result.T)
                qvec_nvm = list(Quaternion(matrix=query_T_w))
                pos_nvm = query_T_w[:3, 3].tolist()
                line = f'{Path(query.name).name}'
                line += ' ' + ' '.join(map(str, qvec_nvm+pos_nvm))
                f.write(line+'\n')

3.2执行代码

python3 hfnet/evaluate_aachen.py /path/superpoint_sfm /DATA_PATH/aachen/images_upright/query/night/milestone --local_method superpoint --global_method netvlad --build_db --queries night_time --export_poses 

3.3执行结果
求解的位姿
在这里插入图片描述

在这里插入图片描述

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值