Transformers 文档

SuperGlue

Hugging Face's logo
加入 Hugging Face 社区

并获取增强的文档体验

开始使用

SuperGlue

PyTorch

概述

SuperGlue 模型由 Paul-Edouard Sarlin、Daniel DeTone、Tomasz Malisiewicz 和 Andrew Rabinovich 在 SuperGlue: Learning Feature Matching with Graph Neural Networks 中提出。

此模型包括匹配在图像中检测到的两组兴趣点。与 SuperPoint 模型 配对使用时,它可以用于匹配两张图像并估计它们之间的姿势。此模型对于图像匹配、单应性估计等任务非常有用。

论文摘要如下:

本文介绍了 SuperGlue,这是一个神经网络,它通过共同查找对应关系和拒绝不可匹配的点来匹配两组局部特征。通过解决可微分的最优传输问题来估计分配,其成本由图神经网络预测。我们引入了一种基于注意力的灵活上下文聚合机制,使 SuperGlue 能够共同推理潜在的 3D 场景和特征分配。与传统的手工设计的启发式方法相比,我们的技术通过图像对的端到端训练,学习了 3D 世界的几何变换和规律性的先验知识。SuperGlue 优于其他学习方法,并在具有挑战性的真实世界室内和室外环境中的姿势估计任务中取得了最先进的结果。所提出的方法在现代 GPU 上实时执行匹配,并且可以轻松集成到现代 SfM 或 SLAM 系统中。代码和训练权重在此 URL 公开提供。

如何使用

这是一个使用该模型的快速示例。由于此模型是图像匹配模型,因此需要成对的图像进行匹配。原始输出包含关键点检测器检测到的关键点列表以及匹配项列表及其相应的匹配分数。

from transformers import AutoImageProcessor, AutoModel
import torch
from PIL import Image
import requests

url_image1 = "https://raw.githubusercontent.com/magicleap/SuperGluePretrainedNetwork/refs/heads/master/assets/phototourism_sample_images/united_states_capitol_98169888_3347710852.jpg"
image1 = Image.open(requests.get(url_image1, stream=True).raw)
url_image2 = "https://raw.githubusercontent.com/magicleap/SuperGluePretrainedNetwork/refs/heads/master/assets/phototourism_sample_images/united_states_capitol_26757027_6717084061.jpg"
image_2 = Image.open(requests.get(url_image2, stream=True).raw)

images = [image1, image2]

processor = AutoImageProcessor.from_pretrained("magic-leap-community/superglue_outdoor")
model = AutoModel.from_pretrained("magic-leap-community/superglue_outdoor")

inputs = processor(images, return_tensors="pt")
with torch.no_grad():
    outputs = model(**inputs)

您可以使用 SuperGlueImageProcessor 中的 post_process_keypoint_matching 方法以更易读的格式获取关键点和匹配项

image_sizes = [[(image.height, image.width) for image in images]]
outputs = processor.post_process_keypoint_matching(outputs, image_sizes, threshold=0.2)
for i, output in enumerate(outputs):
    print("For the image pair", i)
    for keypoint0, keypoint1, matching_score in zip(
            output["keypoints0"], output["keypoints1"], output["matching_scores"]
    ):
        print(
            f"Keypoint at coordinate {keypoint0.numpy()} in the first image matches with keypoint at coordinate {keypoint1.numpy()} in the second image with a score of {matching_score}."
        )

从输出中,您可以使用以下代码可视化两张图像之间的匹配项

import matplotlib.pyplot as plt
import numpy as np

# Create side by side image
merged_image = np.zeros((max(image1.height, image2.height), image1.width + image2.width, 3))
merged_image[: image1.height, : image1.width] = np.array(image1) / 255.0
merged_image[: image2.height, image1.width :] = np.array(image2) / 255.0
plt.imshow(merged_image)
plt.axis("off")

# Retrieve the keypoints and matches
output = outputs[0]
keypoints0 = output["keypoints0"]
keypoints1 = output["keypoints1"]
matching_scores = output["matching_scores"]
keypoints0_x, keypoints0_y = keypoints0[:, 0].numpy(), keypoints0[:, 1].numpy()
keypoints1_x, keypoints1_y = keypoints1[:, 0].numpy(), keypoints1[:, 1].numpy()

