Local features (detector and descriptor together)#

class kornia.feature.LocalFeature(detector, descriptor, scaling_coef=1.0)[source]#

nn.Module, which combines local feature detector and descriptor.

Parameters:
  • detector (Module) – the detection module.

  • descriptor (LAFDescriptor) – the descriptor module.

  • scaling_coef (float, optional) – multiplier for change default detector scale (e.g. it is too small for KeyNet by default) Default: 1.0

forward(img, mask=None)[source]#

Run forward.

Parameters:
  • img (Tensor) – image to extract features with shape \((B,C,H,W)\).

  • mask (Optional[Tensor], optional) – a mask saying where a detection may be, shape \((B,1,H,W)\) with the spatial size of the image. It is forwarded to the detector unchanged; see the detector for its semantics. Default: None

Return type:

Tuple[Tensor, Tensor, Tensor]

Returns:

  • Detected local affine frames with shape \((B,N,2,3)\).

  • Response function values for corresponding lafs with shape \((B,N)\).

  • Local descriptors of shape \((B,N,D)\) where \(D\) is descriptor size.

The shape is fixed at the detector’s num_features. When an image yields fewer detections, the remaining slots carry a zero response and a zero LAF, and their descriptor is that of a patch sampled at the origin – one and the same vector for every such slot. LocalFeatureMatcher drops them before matching; a hand-rolled pipeline must do the same before any other matcher, including match_nn(), match_mnn(), match_fginn(), match_adalam() and LightGlueMatcher, since identical descriptors match each other at zero distance and a mutual test does not reject a pair of them:

valid = lafs.ne(0).any(-1).any(-1)  # (B, N); the zero LAF marks a padded slot
descs, lafs = descs[0][valid[0]], lafs[:, valid[0]]

Test the LAF, not the response: a signed response can legitimately peak at exactly zero. Only the ratio tests in match_snn() and match_smnn() reject padded slots on their own, because the second-nearest padded descriptor is at the same zero distance.

class kornia.feature.SOLD2_detector(pretrained=True, config=None)[source]#

nn.Module, which detects line segments in an image.

This is based on the original code from the paper “SOLD²: Self-supervised Occlusion-aware Line Detector and Descriptor”. See [PautratLinL+21] for more details.

Parameters:
  • config (DetectorCfg) – Configuration object containing all parameters. None will load the default parameters, which are tuned for images in the range 400~800 px. Using a dataclass ensures type safety and clearer parameter management. Default: None

  • pretrained (bool) – If True, download and set pretrained weights to the model. Default: True

Returns:

The raw junction and line heatmaps, as well as the list of detected line segments (ij coordinates convention).

Example

>>> img = torch.rand(1, 1, 128, 128)
>>> sold2_detector = SOLD2_detector(pretrained=False)
>>> line_segments = sold2_detector(img)["line_segments"]
forward(img)[source]#

Run forward.

Parameters:

img (Tensor) – batched images with shape \((B, 1, H, W)\).

Returns:

list of N line segments in each of the B images \(List[(N, 2, 2)]\). junction_heatmap: raw junction heatmap of shape \((B, H, W)\). line_heatmap: raw line heatmap of shape \((B, H, W)\).

Return type:

line_segments

class kornia.feature.ALIKED(model_name='aliked-n16', max_num_keypoints=-1, detection_threshold=0.2, nms_radius=2)[source]#

ALIKED local feature detector and descriptor.

ALIKED (Adaptive Local Image KEypoint Detection) combines a multi-scale ResNet backbone with deformable descriptor sampling (SDDH) and a differentiable keypoint detector (DKD).

See [ZWC+23] for details.

_images/ALIKED.png
Parameters:
  • model_name (str, optional) – backbone configuration, one of 'aliked-t16', 'aliked-n16', 'aliked-n16rot', 'aliked-n32'. Default: "aliked-n16"

  • max_num_keypoints (int, optional) – maximum number of keypoints to detect. -1 means no limit (threshold-based mode). Default: -1

  • detection_threshold (float, optional) – minimum detection score in threshold mode. Default: 0.2

  • nms_radius (int, optional) – NMS radius (kernel size = 2 * nms_radius + 1). Default: 2

Example

>>> aliked = ALIKED.from_pretrained('aliked-n16')
>>> images = torch.rand(1, 3, 256, 256)
>>> features = aliked(images)
forward(images, image_size=None)[source]#

