superpoint与superglue特征提取与特征匹配得到的h5数据存储格式[笔记]

1. 提取特征得到的数据结构

提取特征后的 .h5 文件是一种层次化的文件结构,典型的数据组织方式如下:

feats-superpoint-n4096-r1600.h5
│
├── image_001.png
│   ├── descriptors : (256, N) 特征描述符矩阵
│   ├── image_size  : (2,) 图像尺寸 (width, height)
│   ├── keypoints   : (N, 2) 关键点坐标 (x, y)
│   └── scores      : (N,) 每个关键点的分数
│
├── image_002.png
│   └── ...
│
└── ...
  • descriptors:二维数组,大小为 (256, N),其中 256 是描述符的长度(例如 SuperPoint 生成的描述符长度),N 是关键点的数量。每一列表示一个关键点的特征描述符。
  • image_size:包含图像的宽度和高度,便于后续处理时将图像缩放到合适的大小。
  • keypoints:二维数组,大小为 (N, 2),表示图像中每个关键点的坐标 (x, y)
  • scores:一维数组,大小为 (N,),每个元素表示关键点的重要性或可信度分数。

1.1 在代码中加载并使用特征

可以使用 h5py 库来加载 .h5 文件,提取出特定图像的特征信息:

import h5py
import numpy as np

# 加载特征文件
with h5py.File('feats-superpoint-n4096-r1600.h5', 'r') as h5_file:
    # 假设要处理 image_001.png 的特征
    image_name = 'image_001.png'
    
    # 获取关键点、描述符、分数和图像尺寸
    keypoints = h5_file[image_name]['keypoints'][:]
    descriptors = h5_file[image_name]['descriptors'][:]
    scores = h5_file[image_name]['scores'][:]
    image_size = h5_file[image_name]['image_size'][:]

    # 打印一些信息
    print(f"Keypoints shape: {keypoints.shape}")
    print(f"Descriptors shape: {descriptors.shape}")
    print(f"Scores shape: {scores.shape}")
    print(f"Image size: {image_size}")

通过这种方式,可以读取任意图像的特征数据并进行操作。接下来,可以根据需求将这些特征用于图像检索、匹配、定位或三维重建等任务。

2.共视图像对

共视图像是指在三维重建过程中,多个图像拍摄了同一个场景中的相同部分(即有较多的相同三维点被观测到)。共视图像对的选择通常基于以下步骤:

  • 计算共视关系:遍历所有图像对,计算它们之间的共视程度,即有多少三维点被这两个图像共同观测到。
  • 选择最具共视性的图像对:对于每张图像,根据计算出的共视程度,选择与其共视程度最高的 num_covis 个图像。
  • 成对保存:将每对共视程度最高的图像对存储到指定的输出文件中。

2.1生成的输出文件

输出文件(例如 pairs-db-covis20.txt)是一个文本文件,保存的是图像对的名称,每一行表示一个图像对,例如:

image_0.png image_64.png
image_0.png image_136.png
...
  • 结构:每行包含两个图像文件名,表示这两个图像之间有显著的共视关系。
  • 用途:这些图像对将用于后续的特征匹配、三角化或重建等任务。

2.2如何使用共视图像对

生成的共视图像对文件通常用于以下任务:

  • 特征匹配:在后续特征匹配时,可以只对这些共视图像对进行匹配,从而节省计算资源,提高匹配的准确性。
  • 三维重建:共视图像对中拍摄了相同的场景部分,因此可以通过这些图像对中的特征点进行三角化,生成三维点云。
  • 优化计算:通过限制匹配图像对的数量,可以显著减少后续计算量,避免对每张图像进行全图像集的匹配。

3.特征匹配信息的数据结构

feats-superpoint-n4096-r1600_matches-superglue_pairs-db-covis20.h5
│
├── image_001.png
│   ├── image_002.png
│   │   ├── matches0           : (N,) 每个关键点的匹配索引,N为关键点数
│   │   └── matching_scores0   : (N,) 每个匹配点的置信度分数
│   │
│   └── image_003.png
│       ├── matches0
│       └── matching_scores0
│
└── ...

matches0 的具体含义和结构

  • 结构matches0 是一个一维数组,其长度为第一个图像中特征点的数量(假设为 N)。
    • matches0[i] 表示第一个图像中第 i 个特征点在第二个图像中的匹配点的索引。
    • 如果 matches0[i] = -1,则表示第一个图像中的第 i 个特征点没有在第二个图像中找到匹配点(即无效匹配)。
    • 如果 matches0[i] >= 0,则表示第一个图像中的第 i 个特征点与第二个图像中 matches0[i] 索引位置的特征点匹配。

举个例子

假设第一个图像有 5 个特征点,matches0 的内容如下:

matches0 = [ 3, -1, 2, 0, -1 ]

在这个例子中:

  • matches0[0] = 3:表示第一个图像的第一个特征点与第二个图像的第 4 个特征点(索引 3)匹配。
  • matches0[1] = -1:表示第一个图像的第二个特征点在第二个图像中没有找到匹配点。
  • matches0[2] = 2:表示第一个图像的第三个特征点与第二个图像的第 3 个特征点(索引 2)匹配。
  • matches0[3] = 0:表示第一个图像的第四个特征点与第二个图像的第 1 个特征点(索引 0)匹配。
  • matches0[4] = -1:表示第一个图像的第五个特征点在第二个图像中没有找到匹配点。

3.1在代码中加载和处理匹配数据

以下是一个加载匹配数据的示例:
 

import h5py
import numpy as np

# 加载匹配文件
with h5py.File('feats-superpoint-n4096-r1600_matches-superglue_pairs-db-covis20.h5', 'r') as h5_file:
    # 选择图像对 image_001.png 和 image_002.png
    image_pair = h5_file['image_001.png/image_002.png']
    
    # 获取匹配索引和匹配分数
    matches = image_pair['matches0'][:]
    matching_scores = image_pair['matching_scores0'][:]
    
    # 过滤有效的匹配(索引为 -1 表示无匹配)
    valid_matches = matches != -1
    valid_indices = np.where(valid_matches)[0]
    
    # 输出有效匹配信息
    print(f"Valid matches count: {len(valid_indices)}")
    print(f"Matching indices: {matches[valid_indices]}")
    print(f"Matching scores: {matching_scores[valid_indices]}")

猜你喜欢

转载自blog.csdn.net/qq_45372239/article/details/142708500
今日推荐