# Plot the matches
for keypoint0_x, keypoint0_y, keypoint1_x, keypoint1_y, matching_score in zip(
        keypoints0_x, keypoints0_y, keypoints1_x, keypoints1_y, matching_scores
):
    plt.plot(
        [keypoint0_x, keypoint1_x + image1.width],
        [keypoint0_y, keypoint1_y],
        color=plt.get_cmap("RdYlGn")(matching_score.item()),
        alpha=0.9,
        linewidth=0.5,
    )
    plt.scatter(keypoint0_x, keypoint0_y, c="black", s=2)
    plt.scatter(keypoint1_x + image1.width, keypoint1_y, c="black", s=2)

# Save the plot
plt.savefig("matched_image.png", dpi=300, bbox_inches='tight')
plt.close()

image/png

此模型由 stevenbucaille 贡献。原始代码可以在这里找到。

SuperGlueConfig

class transformers.SuperGlueConfig

< >

( keypoint_detector_config: SuperPointConfig = None hidden_size: int = 256 keypoint_encoder_sizes: typing.List[int] = None gnn_layers_types: typing.List[str] = None num_attention_heads: int = 4 sinkhorn_iterations: int = 100 matching_threshold: float = 0.0 initializer_range: float = 0.02 **kwargs )

参数

  • keypoint_detector_config (Union[AutoConfig, dict], 可选, 默认为 SuperPointConfig) — 关键点检测器的配置对象或字典。
  • hidden_size (int, 可选, 默认为 256) — 描述符的维度。
  • keypoint_encoder_sizes (List[int], 可选, 默认为 [32, 64, 128, 256]) — 关键点编码器层的大小。
  • gnn_layers_types (List[str], 可选, 默认为 ['self', 'cross', 'self', 'cross', 'self', 'cross', 'self', 'cross', 'self', 'cross', 'self', 'cross', 'self', 'cross', 'self', 'cross', 'self', 'cross']) — GNN 层的类型。 必须为 ‘self’ 或 ‘cross’。
  • num_attention_heads (int, 可选, 默认为 4) — GNN 层中头的数量。
  • sinkhorn_iterations (int, 可选, 默认为 100) — Sinkhorn 迭代的次数。
  • matching_threshold (float, 可选, 默认为 0.0) — 匹配阈值。
  • initializer_range (float, 可选, 默认为 0.02) — 用于初始化所有权重矩阵的截断正态初始化器的标准差。

这是用于存储 SuperGlueModel 配置的配置类。 它用于根据指定的参数实例化 SuperGlue 模型,定义模型架构。 使用默认值实例化配置将产生与 SuperGlue magic-leap-community/superglue_indoor 架构类似的配置。

配置对象继承自 PretrainedConfig,可用于控制模型输出。 有关更多信息,请阅读 PretrainedConfig 的文档。

示例

>>> from transformers import SuperGlueConfig, SuperGlueModel

>>> # Initializing a SuperGlue superglue style configuration
>>> configuration = SuperGlueConfig()

>>> # Initializing a model from the superglue style configuration
>>> model = SuperGlueModel(configuration)

>>> # Accessing the model configuration
>>> configuration = model.config

SuperGlueImageProcessor

class transformers.SuperGlueImageProcessor

< >

( do_resize: bool = True size: typing.Dict[str, int] = None resample: Resampling = <Resampling.BILINEAR: 2> do_rescale: bool = True rescale_factor: float = 0.00392156862745098 do_grayscale: bool = True **kwargs )

参数

  • do_resize (bool, 可选, 默认为 True) — 控制是否将图像的(高度,宽度)尺寸调整为指定的 size。 可以通过 preprocess 方法中的 do_resize 覆盖。
  • size (Dict[str, int] 可选, 默认为 {"height" -- 480, "width": 640}): 应用 resize 后输出图像的分辨率。 仅当 do_resize 设置为 True 时才有效。 可以通过 preprocess 方法中的 size 覆盖。
  • resample (PILImageResampling, 可选, 默认为 Resampling.BILINEAR) — 如果调整图像大小,则使用的重采样过滤器。 可以通过 preprocess 方法中的 resample 覆盖。
  • do_rescale (bool, 可选, 默认为 True) — 是否通过指定的比例 rescale_factor 重新缩放图像。 可以通过 preprocess 方法中的 do_rescale 覆盖。
  • rescale_factor (intfloat, 可选, 默认为 1/255) — 如果重新缩放图像,则使用的比例因子。 可以通过 preprocess 方法中的 rescale_factor 覆盖。
  • do_grayscale (bool, 可选, 默认为 True) — 是否将图像转换为灰度。 可以通过 preprocess 方法中的 do_grayscale 覆盖。