Detect and describe local features in a batch of images.

Parameters:
  • images (Tensor) – (B, 3, H, W) float images (can be grayscale (B, 1, H, W) — will be broadcast to 3 channels automatically).

  • image_size (Optional[Tensor], optional) – optional (B, 2) tensor of valid (W, H) for border masking when images are padded to a common size. Default: None

Return type:

list[ALIKEDFeatures]

Returns:

A list of ALIKEDFeatures of length B, one per image. Keypoints are in pixel coordinates [x, y].

forward_laf(img, mask=None, compute_affine=True)[source]#

Detect and describe local features, returning results in kornia LAF format.

Local Affine Frames are estimated from the soft-argmax weight covariance computed inside DKD: the 2x2 affine matrix captures the dominant orientation and scale of each detected keypoint without any additional network parameters.

All per-image tensors are zero-padded along the keypoint dimension so that the outputs are proper batched tensors.

Parameters:
  • img (Tensor) – image to extract features with shape \((B,C,H,W)\).

  • mask (Optional[Tensor], optional) – optional spatial mask (B, 1, H, W) with values in [0, 1]; the score map is multiplied by this mask before keypoint detection so that features are suppressed in masked regions. Default: None

  • compute_affine (bool, optional) – if True (default), estimate the 2x2 affine shape of each LAF using torch.linalg.eigh on the soft-argmax covariance. Set to False to skip the eigendecomposition and return identity affines, which is faster and avoids the linalg call entirely (useful when only keypoint positions are needed). Default: True

Return type:

Tuple[Tensor, Tensor, Tensor]

Returns:

  • Detected local affine frames with shape \((B,N,2,3)\).

  • Response function values for corresponding LAFs with shape \((B,N,1)\).

  • Local descriptors of shape \((B,N,D)\).

classmethod from_pretrained(model_name='aliked-n16', max_num_keypoints=-1, detection_threshold=0.2, nms_radius=2, device=None)[source]#

Load a pretrained ALIKED model from the official checkpoint repository.

Parameters:
  • model_name (str, optional) – one of 'aliked-t16', 'aliked-n16', 'aliked-n16rot', 'aliked-n32'. Default: "aliked-n16"

  • max_num_keypoints (int, optional) – passed to ALIKED constructor. Default: -1

  • detection_threshold (float, optional) – passed to ALIKED constructor. Default: 0.2

  • nms_radius (int, optional) – passed to ALIKED constructor. Default: 2

  • device (Optional[device], optional) – target device; defaults to CPU. Default: None

Return type:

ALIKED

Returns:

Pretrained ALIKED in eval mode.

class kornia.feature.ALIKEDFeatures(keypoints, descriptors, keypoint_scores)[source]#

Keypoints, descriptors and scores detected by ALIKED for a single image.

Since ALIKED detects a varying number of keypoints per image, ALIKEDFeatures is not batched.

Parameters:
  • keypoints (Tensor) – pixel coordinates (N, 2) as [x, y].

  • descriptors (Tensor) – L2-normalised descriptors (N, D).

  • keypoint_scores (Tensor) – detection confidence scores (N,).

property n: int#

Number of detected keypoints.

to(*args, **kwargs)[source]#

Move all tensors to a new device / dtype.

Return type:

ALIKEDFeatures

class kornia.feature.DeDoDe(detector_model='L', descriptor_model='G', amp_dtype=torch.float16)[source]#

nn.Module which detects and/or describes local features in an image using the DeDode method.

See [EBWF24] for details.

Note

DeDode takes ImageNet normalized images as input (not in range [0, 1]).

Parameters:
  • detector_model (Literal['L'], optional) – The detector model kind. Available options are: L. Default: "L"

  • descriptor_model (Literal['G', 'B'], optional) – The descriptor model kind. Available options are: G or B Default: "G"

  • amp_dtype (dtype, optional) – The automatic mixed precision desired. Default: torch.float16

Example

>>> dedode = DeDoDe.from_pretrained(detector_weights="L-C4-v2", descriptor_weights="B-upright")
>>> images = torch.randn(1, 3, 256, 256)
>>> keypoints, scores = dedode.detect(images)
>>> descriptions = dedode.describe(images, keypoints = keypoints)
>>> keypoints, scores, features = dedode(images) # alternatively do both
describe(images, keypoints=None, apply_imagenet_normalization=True, pad_if_not_divisible=True, crop_h=None, crop_w=None)[source]#

