Transformers 文档
SuperGlue
并获取增强的文档体验
开始使用
SuperGlue
概述
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()
此模型由 stevenbucaille 贡献。原始代码可以在这里找到。
SuperGlueConfig
class transformers.SuperGlueConfig
< source >( 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
< source >( 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 (
int
或float
, 可选, 默认为1/255
) — 如果重新缩放图像,则使用的比例因子。 可以通过preprocess
方法中的rescale_factor
覆盖。 - do_grayscale (
bool
, 可选, 默认为True
) — 是否将图像转换为灰度。 可以通过preprocess
方法中的do_grayscale
覆盖。
构建 SuperGlue 图像处理器。
post_process_keypoint_matching
< source >( 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.Tensor
或List[Tuple[Tuple[int, int]]]
, 可选) — 形状为(batch_size, 2, 2)
的张量或元组列表,其中元组又包含元组 (Tuple[int, int]
),表示批次中每个图像的目标大小(height, width)
。 这必须是原始图像大小(在任何处理之前)。 - threshold (
float
, 可选, 默认为 0.0) — 用于过滤掉低分匹配项的阈值。
返回
List[Dict]
字典列表,每个字典包含图像对中第一张和第二张图像中的关键点、匹配分数和匹配索引。
将 KeypointMatchingOutput
的原始输出转换为关键点、分数和描述符列表,其坐标相对于原始图像大小是绝对的。
preprocess
< source >( 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 (
str
或TensorType
, 可选) — 要返回的张量类型。 可以是以下之一:- Unset:返回
np.ndarray
列表。 TensorType.TENSORFLOW
或'tf'
:返回tf.Tensor
类型的批次。TensorType.PYTORCH
或'pt'
:返回torch.Tensor
类型的批次。TensorType.NUMPY
或'np'
:返回np.ndarray
类型的批次。TensorType.JAX
或'jax'
:返回jax.numpy.ndarray
类型的批次。
- Unset:返回
- data_format (
ChannelDimension
或str
, 可选, 默认为ChannelDimension.FIRST
) — 输出图像的通道维度格式。 可以是以下之一:"channels_first"
或ChannelDimension.FIRST
:图像格式为 (num_channels, height, width)。"channels_last"
或ChannelDimension.LAST
:图像格式为 (height, width, num_channels)。- Unset:使用输入图像的通道维度格式。
- input_data_format (
ChannelDimension
或str
, 可选) — 输入图像的通道维度格式。 如果未设置,则通道维度格式从输入图像推断。 可以是以下之一:"channels_first"
或ChannelDimension.FIRST
:图像格式为 (num_channels, height, width)。"channels_last"
或ChannelDimension.LAST
:图像格式为 (height, width, num_channels)。"none"
或ChannelDimension.NONE
:图像格式为 (height, width)。
预处理一张或一批图像。
resize
< source >( 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 (
ChannelDimension
或str
, 可选) — 输出图像的通道维度格式。如果未提供,将从输入图像中推断。可以是以下之一:"channels_first"
或ChannelDimension.FIRST
: 图像格式为 (num_channels, height, width)。"channels_last"
或ChannelDimension.LAST
: 图像格式为 (height, width, num_channels)。"none"
或ChannelDimension.NONE
: 图像格式为 (height, width)。
- input_data_format (
ChannelDimension
或str
, 可选) — 输入图像的通道维度格式。如果未设置,则从输入图像中推断通道维度格式。可以是以下之一:"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
< source >( config: SuperGlueConfig )
参数
- config (SuperGlueConfig) — 带有模型所有参数的模型配置类。使用配置文件初始化不会加载与模型关联的权重,仅加载配置。查看 from_pretrained() 方法来加载模型权重。
SuperGlue 模型将图像作为输入并输出它们的匹配结果。此模型是 PyTorch torch.nn.Module 子类。将其用作常规 PyTorch 模块,并参考 PyTorch 文档以了解所有与常规用法和行为相关的事项。
SuperGlue 特征匹配中间层
给定两组关键点和位置,我们通过以下方式确定对应关系
- 关键点编码(归一化 + 视觉特征和位置融合)
- 具有多个自注意力和交叉注意力层的图神经网络
- 最终投影层
- 最优传输层(可微分的匈牙利匹配算法)
- 基于互斥性和 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
< source >( 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