构建 SuperGlue 图像处理器。

post_process_keypoint_matching

< >

( outputs: KeypointMatchingOutput target_sizes: typing.Union[transformers.utils.generic.TensorType, typing.List[typing.Tuple]] threshold: float = 0.0 ) List[Dict]

参数

  • outputs (KeypointMatchingOutput) — 模型的原始输出。
  • target_sizes (torch.TensorList[Tuple[Tuple[int, int]]], 可选) — 形状为 (batch_size, 2, 2) 的张量或元组列表,其中元组又包含元组 (Tuple[int, int]),表示批次中每个图像的目标大小 (height, width)。 这必须是原始图像大小(在任何处理之前)。
  • threshold (float, 可选, 默认为 0.0) — 用于过滤掉低分匹配项的阈值。

返回

List[Dict]

字典列表,每个字典包含图像对中第一张和第二张图像中的关键点、匹配分数和匹配索引。

KeypointMatchingOutput 的原始输出转换为关键点、分数和描述符列表,其坐标相对于原始图像大小是绝对的。

preprocess

< >

( images do_resize: bool = None size: typing.Dict[str, int] = None resample: Resampling = None do_rescale: bool = None rescale_factor: float = None do_grayscale: bool = None return_tensors: typing.Union[str, transformers.utils.generic.TensorType, NoneType] = None data_format: ChannelDimension = <ChannelDimension.FIRST: 'channels_first'> input_data_format: typing.Union[str, transformers.image_utils.ChannelDimension, NoneType] = None **kwargs )

参数

  • images (ImageInput) — 要预处理的图像对。 期望是 2 张图像的列表,或者是像素值范围为 0 到 255 的 2 张图像列表的列表。 如果传入像素值在 0 到 1 之间的图像,请设置 do_rescale=False
  • do_resize (bool, 可选, 默认为 self.do_resize) — 是否调整图像大小。
  • size (Dict[str, int], 可选, 默认为 self.size) — 应用 resize 后输出图像的大小。 如果 size["shortest_edge"] >= 384,则图像将被调整为 (size["shortest_edge"], size["shortest_edge"])。 否则,图像的较小边缘将与 int(size["shortest_edge"]/ crop_pct) 匹配,之后图像将被裁剪为 (size["shortest_edge"], size["shortest_edge"])。 仅当 do_resize 设置为 True 时才有效。
  • resample (PILImageResampling, 可选, 默认为 self.resample) — 如果调整图像大小,则使用的重采样过滤器。 这可以是 PILImageResampling 之一,即过滤器。 仅当 do_resize 设置为 True 时才有效。
  • do_rescale (bool, 可选, 默认为 self.do_rescale) — 是否将图像值重新缩放到 [0 - 1] 之间。
  • rescale_factor (float, 可选, 默认为 self.rescale_factor) — 如果 do_rescale 设置为 True,则用于重新缩放图像的比例因子。
  • do_grayscale (bool, 可选, 默认为 self.do_grayscale) — 是否将图像转换为灰度。
  • return_tensors (strTensorType, 可选) — 要返回的张量类型。 可以是以下之一:
    • Unset:返回 np.ndarray 列表。
    • TensorType.TENSORFLOW'tf':返回 tf.Tensor 类型的批次。
    • TensorType.PYTORCH'pt':返回 torch.Tensor 类型的批次。
    • TensorType.NUMPY'np':返回 np.ndarray 类型的批次。
    • TensorType.JAX'jax':返回 jax.numpy.ndarray 类型的批次。
  • data_format (ChannelDimensionstr, 可选, 默认为 ChannelDimension.FIRST) — 输出图像的通道维度格式。 可以是以下之一:
    • "channels_first"ChannelDimension.FIRST:图像格式为 (num_channels, height, width)。
    • "channels_last"ChannelDimension.LAST:图像格式为 (height, width, num_channels)。
    • Unset:使用输入图像的通道维度格式。
  • input_data_format (ChannelDimensionstr, 可选) — 输入图像的通道维度格式。 如果未设置,则通道维度格式从输入图像推断。 可以是以下之一:
    • "channels_first"ChannelDimension.FIRST:图像格式为 (num_channels, height, width)。
    • "channels_last"ChannelDimension.LAST:图像格式为 (height, width, num_channels)。
    • "none"ChannelDimension.NONE:图像格式为 (height, width)。