Describe keypoints in the input images. If keypoints are not provided, returns the dense descriptors.

Note

This method unconditionally sets the model to eval mode via self.train(False) so that BatchNorm and Dropout behave deterministically. This is intentional: the descriptor is only used at inference time and its statistics must be frozen.

Parameters:
  • images (Tensor) – A torch.Tensor of shape \((B, 3, H, W)\) containing the input images.

  • keypoints (Optional[Tensor], optional) – An optional torch.Tensor of shape \((B, N, 2)\) containing the detected keypoints. Default: None

  • apply_imagenet_normalization (bool, optional) – Whether to apply ImageNet normalization to the input images. Default: True

  • pad_if_not_divisible (bool, optional) – Zero-pad the image so H and W are divisible by 14. Required when using the G descriptor backed by DINOv2 (patch size 14). Ignored for B. Default: True

  • crop_h (Optional[int], optional) – The height of the crop to be used for description. If None, the full image is used. Default: None

  • crop_w (Optional[int], optional) – The width of the crop to be used for description. If None, the full image is used. Default: None

Returns:

A torch.Tensor of shape \((B, N, DIM)\) containing the descriptions

of the detected keypoints. If the dense descriptors are requested, the shape is \((B, DIM, H, W)\).

Return type:

descriptions

detect(images, n=10000, apply_imagenet_normalization=True, pad_if_not_divisible=True, crop_h=None, crop_w=None)[source]#

Detect keypoints in the input images.

Note

This method unconditionally sets the model to eval mode via self.train(False) so that BatchNorm and Dropout behave deterministically. This is intentional: the detector is only used at inference time and its statistics must be frozen.

Parameters:
  • images (Tensor) – A torch.Tensor of shape \((B, 3, H, W)\) containing the input images.

  • n (Optional[int], optional) – The number of keypoints to detect. Default: 10000

  • apply_imagenet_normalization (bool, optional) – Whether to apply ImageNet normalization to the input images. Default: True

  • pad_if_not_divisible (bool, optional) – F.pad image shape if not evenly divisible. Default: True

  • crop_h (Optional[int], optional) – The height of the crop to be used for detection. If None, the full image is used. Default: None

  • crop_w (Optional[int], optional) – The width of the crop to be used for detection. If None, the full image is used. Default: None

Returns:

A torch.Tensor of shape \((B, N, 2)\) containing the detected keypoints, normalized to the range \([-1, 1]\). scores: A torch.Tensor of shape \((B, N)\) containing the scores of the detected keypoints.

Return type:

keypoints

forward(images, n=10_000, apply_imagenet_normalization=True, pad_if_not_divisible=True)[source]#

Detect and describe keypoints in the input images.

Parameters:
  • images (Tensor) – A torch.Tensor of shape \((B, 3, H, W)\) containing the ImageNet-Normalized input images.

  • n (Optional[int], optional) – The number of keypoints to detect. Default: 10_000

  • apply_imagenet_normalization (bool, optional) – Whether to apply ImageNet normalization to the input images. Default: True

  • pad_if_not_divisible (bool, optional) – F.pad image shape if not evenly divisible. Default: True

Returns:

A torch.Tensor of shape \((B, N, 2)\) containing the detected keypoints in the image range,

unlike .detect() function.

scores: A torch.Tensor of shape \((B, N)\) containing the scores of the detected keypoints.

descriptions: A torch.Tensor of shape \((B, N, DIM)\) containing the descriptions

of the detected keypoints. DIM is 256 for B and 512 for G.

Return type:

keypoints

classmethod from_pretrained(detector_weights='L-C4-v2', descriptor_weights='G-upright', amp_dtype=torch.float16)[source]#

Load a pretrained model.

