Matching#
Descriptor matching#
- kornia.feature.match_nn(desc1, desc2, dm=None)[source]#
Find nearest neighbors in desc2 for each vector in desc1.
If the distance matrix dm is not provided,
torch.cdist()is used.- Parameters:
- Return type:
- Returns:
Descriptor distance of matching descriptors, shape of \((B1, 1)\).
Long torch.Tensor indexes of matching descriptors in desc1 and desc2, shape of \((B1, 2)\).
- kornia.feature.match_mnn(desc1, desc2, dm=None)[source]#
Find mutual nearest neighbors in desc2 for each vector in desc1.
If the distance matrix dm is not provided,
torch.cdist()is used.- Parameters:
- Return type:
- Returns:
Descriptor distance of matching descriptors, shape of. \((B3, 1)\).
Long torch.Tensor indexes of matching descriptors in desc1 and desc2, shape of \((B3, 2)\), where 0 <= B3 <= min(B1, B2)
- kornia.feature.match_snn(desc1, desc2, th=0.8, dm=None)[source]#
Find nearest neighbors in desc2 for each vector in desc1.
The method satisfies first to second nearest neighbor distance <= th.
If the distance matrix dm is not provided,
torch.cdist()is used.- Parameters:
desc1 (
Tensor) – Batch of descriptors of a shape \((B1, D)\).desc2 (
Tensor) – Batch of descriptors of a shape \((B2, D)\).th (
float, optional) – distance ratio threshold. Default:0.8dm (
Optional[Tensor], optional) – torch.Tensor containing the distances from each descriptor in desc1 to each descriptor in desc2, shape of \((B1, B2)\). Default:None
- Return type:
- Returns:
Descriptor distance of matching descriptors, shape of \((B3, 1)\).
Long torch.Tensor indexes of matching descriptors in desc1 and desc2. Shape: \((B3, 2)\), where 0 <= B3 <= B1.
- kornia.feature.match_smnn(desc1, desc2, th=0.95, dm=None)[source]#
Find mutual nearest neighbors in desc2 for each vector in desc1.
the method satisfies first to second nearest neighbor distance <= th.
If the distance matrix dm is not provided,
torch.cdist()is used.- Parameters:
desc1 (
Tensor) – Batch of descriptors of a shape \((B1, D)\).desc2 (
Tensor) – Batch of descriptors of a shape \((B2, D)\).th (
float, optional) – distance ratio threshold. Default:0.95dm (
Optional[Tensor], optional) – torch.Tensor containing the distances from each descriptor in desc1 to each descriptor in desc2, shape of \((B1, B2)\). Default:None
- Return type:
- Returns:
Descriptor distance of matching descriptors, shape of. \((B3, 1)\).
Long torch.Tensor indexes of matching descriptors in desc1 and desc2, shape of \((B3, 2)\) where 0 <= B3 <= B1.
- kornia.feature.match_fginn(desc1, desc2, lafs1, lafs2, th=0.8, spatial_th=10.0, mutual=False, dm=None)[source]#
Find nearest neighbors in desc2 for each vector in desc1.
The method satisfies first to second nearest neighbor distance <= th, and assures 2nd nearest neighbor is geometrically inconsistent with the 1st one (see [MMP15] for more details)
If the distance matrix dm is not provided,
torch.cdist()is used.Note
The geometric check looks at the
min(10, B2)nearest candidates and penalizes every one of them that lies withinspatial_thpixels of the query’s own 1st nearest neighbor. When all of them do – a dense cluster of detections on one structure – the effective 2nd nearest neighbor distance saturates, the ratio collapses towards zero and the match is accepted. That is the intended reading: no distinct competing structure among the candidates means the 1st nearest neighbor is unambiguous.- Parameters:
desc1 (
Tensor) – Batch of descriptors of a shape \((B1, D)\).desc2 (
Tensor) – Batch of descriptors of a shape \((B2, D)\).lafs1 (
Tensor) – LAFs of a shape \((1, B1, 2, 3)\). Accepted for API symmetry withmatch_adalam()but not read by this function – onlylafs2feeds the geometric check.lafs2 (
Tensor) – LAFs of a shape \((1, B2, 2, 3)\).th (
float, optional) – distance ratio threshold. Default:0.8spatial_th (
float, optional) – minimal distance in pixels to 2nd nearest neighbor. Default:10.0mutual (
bool, optional) – also perform mutual nearest neighbor check. Default:Falsedm (
Optional[Tensor], optional) – torch.Tensor containing the distances from each descriptor in desc1 to each descriptor in desc2, shape of \((B1, B2)\). Default:None
- Return type:
- Returns:
Descriptor distance of matching descriptors, shape of \((B3, 1)\).
Long torch.Tensor indexes of matching descriptors in desc1 and desc2. Shape: \((B3, 2)\), where 0 <= B3 <= B1.
- kornia.feature.match_adalam(desc1, desc2, lafs1, lafs2, config=None, hw1=None, hw2=None, dm=None)[source]#
Perform descriptor matching, followed by AdaLAM filtering.
See [CLO+20] for more details.
If the distance matrix dm is not provided,
torch.cdist()is used.- Parameters:
desc1 (
Tensor) – Batch of descriptors of a shape \((B1, D)\).desc2 (
Tensor) – Batch of descriptors of a shape \((B2, D)\).lafs1 (
Tensor) – LAFs of a shape \((1, B1, 2, 3)\).lafs2 (
Tensor) – LAFs of a shape \((1, B2, 2, 3)\).config (
Optional[AdalamConfig], optional) – dict with AdaLAM config Default:Nonedm (
Optional[Tensor], optional) – torch.Tensor containing the distances from each descriptor in desc1 to each descriptor in desc2, shape of \((B1, B2)\). Default:Nonehw1 (
Optional[Tuple[int,int]], optional) – Height/width of image. Default:Nonehw2 (
Optional[Tuple[int,int]], optional) – Height/width of image. Default:None
- Return type:
- Returns:
Descriptor distance of matching descriptors, shape of \((B3, 1)\).
Long torch.Tensor indexes of matching descriptors in desc1 and desc2. Shape: \((B3, 2)\), where 0 <= B3 <= B1.
- class kornia.feature.DescriptorMatcher(match_mode='snn', th=0.8)[source]#
nn.Module version of descriptor-only matching functions.
This matcher only requires descriptors (no LAFs). For geometry-aware matching that uses LAFs, see
GeometryAwareDescriptorMatcher.- See
match_nn(),match_snn(), match_mnn()ormatch_smnn()for more details.
- Parameters:
- See
- class kornia.feature.GeometryAwareDescriptorMatcher(match_mode='fginn', params=None)[source]#
nn.Module version of geometry-aware matching functions that use LAFs (Local Affine Frames).
Unlike
DescriptorMatcher, this matcher requires both descriptors and LAFs. Seematch_fginn()ormatch_adalam()for more details.- Parameters:
- class kornia.feature.LocalFeatureMatcher(local_feature, matcher)[source]#
nn.Module, which finds correspondences between two images based on local features.
- Parameters:
local_feature (
Module) – Local feature detector. SeeGFTTAffNetHardNet.matcher (
Module) – Descriptor matcher, seeDescriptorMatcher.
- Returns:
Dictionary with image correspondences and confidence scores.
- Return type:
Dict[str, torch.Tensor]
Example
>>> img1 = torch.rand(1, 1, 320, 200) >>> img2 = torch.rand(1, 1, 128, 128) >>> input = {"image0": img1, "image1": img2} >>> gftt_hardnet_matcher = LocalFeatureMatcher( ... GFTTAffNetHardNet(10), kornia.feature.DescriptorMatcher('snn', 0.8) ... ) >>> out = gftt_hardnet_matcher(input)
- forward(data)[source]#
Run forward.
- Parameters:
data (
Dict[str,Tensor]) – dictionary containing the input data in the following format:- Keyword Arguments:
image0 – left image with shape \((N, 1, H1, W1)\).
image1 – right image with shape \((N, 1, H2, W2)\).
mask0 (optional) – left image mask. ‘0’ suppresses detection, with shape \((N, H1, W1)\) or \((N, 1, H1, W1)\).
mask1 (optional) – right image mask. ‘0’ suppresses detection, with shape \((N, H2, W2)\) or \((N, 1, H2, W2)\).
- Return type:
- Returns:
keypoints0, matching keypoints from image0 \((NC, 2)\).keypoints1, matching keypoints from image1 \((NC, 2)\).confidence,1 - descriptor distance\((NC)\). This lies in \([0, 1]\) only for the ratio-basedDescriptorMatchermodes (snn,smnn);nnandmnnreturn raw distances, which are unbounded for an arbitrary descriptor, so the confidence has no lower bound in general – it goes at least down to -1, the value reached by unit-norm descriptors, whose distance tops out at 2.0.lafs0, matching LAFs from image0 \((1, NC, 2, 3)\).lafs1, matching LAFs from image1 \((1, NC, 2, 3)\).batch_indexes, batch indexes for the keypoints and lafs \((NC)\).
Learned matchers#
- class kornia.feature.LightGlueMatcher(feature_name='disk', params=None)[source]#
LightGlue-based matcher in kornia API.
This is based on the original code from paper “LightGlue: Local Feature Matching at Light Speed”. See [LSP23] for more details.
- Parameters:
- forward(desc1, desc2, lafs1, lafs2, hw1=None, hw2=None)[source]#
Run forward.
- Parameters:
desc1 (
Tensor) – Batch of descriptors of a shape \((B1, D)\).desc2 (
Tensor) – Batch of descriptors of a shape \((B2, D)\).lafs1 (
Tensor) – LAFs of a shape \((1, B1, 2, 3)\).lafs2 (
Tensor) – LAFs of a shape \((1, B2, 2, 3)\).hw1 (
Optional[Tuple[int,int]], optional) – Height/width of image. Default:Nonehw2 (
Optional[Tuple[int,int]], optional) – Height/width of image. Default:None
- Return type:
- Returns:
Descriptor distance of matching descriptors, shape of \((B3, 1)\).
- Long torch.Tensor indexes of matching descriptors in desc1 and desc2,
shape of \((B3, 2)\) where \(0 <= B3 <= B1\).
- class kornia.feature.LightGlue(features='superpoint', **conf_)[source]#
Implement the LightGlue matcher for sparse local features.
LightGlue is a deep network that matches local features across image pairs using a series of transformer layers and an adaptive pruning mechanism.
- Parameters:
features (
str, optional) – The type of local features to match (e.g., ‘superpoint’, ‘disk’). Default:"superpoint"conf – A configuration dictionary to override default parameters.
- forward(data)[source]#
Match keypoints and descriptors between two images.
- Return type:
- Input (dict):
- image0: dict
keypoints: [B x M x 2] descriptors: [B x M x D] image: [B x C x H x W] or image_size: [B x 2]
- image1: dict
keypoints: [B x N x 2] descriptors: [B x N x D] image: [B x C x H x W] or image_size: [B x 2]
- Output (dict):
log_assignment: [B x M+1 x N+1] matches0: [B x M] matching_scores0: [B x M] matches1: [B x N] matching_scores1: [B x N] matches: List[[Si x 2]], scores: List[[Si]]
- class kornia.feature.OnnxLightGlue(weights=None, device='cpu')[source]#
Wrapper for loading LightGlue-ONNX models and running inference via ONNXRuntime.
LightGlue [LSP23] performs fast descriptor-based deep keypoint matching. This module requires onnxruntime to be installed.
If you have trained your own LightGlue model, see fabio-sim/LightGlue-ONNX for how to export the model to ONNX and optimize it.
- Parameters:
weights (
str|None, optional) – Pretrained weights, or a path to your own exported ONNX model. Available pretrained weights are'disk','superpoint','disk_fp16', and'superpoint_fp16'. Note that FP16 requires CUDA. Defaults to'disk_fp16'ifdeviceis CUDA, and'disk'if CPU. Default:Nonedevice (
Union[str,device,None], optional) – Union[str, torch.device, None] to run inference on. Default:"cpu"
- forward(data)[source]#
Match keypoints and descriptors between two images.
The output contains the matches (the indices of the matching keypoint pairs between the first and second image) and the corresponding confidence scores. Only a batch size of 1 is supported.
- Parameters:
data (
dict[str,dict[str,Tensor]]) – Dictionary containing both images and the keypoints and descriptors thereof.- Return type:
- Returns:
Dictionary containing the matches and scores.
data(dict):image0(dict):keypoints(float32): \((1, M, 2)\)descriptors(float32): \((1, M, D)\)image: \((1, C, H, W)\) orimage_size: \((1, 2)\)image1(dict):keypoints(float32): \((1, N, 2)\)descriptors(float32): \((1, N, D)\)image: \((1, C, H, W)\) orimage_size: \((1, 2)\)
output(dict):matches(int64): \((S, 2)\)scores(float32): \((S)\)
- class kornia.feature.LoFTR(pretrained='outdoor', config=default_cfg)[source]#
nn.Module, which finds correspondences between two images.
This is based on the original code from paper “LoFTR: Detector-Free Local Feature Matching with Transformers”. See [SSW+21] for more details.
If the distance matrix dm is not provided,
torch.cdist()is used.- Parameters:
config (
dict[str,Any], optional) – Dict with initialization parameters. Do not pass it, unless you know what you are doing`. Default:default_cfgpretrained (
Optional[str], optional) – Download and set pretrained weights to the model. Options: ‘outdoor’, ‘indoor’. ‘outdoor’ is trained on the MegaDepth dataset and ‘indoor’ on the ScanNet. Default:"outdoor"
- Returns:
Dictionary with image correspondences and confidence scores.
Example
>>> img1 = torch.rand(1, 1, 320, 200) >>> img2 = torch.rand(1, 1, 128, 128) >>> input = {"image0": img1, "image1": img2} >>> loftr = LoFTR('outdoor') >>> out = loftr(input)
- forward(data)[source]#
Run forward.
- Parameters:
data (
dict[str,Tensor]) – dictionary containing the input data in the following format:- Keyword Arguments:
image0 – left image with shape \((N, 1, H1, W1)\).
image1 – right image with shape \((N, 1, H2, W2)\).
mask0 (optional) – left image mask. ‘0’ indicates a padded position \((N, H1, W1)\).
mask1 (optional) – right image mask. ‘0’ indicates a padded position \((N, H2, W2)\).
- Return type:
- Returns:
keypoints0, matching keypoints from image0 \((NC, 2)\).keypoints1, matching keypoints from image1 \((NC, 2)\).confidence, confidence score [0, 1] \((NC)\).batch_indexes, batch indexes for the keypoints and lafs \((NC)\).