预处理一张或一批图像。

resize

< >

( image: ndarray size: typing.Dict[str, int] data_format: typing.Union[str, transformers.image_utils.ChannelDimension, NoneType] = None input_data_format: typing.Union[str, transformers.image_utils.ChannelDimension, NoneType] = None **kwargs )

参数

  • image (np.ndarray) — 要调整大小的图像。
  • size (Dict[str, int]) — 字典形式为 {"height": int, "width": int},指定输出图像的大小。
  • data_format (ChannelDimensionstr, 可选) — 输出图像的通道维度格式。如果未提供,将从输入图像中推断。可以是以下之一:
    • "channels_first"ChannelDimension.FIRST: 图像格式为 (num_channels, height, width)。
    • "channels_last"ChannelDimension.LAST: 图像格式为 (height, width, num_channels)。
    • "none"ChannelDimension.NONE: 图像格式为 (height, width)。
  • input_data_format (ChannelDimensionstr, 可选) — 输入图像的通道维度格式。如果未设置,则从输入图像中推断通道维度格式。可以是以下之一:
    • "channels_first"ChannelDimension.FIRST: 图像格式为 (num_channels, height, width)。
    • "channels_last"ChannelDimension.LAST: 图像格式为 (height, width, num_channels)。
    • "none"ChannelDimension.NONE: 图像格式为 (height, width)。

调整图像大小。

  • preprocess

SuperGlueForKeypointMatching

class transformers.SuperGlueForKeypointMatching

< >

( config: SuperGlueConfig )

参数

  • config (SuperGlueConfig) — 带有模型所有参数的模型配置类。使用配置文件初始化不会加载与模型关联的权重,仅加载配置。查看 from_pretrained() 方法来加载模型权重。

SuperGlue 模型将图像作为输入并输出它们的匹配结果。此模型是 PyTorch torch.nn.Module 子类。将其用作常规 PyTorch 模块,并参考 PyTorch 文档以了解所有与常规用法和行为相关的事项。

SuperGlue 特征匹配中间层

给定两组关键点和位置,我们通过以下方式确定对应关系

  1. 关键点编码(归一化 + 视觉特征和位置融合)
  2. 具有多个自注意力和交叉注意力层的图神经网络
  3. 最终投影层
  4. 最优传输层(可微分的匈牙利匹配算法)
  5. 基于互斥性和 match_threshold 的阈值矩阵

对应 ID 使用 -1 表示非匹配点。

Paul-Edouard Sarlin, Daniel DeTone, Tomasz Malisiewicz, and Andrew Rabinovich. SuperGlue: Learning Feature Matching with Graph Neural Networks. In CVPR, 2020. https://arxiv.org/abs/1911.11763

forward

< >

( pixel_values: FloatTensor labels: typing.Optional[torch.LongTensor] = None output_attentions: typing.Optional[bool] = None output_hidden_states: typing.Optional[bool] = None return_dict: typing.Optional[bool] = None )

参数

  • pixel_values (torch.FloatTensor, 形状为 (batch_size, num_channels, height, width)) — 像素值。像素值可以使用 SuperGlueImageProcessor 获得。 有关详细信息,请参阅 SuperGlueImageProcessor.call()
  • output_attentions (bool, 可选) — 是否返回 attention 张量。 有关更多详细信息,请参见返回张量下的 attentions
  • output_hidden_states (bool, 可选) — 是否返回所有层的隐藏状态。 有关更多详细信息,请参见返回张量下的 hidden_states
  • return_dict (bool, 可选) — 是否返回 ModelOutput 而不是普通元组。
  • 示例
  • ```python

    from transformers import AutoImageProcessor, AutoModel import torch from PIL import Image import requests

SuperGlueForKeypointMatching 的 forward 方法覆盖了 __call__ 特殊方法。

尽管 forward 传递的步骤需要在该函数中定义,但应该在之后调用 Module 实例而不是此函数,因为前者负责运行预处理和后处理步骤,而后者会默默地忽略它们。

  • forward
  • post_process_keypoint_matching
< > 更新 在 GitHub 上