Parameters:
  • detector_weights (str, optional) – The weights to load for the detector. One of ‘L-upright’ (original paper, https://arxiv.org/abs/2308.08479), ‘L-C4’, ‘L-SO2’ (from steerers, better for rotations, https://arxiv.org/abs/2312.02152), ‘L-C4-v2’ (from dedode v2, better at rotations, less clustering, https://arxiv.org/abs/2404.08928). Default is ‘L-C4-v2’. Default: "L-C4-v2"

  • descriptor_weights (str, optional) – The weights to load for the descriptor. One of ‘B-upright’,’G-upright’ (original paper, https://arxiv.org/abs/2308.08479), ‘B-C4’, ‘B-SO2’, ‘G-C4’, ‘G-SO2’ (from steerers, better for rotations, https://arxiv.org/abs/2312.02152). Default is ‘G-upright’. Default: "G-upright"

  • amp_dtype (dtype, optional) – the dtype to use for the model. One of torch.float16 or torch.float32. Default: torch.float16

  • torch.float16 (Default is)

  • MPS (suitable for CUDA. Use torch.float32 for CPU or)

Return type:

Module

Returns:

The pretrained model.

class kornia.feature.DISK(desc_dim=128, unet=None)[source]#

nn.Module which detects and described local features in an image using the DISK method.

See [TFT20] for details.

_images/disk_outdoor_depth.jpg
Parameters:
  • desc_dim (int, optional) – The dimension of the descriptor. Default: 128

  • unet (Module | None, optional) – The U-Net to use. If None, a default U-Net is used. Kornia doesn’t provide the training code for DISK so this is only useful when using a custom checkpoint trained using the code released with the paper. The unet should take as input a torch.Tensor of shape \((B, C, H, W)\) and output a torch.Tensor of shape \((B, \mathrm{desc\_dim} + 1, H, W)\). Default: None

Example

>>> disk = DISK.from_pretrained('depth')
>>> images = torch.rand(1, 3, 256, 256)
>>> features = disk(images)
forward(images, n=None, window_size=5, score_threshold=0.0, pad_if_not_divisible=False)[source]#

Detect features in an image, returning keypoint locations, descriptors and detection scores.

Parameters:
  • images (Tensor) – The image to detect features in. Shape \((B, 3, H, W)\).

  • n (int | None, optional) – The maximum number of keypoints to detect. If None, all keypoints are returned. Default: None

  • window_size (int, optional) – The size of the non-maxima suppression window used to filter detections. Default: 5

  • score_threshold (float, optional) – The minimum score a detection must have to be returned. See DISKFeatures for details. Default: 0.0

  • pad_if_not_divisible (bool, optional) – if True, the non-16 divisible input is zero-padded to the closest 16-multiply Default: False

Return type:

list[DISKFeatures]

Returns:

A list of length \(B\) containing the detected features.

classmethod from_pretrained(checkpoint='depth', device=None)[source]#

Load a pretrained model.

Depth model was trained using depth map supervision and is slightly more precise but biased to detect keypoints only where SfM depth is available. Epipolar model was trained using epipolar geometry supervision and is less precise but detects keypoints everywhere where they are matchable. The difference is especially pronounced on thin structures and on edges of objects.

Parameters:
  • checkpoint (str, optional) – The checkpoint to load. One of ‘depth’ or ‘epipolar’. Default: "depth"

  • device (device | None, optional) – The device to load the model to. Default: None

Return type:

DISK

Returns:

The pretrained model.

heatmap_and_dense_descriptors(images)[source]#

Return the heatmap and the dense descriptors.

_images/DISK.png
Parameters:

images (Tensor) – The image to detect features in. Shape \((B, 3, H, W)\).

Return type:

tuple[Tensor, Tensor]

Returns:

A tuple of dense detection scores and descriptors. Shapes are \((B, 1, H, W)\) and \((B, D, H, W)\), where \(D\) is the descriptor dimension.

class kornia.feature.XFeat(top_k=4096, detection_threshold=0.05)[source]#

XFeat sparse and semi-dense local feature extractor and matcher.

Wraps XFeatModel with NMS keypoint detection, descriptor interpolation, and mutual nearest-neighbour matching helpers.

Reference:

“XFeat: Accelerated Features for Lightweight Image Matching”, CVPR 2024. https://www.verlab.dcc.ufmg.br/descriptors/xfeat_cvpr24/

_images/XFeat.png
Parameters:
  • top_k (int, optional) – maximum number of keypoints to keep per image. Default: 4096.

  • detection_threshold (float, optional) – minimum keypoint score. Default: 0.05.

Example

>>> model = XFeat()
>>> img = torch.rand(1, 3, 256, 256)
>>> out = model.detectAndCompute(img)
>>> out[0]['keypoints'].shape
torch.Size([..., 2])
detectAndCompute(x, top_k=None, detection_threshold=None)[source]#

Detect sparse keypoints and compute descriptors.

Parameters:
  • x (Tensor) – image tensor of shape \((B, C, H, W)\).

  • top_k (Optional[int], optional) – number of keypoints to keep (overrides self.top_k). Default: None

  • detection_threshold (Optional[float], optional) – minimum score (overrides self.detection_threshold). Default: None

Returns:

  • 'keypoints': \((N, 2)\) keypoints in (x, y) pixel coordinates.

  • 'scores': \((N,)\) reliability scores.

  • 'descriptors': \((N, 64)\) L2-normalised descriptors.

Return type:

List of length B. Each element is a dict with

detectAndComputeDense(x, top_k=None, multiscale=True)[source]#

Detect keypoints and compute dense coarse descriptors.

Parameters:
  • x (Tensor) – image tensor of shape \((B, C, H, W)\).

  • top_k (Optional[int], optional) – number of features to keep (overrides self.top_k). Default: None

  • multiscale (bool, optional) – use dual-scale (0.6x and 1.3x) extraction. Default: True.

Returns:

  • 'keypoints': \((B, K, 2)\) coarse keypoints.

  • 'descriptors': \((B, K, 64)\) coarse descriptors.

  • 'scales': \((B, K)\) extraction scale per keypoint.

Return type:

Dict with

forward(*input)[source]#

Define the computation performed at every call.

Should be overridden by all subclasses.

Note

Although the recipe for forward pass needs to be defined within this function, one should call the Module instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.

Return type:

None

classmethod from_pretrained(top_k=4096, detection_threshold=0.05)[source]#

Instantiate XFeat with pretrained weights downloaded from the official release.

Parameters:
  • top_k (int, optional) – maximum number of keypoints to keep. Default: 4096.

  • detection_threshold (float, optional) – minimum keypoint score. Default: 0.05.

Return type:

XFeat

Returns:

XFeat model with pretrained weights loaded, set to eval mode.

match_xfeat(img1, img2, top_k=None, min_cossim=-1)[source]#

Detect, describe and mutually match keypoints from two images.

Parameters:
  • img1 (Tensor) – first image tensor of shape \((1, C, H, W)\).

  • img2 (Tensor) – second image tensor of shape \((1, C, H, W)\).

  • top_k (Optional[int], optional) – number of top keypoints to use. Default: None

  • min_cossim (float, optional) – minimum cosine similarity threshold. Use -1 to disable. Default: -1

Return type:

Tuple[Tensor, Tensor]

Returns:

Tuple (mkpts0, mkpts1) of matched keypoints, each \((N, 2)\).

match_xfeat_star(im_set1, im_set2, top_k=None)[source]#

Extract coarse features, match pairs and refine matches (XFeat*).

Parameters:
  • im_set1 (Tensor) – batch of images \((B, C, H, W)\).

  • im_set2 (Tensor) – batch of images \((B, C, H, W)\).

  • top_k (Optional[int], optional) – number of top features to use. Default: None

Returns:

list of \((N, 4)\) tensors with (x1, y1, x2, y2) matches. If B == 1: tuple of \((N, 2)\) matched keypoint tensors.

Return type:

If B > 1

class kornia.feature.XFeatModel[source]#

XFeat backbone: CNN feature extractor, keypoint and reliability heads.

Implements the architecture from “XFeat: Accelerated Features for Lightweight Image Matching”, CVPR 2024.

Input: float image tensor \((B, C, H, W)\) (grayscale or RGB, any channel count). Output:

  • feats: dense descriptors \((B, 64, H/8, W/8)\).

  • keypoints: keypoint logits \((B, 65, H/8, W/8)\).

  • heatmap: reliability map \((B, 1, H/8, W/8)\).

Note

Image normalisation (InstanceNorm2d) is wrapped in torch.no_grad() following the original design; backpropagating through it is not supported.

forward(x)[source]#

Run the XFeat backbone.

Parameters:

x (Tensor) – image tensor of shape \((B, C, H, W)\).

Returns:

  • feats: dense descriptors \((B, 64, H/8, W/8)\).

  • keypoints: keypoint logits \((B, 65, H/8, W/8)\).

  • heatmap: reliability map \((B, 1, H/8, W/8)\).

Return type:

Tuple of

class kornia.feature.InterpolateSparse2d(mode='bicubic', align_corners=False)[source]#

Bilinearly or bicubically sample a dense feature map at sparse 2-D positions.

Parameters:
Shape:
  • Input x: \((B, C, H, W)\).

  • Input pos: \((B, N, 2)\) integer or float (x, y) coordinates.

  • Output: \((B, N, C)\).

forward(x, pos, H, W)[source]#

Sample x at positions pos.

Parameters:
  • x (Tensor) – feature map \((B, C, H, W)\).

  • pos (Tensor) – sampling positions \((B, N, 2)\) in pixel coordinates.

  • H (int) – height used for coordinate normalisation.

  • W (int) – width used for coordinate normalisation.

Return type:

Tensor

Returns:

Sampled features \((B, N, C)\).

class kornia.feature.DISKFeatures(keypoints, descriptors, detection_scores)[source]#

A data structure holding DISK keypoints, descriptors and detection scores for an image.

Since DISK detects a varying number of keypoints per image, DISKFeatures is not batched.

Parameters:
  • keypoints (Tensor) – torch.Tensor of shape \((N, 2)\), where \(N\) is the number of keypoints.

  • descriptors (Tensor) – torch.Tensor of shape \((N, D)\), where \(D\) is the descriptor dimension.

  • detection_scores (Tensor) – torch.Tensor of shape \((N,)\) where the detection score can be interpreted as the log-probability of keeping a keypoint after it has been proposed (see the paper section Method → Feature distribution for details).

to(*args, **kwargs)[source]#

Call torch.Tensor.to() on each torch.tensor to move the keypoints, descriptors and detection scores to the specified device and/or data type.

Parameters:
  • *args (Any) – Arguments passed to torch.Tensor.to().

  • **kwargs (Any) – Keyword arguments passed to torch.Tensor.to().

Return type:

DISKFeatures

Returns:

A new DISKFeatures object with tensors of appropriate type and location.

property x: Tensor#

Accesses the x coordinates of keypoints (along image width).

property y: Tensor#

Accesses the y coordinates of keypoints (along image height).

class kornia.feature.SIFTFeature(num_features=8000, upright=False, rootsift=True, device=None, config=None, compile_model=False, score_threshold=0.0)[source]#

Convenience module, which implements DoG detector + (Root)SIFT descriptor.

Using kornia.feature.MultiResolutionDetector without blur pyramid Still not as good as OpenCV/VLFeat because of kornia/kornia#884, but we are working on it

forward(img, mask=None)[source]#

Run forward.

Parameters:
  • img (Tensor) – image to extract features with shape \((B,C,H,W)\).

  • mask (Optional[Tensor], optional) – a mask saying where a detection may be, shape \((B,1,H,W)\) with the spatial size of the image. It is forwarded to the detector unchanged; see the detector for its semantics. Default: None

Return type:

Tuple[Tensor, Tensor, Tensor]

Returns:

  • Detected local affine frames with shape \((B,N,2,3)\).

  • Response function values for corresponding lafs with shape \((B,N)\).

  • Local descriptors of shape \((B,N,D)\) where \(D\) is descriptor size.

The shape is fixed at the detector’s num_features. When an image yields fewer detections, the remaining slots carry a zero response and a zero LAF, and their descriptor is that of a patch sampled at the origin – one and the same vector for every such slot. LocalFeatureMatcher drops them before matching; a hand-rolled pipeline must do the same before any other matcher, including match_nn(), match_mnn(), match_fginn(), match_adalam() and LightGlueMatcher, since identical descriptors match each other at zero distance and a mutual test does not reject a pair of them:

valid = lafs.ne(0).any(-1).any(-1)  # (B, N); the zero LAF marks a padded slot
descs, lafs = descs[0][valid[0]], lafs[:, valid[0]]

Test the LAF, not the response: a signed response can legitimately peak at exactly zero. Only the ratio tests in match_snn() and match_smnn() reject padded slots on their own, because the second-nearest padded descriptor is at the same zero distance.

class kornia.feature.SIFTFeatureScaleSpace(num_features=8000, upright=False, rootsift=True, device=None, compile_modules=False)[source]#

Convenience module, which implements DoG detector + (Root)SIFT descriptor.

Using kornia.feature.ScaleSpaceDetector with blur pyramid.

Still not as good as OpenCV/VLFeat because of kornia/kornia#884, but we are working on it

forward(img, mask=None)[source]#

Run forward.

Parameters:
  • img (Tensor) – image to extract features with shape \((B,C,H,W)\).

  • mask (Optional[Tensor], optional) – a mask saying where a detection may be, shape \((B,1,H,W)\) with the spatial size of the image. It is forwarded to the detector unchanged; see the detector for its semantics. Default: None

Return type:

Tuple[Tensor, Tensor, Tensor]

Returns:

  • Detected local affine frames with shape \((B,N,2,3)\).

  • Response function values for corresponding lafs with shape \((B,N)\).

  • Local descriptors of shape \((B,N,D)\) where \(D\) is descriptor size.

The shape is fixed at the detector’s num_features. When an image yields fewer detections, the remaining slots carry a zero response and a zero LAF, and their descriptor is that of a patch sampled at the origin – one and the same vector for every such slot. LocalFeatureMatcher drops them before matching; a hand-rolled pipeline must do the same before any other matcher, including match_nn(), match_mnn(), match_fginn(), match_adalam() and LightGlueMatcher, since identical descriptors match each other at zero distance and a mutual test does not reject a pair of them:

valid = lafs.ne(0).any(-1).any(-1)  # (B, N); the zero LAF marks a padded slot
descs, lafs = descs[0][valid[0]], lafs[:, valid[0]]

Test the LAF, not the response: a signed response can legitimately peak at exactly zero. Only the ratio tests in match_snn() and match_smnn() reject padded slots on their own, because the second-nearest padded descriptor is at the same zero distance.

class kornia.feature.GFTTAffNetHardNet(num_features=8000, upright=False, device=None, compile_modules=False)[source]#

Convenience module, which implements GFTT detector + AffNet-HardNet descriptor.

forward(img, mask=None)[source]#

Run forward.

Parameters:
  • img (Tensor) – image to extract features with shape \((B,C,H,W)\).

  • mask (Optional[Tensor], optional) – a mask saying where a detection may be, shape \((B,1,H,W)\) with the spatial size of the image. It is forwarded to the detector unchanged; see the detector for its semantics. Default: None

Return type:

Tuple[Tensor, Tensor, Tensor]

Returns:

  • Detected local affine frames with shape \((B,N,2,3)\).

  • Response function values for corresponding lafs with shape \((B,N)\).

  • Local descriptors of shape \((B,N,D)\) where \(D\) is descriptor size.

The shape is fixed at the detector’s num_features. When an image yields fewer detections, the remaining slots carry a zero response and a zero LAF, and their descriptor is that of a patch sampled at the origin – one and the same vector for every such slot. LocalFeatureMatcher drops them before matching; a hand-rolled pipeline must do the same before any other matcher, including match_nn(), match_mnn(), match_fginn(), match_adalam() and LightGlueMatcher, since identical descriptors match each other at zero distance and a mutual test does not reject a pair of them:

valid = lafs.ne(0).any(-1).any(-1)  # (B, N); the zero LAF marks a padded slot
descs, lafs = descs[0][valid[0]], lafs[:, valid[0]]

Test the LAF, not the response: a signed response can legitimately peak at exactly zero. Only the ratio tests in match_snn() and match_smnn() reject padded slots on their own, because the second-nearest padded descriptor is at the same zero distance.

class kornia.feature.HesAffNetHardNet(num_features=2048, upright=False, device=None, compile_modules=False)[source]#

Convenience module, which implements Hessian detector + AffNet-HardNet descriptor.

forward(img, mask=None)[source]#

Run forward.

Parameters:
  • img (Tensor) – image to extract features with shape \((B,C,H,W)\).

  • mask (Optional[Tensor], optional) – a mask saying where a detection may be, shape \((B,1,H,W)\) with the spatial size of the image. It is forwarded to the detector unchanged; see the detector for its semantics. Default: None

Return type:

Tuple[Tensor, Tensor, Tensor]

Returns:

  • Detected local affine frames with shape \((B,N,2,3)\).

  • Response function values for corresponding lafs with shape \((B,N)\).

  • Local descriptors of shape \((B,N,D)\) where \(D\) is descriptor size.

The shape is fixed at the detector’s num_features. When an image yields fewer detections, the remaining slots carry a zero response and a zero LAF, and their descriptor is that of a patch sampled at the origin – one and the same vector for every such slot. LocalFeatureMatcher drops them before matching; a hand-rolled pipeline must do the same before any other matcher, including match_nn(), match_mnn(), match_fginn(), match_adalam() and LightGlueMatcher, since identical descriptors match each other at zero distance and a mutual test does not reject a pair of them:

valid = lafs.ne(0).any(-1).any(-1)  # (B, N); the zero LAF marks a padded slot
descs, lafs = descs[0][valid[0]], lafs[:, valid[0]]

Test the LAF, not the response: a signed response can legitimately peak at exactly zero. Only the ratio tests in match_snn() and match_smnn() reject padded slots on their own, because the second-nearest padded descriptor is at the same zero distance.

class kornia.feature.KeyNetAffNetHardNet(num_features=8000, upright=False, device=None, scale_laf=1.0, compile_model=False, score_threshold=0.0)[source]#

Convenience module, which implements KeyNet detector + AffNet + HardNet descriptor.

_images/keynet_affnet.jpg
forward(img, mask=None)[source]#

Run forward.

Parameters:
  • img (Tensor) – image to extract features with shape \((B,C,H,W)\).

  • mask (Optional[Tensor], optional) – a mask saying where a detection may be, shape \((B,1,H,W)\) with the spatial size of the image. It is forwarded to the detector unchanged; see the detector for its semantics. Default: None

Return type:

Tuple[Tensor, Tensor, Tensor]

Returns:

  • Detected local affine frames with shape \((B,N,2,3)\).

  • Response function values for corresponding lafs with shape \((B,N)\).

  • Local descriptors of shape \((B,N,D)\) where \(D\) is descriptor size.

The shape is fixed at the detector’s num_features. When an image yields fewer detections, the remaining slots carry a zero response and a zero LAF, and their descriptor is that of a patch sampled at the origin – one and the same vector for every such slot. LocalFeatureMatcher drops them before matching; a hand-rolled pipeline must do the same before any other matcher, including match_nn(), match_mnn(), match_fginn(), match_adalam() and LightGlueMatcher, since identical descriptors match each other at zero distance and a mutual test does not reject a pair of them:

valid = lafs.ne(0).any(-1).any(-1)  # (B, N); the zero LAF marks a padded slot
descs, lafs = descs[0][valid[0]], lafs[:, valid[0]]

Test the LAF, not the response: a signed response can legitimately peak at exactly zero. Only the ratio tests in match_snn() and match_smnn() reject padded slots on their own, because the second-nearest padded descriptor is at the same zero distance.

class kornia.feature.KeyNetHardNet(num_features=8000, upright=False, device=None, scale_laf=1.0, compile_model=False, score_threshold=0.0)[source]#

Convenience module, which implements KeyNet detector + HardNet descriptor.

forward(img, mask=None)[source]#

Run forward.

Parameters:
  • img (Tensor) – image to extract features with shape \((B,C,H,W)\).

  • mask (Optional[Tensor], optional) – a mask saying where a detection may be, shape \((B,1,H,W)\) with the spatial size of the image. It is forwarded to the detector unchanged; see the detector for its semantics. Default: None

Return type:

Tuple[Tensor, Tensor, Tensor]

Returns:

  • Detected local affine frames with shape \((B,N,2,3)\).

  • Response function values for corresponding lafs with shape \((B,N)\).

  • Local descriptors of shape \((B,N,D)\) where \(D\) is descriptor size.

The shape is fixed at the detector’s num_features. When an image yields fewer detections, the remaining slots carry a zero response and a zero LAF, and their descriptor is that of a patch sampled at the origin – one and the same vector for every such slot. LocalFeatureMatcher drops them before matching; a hand-rolled pipeline must do the same before any other matcher, including match_nn(), match_mnn(), match_fginn(), match_adalam() and LightGlueMatcher, since identical descriptors match each other at zero distance and a mutual test does not reject a pair of them:

valid = lafs.ne(0).any(-1).any(-1)  # (B, N); the zero LAF marks a padded slot
descs, lafs = descs[0][valid[0]], lafs[:, valid[0]]

Test the LAF, not the response: a signed response can legitimately peak at exactly zero. Only the ratio tests in match_snn() and match_smnn() reject padded slots on their own, because the second-nearest padded descriptor is at the same zero distance.