Local features (detector and descriptor together)#
LocalFeature combines a detector and a LAF descriptor. Its SIFT and HardNet presets return
LAFs (B, N, 2, 3) in pixels, responses (B, N) and descriptors (B, N, D), with
N = num_features slots per image. Unused slots contain zero LAFs. Use laf_is_filled() to keep
detected features and discard padded slots; apply the same mask to all three outputs.
LocalFeatureMatcher filters this padding automatically.
SIFTFeature, KeyNetHardNet and KeyNetAffNetHardNet take one grayscale image
(1, 1, H, W) per call. The other presets take a batch (B, 1, H, W).
SIFTFeatureScaleSpace(descriptor_backend="pyramid") also accepts an RGB batch and converts it to grayscale.
The learned models have separate interfaces and are not
LocalFeature subclasses.
Choosing a SIFT pipeline#
For new scale-space SIFT pipelines, start with
SIFTFeatureScaleSpace and explicitly select descriptor_backend="pyramid":
import kornia.feature as KF
feature = KF.SIFTFeatureScaleSpace(
num_features=2048, descriptor_backend="pyramid", rootsift=True
).to(grayscale_image.device)
lafs, responses, descriptors = feature(grayscale_image)
grayscale_image is a floating-point tensor of shape (B, 1, H, W) with values
in [0, 1]. Outputs are LAFs (B, N, 2, 3), responses (B, N) and descriptors
(B, N, 128). N is the requested feature budget; fewer detections leave padded
slots. Use laf_is_filled() to identify real detections before matching.
rootsift=True selects RootSIFT normalization. Use descriptor_layout="opencv"
when feeding descriptors to LightGlueMatcher with "sift".
Both feature classes default to descriptor_backend="patch". Backend performance
depends on device, image size, feature count and batching; the recipe is not a claim
that pyramid extraction is always faster.
Pipeline |
Detection and extraction |
When to use it |
|---|---|---|
|
Dedicated DoG scale-space detector; orientation and description share the detector’s Gaussian layers. |
Primary recipe for new scale-space SIFT use. |
|
Generic |
Existing pipelines, or workloads where measurements favor patch extraction. |
|
Multiresolution, per-level DoG detection; patch orientation and description. |
Existing multiresolution pipelines; this is an approximation to scale-space SIFT. |
|
The same multiresolution detector; a separate image pyramid supplies smoothed gradients for orientation and pooled histogram maps for description. |
Measured multiresolution workloads; see the validation below. |
The two feature classes have different detector algorithms. SIFTFeature
applies a single-scale DoG response independently at each image resolution, with
2-D non-maximum suppression. It does not select extrema across scale or refine
positions and scales to subpixel precision. SIFTFeatureScaleSpace searches
3-D DoG scale-space extrema and refines their positions and scales. Neither preset
implements classical SIFT’s contrast and Hessian edge rejection, and each assigns
only one orientation per detection (or preserves upright frames when requested).
descriptor_backend is not an interchangeable descriptor switch. In
SIFTFeature it changes orientation and description but keeps detection;
in SIFTFeatureScaleSpace it also selects a different detector implementation.
Consequently, the scale-space backends can return different detections as well as
different descriptors.
The scale-space pyramid path ranks valid refined extrema by absolute response.
Precise doubling and integer octave decimation keep pixel coordinates aligned.
The converged integer Gaussian layer and refined continuous scale are retained
separately. Gradients are computed once per used layer and shared between orientation
and description; no pyramid is retained between calls. Sampling and Gaussian support
differ from patch extraction, so descriptors are not numerically interchangeable.
For this backend, compile_modules accepts scale_pyr and subpix (or
True for both); sparse orientation and description run eagerly. The patch
backend passes compile_modules to ScaleSpaceDetector.
Matching with LightGlue#
Use descriptor_layout="opencv" with LightGlueMatcher in "sift"
mode. Pass the oriented LAFs returned by the feature, filter zero-LAF padding from
both LAFs and descriptor rows with laf_is_filled(), and supply the original
image sizes as hw1=(height0, width0) and hw2=(height1, width1). The matcher
converts the LAF angle and scale internally; do not apply those conversions twice.
The public adapter uses one sixth of the LAF scale. For the scale-space presets’
6-sigma frames this is the detection sigma. SIFTFeature uses a different
measurement-region convention, so its multiresolution frames do not imply the same
detection sigma. Descriptor-layout compatibility alone does not guarantee equal
matching accuracy across the four pipelines. Evaluate the complete feature/matcher
combination at the intended feature budget.
Validation and possible deprecation#
The automatic orientation used by SIFTFeature(descriptor_backend="pyramid")
integrates a 19x19 support of smoothed image gradients before angular binning,
without extracting image patches. Its acceptance criteria, tracked in
#5748, include performance at
1024 features and Oxford accuracy at 2048 features. Promotion of this convenience
combination requires accuracy matching the patch backend and a demonstrated
runtime or memory advantage on a stated workload.
Validation should compare with the patch backend at 1024 and 2048 features on
IMC PhotoTourism pose estimation and Oxford homography estimation, reporting
matcher settings, device and timing methodology.
If validation does not establish those benefits, the plan is to deprecate this
convenience combination and remove it only after the API stability policy window: at least one minor release of warnings and a
documented replacement. No deprecation warning or removal version is set.
This plan concerns the combination, not the standalone
SIFTDescriptorFromPyramid descriptor-only interface; see
Choosing a SIFT descriptor interface.
HardNet presets#
The six HardNet presets describe 32 x 32 patches with pretrained HardNet through
LAFDescriptor. They load pretrained weights for every network they use and start in evaluation mode.
Choose a preset by its detector and whether you need affine shape adaptation. The AffNet presets adapt each
frame’s shape before estimating its orientation; upright=True skips orientation estimation.
Preset |
Detector and frames |
Orientation |
Input, |
|
|---|---|---|---|---|
|
|
|
none |
|
|
|
|
none |
|
The DoG detector of |
|
|
|
|
The same, with AffNet shapes |
|
|
|
|
|
none |
|||
|
|
|
For a preset with a LightGlueMatcher mode, drop the padded slots and pass its LAFs and descriptors to the
matcher in that mode. The DoG presets return the 12-sigma frames that the "doghardnet" weights expect.
Learned local features#
ALIKED, DISK, XFeat and DeDoDe detect and describe keypoints.
Load them with from_pretrained to get pretrained weights and evaluation mode. Their constructors otherwise
create models in training mode with random weights, except that the default DeDoDe() also loads a pretrained
DINOv2 backbone. SOLD2_detector detects line segments and loads pretrained weights by default.
The four keypoint models return (x, y) pixel coordinates. To match one image pair with
LightGlueMatcher, use laf_from_center_scale_ori() on keypoints[None] to construct LAFs,
then pass the LAFs and descriptors to the matcher in the mode listed below.
Subtract 0.5 from DeDoDe’s keypoints first to convert its half-pixel centres to integer pixel centres.
ALIKED.forward_laf() can return LAFs directly.
XFeat.match_xfeat_star anchors both matched points at bin 3 of their coarse cells, in pixels of the image
the network saw, before refining the first point. These coordinates differ from the raw top-left cell
positions returned by detectAndComputeDense; see XFeat for the measured accuracy and convention.
XFeat returns inference tensors. Match these outputs under torch.no_grad() or torch.inference_mode()
(#6533).
The image matching guide compares the speed and accuracy of the four
keypoint models with the authors’ code on each device.
Model |
Input |
Output |
|
|---|---|---|---|
RGB |
one |
|
|
RGB |
one |
|
|
|
|
|
|
RGB |
tensors of the |
|
|
grayscale |
line segments, one |
none |
API reference#
- class kornia.feature.LocalFeature(detector, descriptor, scaling_coef=1.0)[source]#
Detect and describe LAFs in one call with a given detector and LAF descriptor module.
feature = LocalFeature(detector, descriptor), thenlafs, responses, descs = feature(img, mask)runs a detector and descriptor as one pipeline. It takes images(B, C, H, W)and an optional mask. The detector returns LAFs(B, N, 2, 3)in pixels and responses(B, N). The descriptor returns one descriptor per LAF,(B, N, D).scaling_coefchanges the LAF shape before description. UseLAFDescriptorto adapt a patch descriptor such asHardNet;SIFTDescriptorFromPyramidalready takes images and LAFs. The detector and descriptor define accepted batch sizes, channels and intensity ranges. To match features from two images, useLocalFeatureMatcher. For learned features, useDISK,ALIKED,XFeatorDeDoDe.- Convention:
The returned LAFs use the pixel convention of
laf_from_center_scale_ori()(see Local features).scaling_coefmultiplies their shapeA(scale_laf()) before the description and leaves the centres and the responses unchanged.Cast the module to the image dtype before calling it, for example
feature.to(img.dtype). See each preset for its supported dtypes.A detector can return zero-LAF padding when fewer than
Nfeatures are found.laf_is_filled(lafs)isTruefor detections; index LAFs, responses and descriptors with it to discard padding before matching.LocalFeatureMatcherdoes this automatically.
- Parameters:
detector (
Module) – the detection module, called asdetector(img, mask)and returning(lafs, responses), such asScaleSpaceDetector.descriptor (
Module) – the descriptor module, called asdescriptor(img, lafs)and returning(B, N, D), such asLAFDescriptor.scaling_coef (
float, optional) – the multiplier of the detector’s LAFs before the description, see the Convention block. Anintis converted tofloat. Must be positive. Default:1.0
- Raises:
ValueError – if
scaling_coefis not positive.
See also
ScaleSpaceDetector: a scale-space detector for a batch of images.MultiResolutionDetector: a detector for one image per call.laf_is_filled(): returns the detection slots to keep and discard padding.LocalFeatureMatcher: runs a local feature on two images and matches the descriptors.SIFTFeatureScaleSpace: the SIFT preset for a batch of images.
Example
>>> feature = LocalFeature(ScaleSpaceDetector(10), LAFDescriptor(SIFTDescriptor(32), patch_size=32)) >>> lafs, responses, descs = feature(torch.rand(2, 1, 64, 64)) >>> lafs.shape, responses.shape, descs.shape (torch.Size([2, 10, 2, 3]), torch.Size([2, 10]), torch.Size([2, 10, 128]))
- forward(img, mask=None)[source]#
Run forward.
- Parameters:
- Return type:
- 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 Convention block of
LocalFeaturegives the frame,Nand the slots the detector did not fill, which have to be dropped before matching.
- class kornia.feature.ALIKED(model_name='aliked-n16', max_num_keypoints=-1, detection_threshold=0.2, nms_radius=2)[source]#
Detect sub-pixel keypoints in images of any size, described by deformable sampling (ALIKED).
aliked = ALIKED.from_pretrained("aliked-n16")loads the trained weights in evaluation mode, andfeatures = aliked(images)takes RGB images(B, 3, H, W)in \([0, 1]\), or grayscale(B, 1, H, W), of any height and width, and returns a list ofBALIKEDFeatures, one per image. Each holds sub-pixel keypoints(N, 2)as(x, y)pixels, their scores(N,)and L2-normalised descriptors(N, D), withD128, or 64 for"aliked-t16", andNset by the image’s score map. Withlafs, responses, descs = aliked.forward_laf(images), the same keypoints, scores and descriptors come as tensors(B, N, 2, 3),(B, N, 1)and(B, N, D), padded to the largestNof the batch. To match two images, pass the 128-D descriptors withlaf_from_center_scale_ori(keypoints[None])toLightGlueMatcherin"aliked"mode; for the same number of keypoints in every image, useDeDoDeinstead.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.
Speed against the authors’ Python code (640 px, 2,048 keypoints): on CUDA, compile the model for repeated inference. Eager, it runs at 0.8x the authors’ speed on an RTX 4090, because its PyTorch deformable convolution launches many small kernels;
torch.compile(model)runs at 1.6x (1.2x withdynamic=True). On CPUs keep it eager: it runs at 1.7-2.0x the authors’ speed, and compiling it made it slower on an x86 CPU. See the image matching guide.
- Convention:
ALIKED()builds random weights in training mode, where BatchNorm normalises with the batch, updates its running statistics on every call, and a single small image raises; call.eval()for inference.from_pretrained()returns the trained model in evaluation mode.The network applies no normalisation, so pass images in \([0, 1]\), the range of the pretrained weights; a
(B, 1, H, W)image is repeated to three channels, and other channel counts raise. AnyHandWwork: the image is replicate-padded around its centre to multiples of 32 and the maps are cropped back, so the padding does not move the keypoints. The image must have the model’s dtype: a float16, bfloat16 or float64 image raises on a float32 model, so cast the model first,aliked.to(images.dtype).The keypoints of
forward()are sub-pixel(x, y)in the pixel convention oflaf_from_center_scale_ori()(see Local features): a strict maximum of the score map in its2 * nms_radius + 1window (see the note), at leastnms_radiuspixels from the border, moved by a soft-argmax over that window. Its score is the score map read bilinearly there, and the descriptors are L2-normalised. The keypoints, and the LAFs offorward_laf(), are float32 for a float16 or bfloat16 model and otherwise in the image’s dtype; scores and descriptors keep the model’s dtype.With
detection_threshold > 0(threshold mode), the maxima strictly above it are kept, at mostmax_num_keypointsof them, and at most 20000 for a non-positivemax_num_keypoints. An image with no maximum above the threshold keeps the maxima above its own mean score instead, whatever the rest of the batch. Withdetection_threshold <= 0andmax_num_keypoints > 0(top-k mode), themax_num_keypointsstrongest maxima are kept, or all of them when there are fewer; with both<= 0, the maxima above the image’s mean score.image_sizeholds the valid(W, H)of each image of a batch padded at the bottom and right to a common size: maxima closer thannms_radiuspixels to that image’s last valid row or column are dropped.forward_laf()returns padded tensors likeLocalFeature, butNis the largest keypoint count in the batch and the responses are(B, N, 1). Padded slots hold zero LAFs, responses and descriptors;laf_is_filled(lafs)is true for detections, so index every output with it to discard the padding. Itsmaskmultiplies the score map, and it takes noimage_size.Known defects: on CPU, float16 and bfloat16 score and feature maps go to torch’s
grid_samplewithout an upcast: the half-precision kernel can return wrong values, NaN or overflow, and where torch has none the call raises (#5810).
- 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) – the keypoint budget, a cap on the number of maxima kept in threshold mode and in top-k mode; see the Convention block. Default:-1detection_threshold (
float, optional) – a positive value selects threshold mode and is the score a maximum must exceed; zero or a negative value selects top-k mode whenmax_num_keypointsis positive. See the Convention block. Default:0.2nms_radius (
int, optional) – NMS radius (kernel size= 2 * nms_radius + 1). The suppression keeps strict local maxima only; see the note below. Default:2
Note
Keypoints are the strict local maxima of the score map:
nms2d()keeps a position only if its score is greater than every other score in its2 * nms_radius + 1window. This departs on purpose from the reference implementations (Shiaoming/ALIKED and LightGlue’s port). Theirsimple_nmsalso keeps tied maxima, and in two further rounds it adds the positions that become the maximum of their window once the windows around the maxima already kept are zeroed. Those positions lie on the flank of a stronger peak and are not local maxima of the score map. In threshold mode, when neither the keypoint budget nor the fallback below decides the count, kornia therefore returns a subset of the reference keypoints: with the pretrainedaliked-n16and the default threshold it returns up to 10 % fewer keypoints than the reference on the Oxford img1 images, and each one left out has a higher score in its window. Otherwise the two keypoint sets need not be nested, because the reference ranks those extra positions with the maxima: in top-k mode, where it also fillstop_kslots with positions that are not maxima when the score map has fewer maxima, and when the budget cuts the count in threshold mode. The reference falls back to the mean score only when no image of the batch has a maximum above the threshold; kornia returns maxima only and decides the fallback for each image, so an image’s keypoints do not depend on the rest of the batch.See also
ALIKEDFeatures: the per-image result offorward().DISK: learned integer-pixel keypoints with 128-D descriptors, for RGB images whose sides are multiples of 16.XFeat: learned keypoints with 64-D descriptors, and its own mutual-nearest-neighbour and refined matching of image pairs.DeDoDe: separate learned detector and descriptor networks, withnkeypoints in every image.LocalFeature: a classical detector and LAF descriptor in one call;forward_laf()returns padded LAF tensors like it, with(B, N, 1)responses.LightGlueMatcher: matches ALIKED’s descriptors and keypoints with the"aliked"weights.
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:
- Return type:
- Returns:
A list of
ALIKEDFeaturesof 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.
With
compute_affine=Truethe 2x2 blockAof each LAF comes from the covariance of the soft-argmax weights in the keypoint’s2 * nms_radius + 1detection window, computed by the keypoint detection step (DKD) without any additional network parameters:A @ A.Tis that covariance, so the axes of the frame are its principal axes, anddet A > 0(the frame is never mirrored). The frame describes how sharply the score map peaks, not an image structure. Its scale (get_laf_scale()) is about a pixel or less with the pretrainedaliked-n16. That is much smaller than the region the descriptor samples, so rescale the frames, for example withscale_laf(), before using them as a region size.All per-image tensors are zero-padded along the keypoint dimension to the largest keypoint count in the batch, so that the outputs are proper batched tensors.
- Parameters:
img (
Tensor) – image to extract features with shape(B, 3, H, W), or(B, 1, H, W), repeated to three channels.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:Nonecompute_affine (
bool, optional) – ifTrue(default), estimate the 2x2 affine shape of each LAF usingtorch.linalg.eighon the soft-argmax covariance. Set toFalseto skip the eigendecomposition and return identity affines, which avoids the linalg call entirely (useful when only keypoint positions are needed). Default:True
- Return type:
- 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]#
Build an ALIKED model and load the pretrained checkpoint of
model_name, in evaluation mode.- Parameters:
model_name (
str, optional) – one of'aliked-t16','aliked-n16','aliked-n16rot','aliked-n32'. Default:"aliked-n16"max_num_keypoints (
int, optional) – passed toALIKEDconstructor. Default:-1detection_threshold (
float, optional) – passed toALIKEDconstructor. Default:0.2nms_radius (
int, optional) – passed toALIKEDconstructor. Default:2device (
Optional[device], optional) – target device; defaults to CPU. Default:None
- Return type:
- Returns:
Pretrained
ALIKEDin eval mode.
- class kornia.feature.ALIKEDFeatures(keypoints, descriptors, keypoint_scores)[source]#
Hold the sub-pixel keypoints, descriptors and scores that ALIKED detects in one image.
features = aliked(images)[b]is whatALIKEDreturns for imageb:features.keypoints(N, 2), sub-pixel(x, y)pixels,features.descriptors(N, D), L2-normalised, andfeatures.keypoint_scores(N,), withN = features.n. It is not batched, because ALIKED detects a different number of keypoints in each image;features.to(device)moves the three tensors. For the keypoints of a whole batch as padded LAF tensors, useALIKED.forward_laf()instead.- Convention:
The keypoints, descriptors and scores that
ALIKEDreturns for one image; its Convention block gives their frame and how many there are.
- Parameters:
See also
ALIKED: the detector, which returns one of these per image.DISKFeatures: the same container forDISK, whose keypoints are integer pixels.
- class kornia.feature.DeDoDe(detector_model='L', descriptor_model='G', amp_dtype=torch.float16)[source]#
Detect the n best keypoints of each RGB image and describe them with two networks (DeDoDe).
dedode = DeDoDe.from_pretrained(detector_weights="L-C4-v2", descriptor_weights="B-upright")loads trained weights in evaluation mode.keypoints, scores, descriptions = dedode(images, n=10_000)takes RGB images(B, 3, H, W)in \([0, 1]\) and returns the bestN = min(n, H W)keypoints per image. Outputs are(x, y)pixel coordinates(B, N, 2)with pixel centres ati + 0.5, scores(B, N)and unnormalised descriptors(B, N, 256). UseALIKEDorDISKwhen the keypoint count should depend on image content.See [EBWF24] for details.
- Convention:
detect()anddescribe()run the detector and descriptor separately. The default descriptor,G, combines VGG19 with a frozen DINOv2 ViT-L/14 backbone and loads the backbone’s weights in the constructor. DescriptorBuses VGG19 alone.For
LightGlueMatcher, construct LAFs centred on the keypoints minus 0.5 and pass them with the descriptors in"dedodeb"or"dedodeg"mode, matching the descriptor variant.forward(),detect()anddescribe()take RGB images in the range \([0, 1]\) and apply the ImageNet normalization themselves; passapply_imagenet_normalization=Falsefor images that are already normalized.pad_if_not_divisiblezero-pads the normalized image at the bottom and right to multiples of 14, so the padding is the ImageNet mean colour, and removes it from the maps again.forward()returns pixeliasi + 0.5: subtract 0.5 for the pixel convention oflaf_from_center_scale_ori()(see Local features).detect()returns it normalized, as(2 i + 1) / (W, H) - 1in \([-1, 1]\) (align_corners=False), the formdescribe()takes;(k + 1) * (W, H) / 2 - 0.5converts such akto kornia’s frame. A description is read at the centre of pixeli.The keypoints of an image come in descending order of score, with no threshold and no padding. Keypoints, and the descriptions of
forward()and ofdescribe(images, keypoints), are float32. The scoremap softmax and the keypoint sampling run in at least float32, so the scores are float32 for a half-precision model and float64 for a float64 one. The dense map ofdescribe(images)follows the network dtype:amp_dtypeon CUDA, the dtype of the model on CPU and MPS.kornia detects and describes at the size of the input. The authors resize every image to 784 x 784, without keeping its aspect ratio, in
detect_from_pathanddescribe_keypoints_from_path, and train the detector and theBdescriptor at 512 x 512 (Gat 560 x 560). The 51-pixel coverage window of the keypoint sampling and the 14-pixel patches ofGdo not scale with the image. After resizing to 784 x 784, the normalized keypoints ofdetect()hold for the original image unchanged; multiply those offorward()by(W / 784, H / 784).amp_dtypeis CUDA mixed precision in every component: on CUDA tensors the networks run undertorch.autocastinamp_dtype(and the DINOv2 backbone of theGdescriptor is cast to it). On CPU and MPS it has no effect, so the default argument runs there with float32 weights and images.
- 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 dtype of the automatic mixed precision used on CUDA; it has no effect on other devices. Default:torch.float16
See also
ALIKED: learned sub-pixel keypoints whose count follows each image’s score map, for RGB images of any size.DISK: learned integer-pixel keypoints with 128-D descriptors from one U-Net, for RGB images whose sides are multiples of 16.XFeat: learned keypoints with 64-D descriptors, and its own mutual-nearest-neighbour and refined matching of image pairs.LightGlueMatcher: matches the descriptions and keypoints with the"dedodeb"weights for theBdescriptor and the"dedodeg"weights forG.
Example
>>> dedode = DeDoDe.from_pretrained(detector_weights="L-C4-v2", descriptor_weights="B-upright") >>> images = torch.rand(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 RGB input images in the range \([0, 1]\).keypoints (
Optional[Tensor], optional) – An optional torch.Tensor of shape(B, N, 2)containing the detected keypoints. Default:Noneapply_imagenet_normalization (
bool, optional) – Whether to apply ImageNet normalization to the input images. PassFalseif they are already ImageNet-normalized. Default:Truepad_if_not_divisible (
bool, optional) – Zero-pad the (normalised) image on the bottom and right so that H and W are multiples of 14; the pad is the ImageNet mean colour, as inforward()anddetect(). Required when using theGdescriptor backed by DINOv2 (patch size 14). The padding is removed from the descriptor map, so the map has the size of the input image. Default:Truecrop_h (
Optional[int], optional) – The height of the crop to be used for description. If None, the full image is used. Default:Nonecrop_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).
- A torch.Tensor of shape
- 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 RGB input images in the range \([0, 1]\).n (
Optional[int], optional) – The number of keypoints to detect. Default:10000apply_imagenet_normalization (
bool, optional) – Whether to apply ImageNet normalization to the input images. PassFalseif they are already ImageNet-normalized. Default:Truepad_if_not_divisible (
bool, optional) – Zero-pad the (normalised) image on the bottom and right so that H and W are multiples of 14; the pad is the ImageNet mean colour, as inforward()anddescribe(). The padding is removed from the scoremap, so keypoints are never reported in it. Default:Truecrop_h (
Optional[int], optional) – The height of the crop to be used for detection. If None, the full image is used. Default:Nonecrop_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 RGB input images in the range \([0, 1]\).n (
Optional[int], optional) – The number of keypoints to detect in each image, at mostH W;Nonekeeps every pixel. Default:10_000apply_imagenet_normalization (
bool, optional) – Whether to apply ImageNet normalization to the input images. PassFalseif they are already ImageNet-normalized. Default:Truepad_if_not_divisible (
bool, optional) – Zero-pad the (normalised) image on the bottom and right so that H and W are multiples of 14; the pad is the ImageNet mean colour. The padding is removed from the scoremap, so keypoints are never reported in it. Default:True
- Returns:
- A torch.Tensor of shape
(B, N, 2)containing the detected keypoints in pixels, with pixel iati + 0.5, unlikedetect(), which normalises them.
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 both B and G.
- A torch.Tensor of shape
- 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 of the automatic mixed precision used on CUDA, one of torch.float16 or torch.float32. It has no effect on CPU or MPS, where every component runs in the dtype of the input and the model. Default is torch.float16. Default:torch.float16
- Return type:
- Returns:
The pretrained model.
- class kornia.feature.DISK(desc_dim=128, unet=None)[source]#
Detect integer-pixel keypoints and describe them with the dense maps of one U-Net (DISK).
disk = DISK.from_pretrained("depth")loads trained weights in evaluation mode.features = disk(images, n=2048)takes RGB images(B, 3, H, W)and returns oneDISKFeaturesper image: up toninteger-pixel keypoints(N, 2), scores(N,)and L2-normalised descriptors(N, 128). Image dimensions must be multiples of 16 unlesspad_if_not_divisible=True. UseALIKEDfor subpixel keypoints orDeDoDefor a fixed keypoint budget per image.See [TFT20] for details.
- Convention:
DISK()creates random weights in training mode. For matching, construct LAFs withlaf_from_center_scale_ori()onkeypoints[None]and pass them with the descriptors toLightGlueMatcherin"disk"mode.imagesare RGB,(B, 3, H, W), which the U-Net sees as given, without normalisation. With the default U-Net, a common positive gain of the input, such as \([0, 255]\) instead of \([0, 1]\), changes the outputs only through the instance norms’eps, which weighs more the lower the image’s contrast. At ordinary contrast the maps barely change, though a keypoint can still swap where scores nearly tie or at thencut; at low contrast the keypoints and descriptors change substantially. With thedepthweights andn=2048, the \([0, 1]\) and \([0, 255]\) versions of Oxford graf, wall and barkimg1differ in 0 to 2 keypoints, in 2 to 6 % of them with the intensities multiplied by 0.1, and in about 30 % multiplied by 0.01.HandWmust be multiples of 16, unlesspad_if_not_divisible=Truezero-pads the bottom and right, in which case the maps are cropped back to the image before the suppression and no keypoint lies in the padding. The image must have the network’s dtype: a float16, bfloat16 or float64 image raises on a float32 model, so cast the model first,disk.to(images.dtype).Keypoints are the integer
(x, y)pixels of the strict heatmap maxima (see the note), using the pixel convention oflaf_from_center_scale_ori()(see Local features), listed in raster order (row by row, then column by column) rather than by score, in float32 for a float16 or bfloat16 network and otherwise in the dtype of the network’s output.detection_scoresare the heatmap values there, in the network’s dtype, and each descriptor is the dense descriptor at the keypoint’s pixel, L2-normalised;heatmap_and_dense_descriptors()returns the dense descriptors without normalisation.score_thresholdkeeps the scores strictly above it.nis an upper bound on the maxima abovescore_thresholdin each image; thenargument offorward()says which of them are kept when there are more.
- Parameters:
desc_dim (
int, optional) – The dimension of the descriptor. Default:128unet (
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, desc_dim + 1, H, W): the descriptors, then the heatmap. Default:None
Note
Keypoints are the strict local maxima of the heatmap:
nms2d()keeps a position only if its score is greater than every other score in its fullwindow_sizewindow. Tied maxima, and the positions near the border whose window runs off the image (seenms2d()), are never keypoints. This departs on purpose from the reference implementation (cvlab-epfl/disk). Its max-pool NMS clips the window at the border, so it judges a border position against part of its window. Of several equal maxima it keeps the one the max-pool reports first, which depends on an order PyTorch does not specify. With the pretraineddepthweights on Oxford graf and boat img1, every keypoint of the reference that kornia leaves out lies in that border strip. The reference’snkeeps the scores strictly above the(n + 1)-th largest, which drops the weakest maximum, with every maximum tied with it, of an image withnmaxima or fewer, and every maximum tied across the cut. kornia’snis an upper bound, so such an image keeps every maximum, and a tie at the cut is filled in raster order.See also
DISKFeatures: the per-image result offorward().ALIKED: learned sub-pixel keypoints for RGB images of any size, also as padded LAF tensors.XFeat: learned keypoints with 64-D descriptors, and its own mutual-nearest-neighbour and refined matching of image pairs.DeDoDe: separate learned detector and descriptor networks, withnkeypoints in every image.LocalFeature: a classical detector and LAF descriptor in one call, returning padded LAF tensors instead of a list per image.laf_from_center_scale_ori(): turns the keypoints of one image into the LAFs thatLightGlueMatcherandLAFDescriptortake.LightGlueMatcher: matches DISK’s descriptors and keypoints with the"disk"weights.
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 per image, counted among the maxima abovescore_threshold. An image withnsuch maxima or fewer keeps all of them; with more, itsnstrongest, where maxima tied at then-th score are taken in raster order. If None, all keypoints are returned. Default:Nonewindow_size (
int, optional) – The size of the non-maxima suppression window used to filter detections. Default:5score_threshold (
float, optional) – Detections must score strictly above it to be returned. SeeDISKFeaturesfor details. Default:0.0pad_if_not_divisible (
bool, optional) – if True, an input whose height or width is not a multiple of 16 is zero-padded at the bottom and right to the next multiple of 16. Default:False
- Return type:
- 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.
- class kornia.feature.DISKFeatures(keypoints, descriptors, detection_scores)[source]#
Hold the integer-pixel keypoints, descriptors and detection scores that DISK detects in one image.
features = disk(images)[b]is whatDISKreturns for imageb:features.keypoints(N, 2), integer(x, y)pixels, also read asxandy,features.descriptors(N, D), L2-normalised, andfeatures.detection_scores(N,), withN = features.n. It is not batched, because DISK detects a different number of keypoints in each image;features.to(device)moves the three tensors.- Convention:
The keypoints, scores and descriptors that
DISKreturns for one image; its Convention block gives their frame and order.
- Parameters:
keypoints (
Tensor) – torch.Tensor of shape(N, 2), whereNis the number of keypoints.descriptors (
Tensor) – torch.Tensor of shape(N, D), whereDis the descriptor dimension.detection_scores (
Tensor) – torch.Tensor of shape(N,), the detection heatmap value at each keypoint: a raw logit of the network, not a log-probability.
See also
DISK: the detector, which returns one of these per image.ALIKEDFeatures: the same container forALIKED, whose keypoints are sub-pixel.
- to(*args, **kwargs)[source]#
Return a copy whose keypoints, descriptors and detection scores went through
torch.Tensor.to().- Parameters:
*args (
Any) – Arguments passed totorch.Tensor.to().**kwargs (
Any) – Keyword arguments passed totorch.Tensor.to().
- Return type:
- Returns:
A new DISKFeatures object with tensors of appropriate type and location.
- class kornia.feature.XFeat(top_k=4096, detection_threshold=0.05)[source]#
Detect and describe keypoints with XFeat, and match image pairs, sparse or refined (XFeat*).
xfeat = XFeat.from_pretrained()loads trained weights in evaluation mode.out = xfeat.detectAndCompute(images)takes images(B, C, H, W)with any channel count and returns one dictionary per image. Each contains up totop_kkeypoints(N, 2)in(x, y)pixels, scores(N,)in descending order and L2-normalised descriptors(N, 64). Usematch_xfeat()to extract and match sparse features, ormatch_xfeat_star()for refined matches from semi-dense features. For subpixel keypoint detection, useALIKEDinstead.- Reference:
“XFeat: Accelerated Features for Lightweight Image Matching”, CVPR 2024. https://www.verlab.dcc.ufmg.br/descriptors/xfeat_cvpr24/
- Convention:
Use the named extraction and matching methods: XFeat has no
forward. Its network,xfeat.net, is anXFeatModelthat produces dense maps. To match with LighterGlue, construct LAFs withlaf_from_center_scale_ori()onkeypoints[None]and pass them with the descriptors toLightGlueMatcherin"xfeat"mode, with gradients disabled.XFeat()builds random weights in training mode. Batch normalisation can raise on a single small image; call.eval()for inference.from_pretrained()returns the trained model in evaluation mode.detectAndCompute(),detectAndComputeDense(),match_xfeat()andmatch_xfeat_star()run undertorch.inference_mode, so they return inference tensors.The image is
(B, C, H, W)with any channel count. Each extraction resizes the image it gets bilinearly to(H', W'):HandWrounded down to multiples of 32, with a minimum of 32.XFeatModelthen averages the channels and instance-normalises the result, so an affine change of the intensities with a positive gain changes its maps only through the norm’seps, which weighs more the lower the image’s contrast. With the pretrained weights andtop_k=2048, the \([0, 1]\) and \([0, 255]\) versions of Oxford graf and wallimg1differ in at most 1 keypoint, in 1 to 2 % of them with the intensities multiplied by 0.1, and in 35 to 40 % multiplied by 0.01.Keypoints are float32. Scores and descriptors have the dtype of the weights, and the resized image is cast to it, so a float16 or bfloat16 model runs on an image of any float dtype; under autocast, the descriptors of
detectAndComputeDense()have the dtype autocast gives the network. With the pretrained weights,top_k=2048and the 290 HPatches pairs on an RTX 4090 with torch 2.15,match_xfeat()keeps its inliers at 3 px within 0.6 % of float32, and float16 and bfloat16 keep 99.4 % and 95.0 % of its keypoints. On an Apple M1 half precision takes about 15 times as long as float32 on the CPU and about as long on MPS. On torch 2.5.1 the CPU float16 instance norm is wrong: on HPatches a[0, 255]image gave no keypoints and a[0, 1]one 18 % of the inliers. Use float32 or bfloat16 weights there. torch 2.15 and a 2.16 nightly are correct; versions in between were not checked.detectAndCompute()keypoints are integer pixels of the resized image, strict maxima of the keypoint heatmap in their 5 x 5 window (see the note). Pixel \(i\) of the resized image is reported at its centre in the input, \((i + 0.5) W / W' - 0.5\) in \(x\) and likewise in \(y\), in the pixel convention oflaf_from_center_scale_ori()(see Local features). That is exactly \(i\) whenHandWare multiples of 32. The reference implementation reports \(i W / W'\) instead, up to nearly half a pixel away.The heatmap value must be strictly above
detection_threshold.scoresis that value times the reliability map, and thetop_kbest keypoints come sorted by it. Each descriptor is 64-D, sampled bicubically from the dense map at the keypoint byInterpolateSparse2d, and L2-normalised.With
multiscale=False,detectAndComputeDense()takes cell(j, i)of the 1/8-resolution map at pixel8 * (j, i)of the resized image, the top-left pixel of the cell and not its centre, and reports that pixel’s centre in the input as above: exactly8 * (j, i)whenHandWare multiples of 32. It keeps up totop_kcells by reliability;top_k < 1keeps every cell. With the defaultmultiscale=True, it rescales the image bilinearly by 0.6 and by 1.3, runs that extraction on each withint(0.2 * top_k)and the remainingtop_k - int(0.2 * top_k)cells, and maps each keypointpof the image rescaled bysback through the pixel centre,(p + 0.5) / s - 0.5;scalesis1 / 0.6or1 / 1.3for each keypoint. The reference divides by the factor,p / s, 0.333 px up and to the left of the pixel at 0.6 and 0.115 px down and to the right at 1.3 (#6537). A share of 0 yields no cell from its scale, and a scale with fewer cells than its share returns all of them, so there are never more thantop_kkeypoints, and exactlytop_kwhen both scales have enough cells. Atop_kbelow 1 keeps every cell of both scales. Its descriptors are not normalised. The reference implementation gives the 1.3 scaleint(0.8 * top_k)and reads a share of 0 as “every cell”; kornia does not, because that returns more keypoints thantop_kasks for.Known defects: autograd cannot save the inference tensors of the four methods above for a backward pass, so
LightGlueMatcher, whose parameters require gradients, raises on them with gradients enabled, the default grad mode: call it undertorch.no_grad()ortorch.inference_mode(), orclone()the outputs first (#6533).
- Parameters:
Note
Keypoints are the strict local maxima of the keypoint heatmap:
nms2d()keeps a position only if its score is greater than every other score in its full 5x5 window. Tied maxima, and the positions within 2 pixels of the border whose window runs off the image, are never keypoints. This departs on purpose from the reference implementation (verlab/accelerated_features). Its NMS keeps every position equal to the maximum of its window: all positions of a plateau survive, and whether a near-tie survives depends on rounding-level differences of the scores. Its window is also clipped at the border, so it judges a border position against part of its window. With the pretrained weights on Oxford graf and boat img1, every candidate of the reference that kornia leaves out lies in that border strip.XFeat* (
match_xfeat_star()) anchors both matched cells at bin 3: it moves both points three pixels into their cells, then moves the first point by the fine displacement. Both are pixels of the image the network saw, and one such pixel spansr / sinput pixels per axis, for extraction scales(0.6 or 1.3) and the ratiorof the resize to multiples of 32. This differs from the raw top-left coordinates returned bydetectAndComputeDense()and from the reference, which starts both points at the top-left pixel and scales the displacement by1 / s.On 40 Oxford affine pairs, this match origin raises homography AUC@3 from 0.365 to 0.401 (three correspondence-order seeds, float32,
top_k=4096, USAC_MAGSAC at 1 px), and on 813 IMC PhotoTourism validation pairs scene-mean relative-pose mAA@10 from 0.458 to 0.473 (USAC_MAGSAC at 0.5 px, measured before the pixel-centre mapping of the dual-scale rescale below).The displacement of the first image is the soft-argmax of the fine matcher’s 8 x 8 heatmap times the keypoint’s scale, measured from bin 3 of each axis. This also departs on purpose from the reference implementation, which measures it from bin 4, the window centre: the pretrained fine matcher puts a zero displacement at bin 3. Matching Oxford bikes img1 with itself (pretrained weights,
multiscale=False), the reference’s refinement moves the points by (-1.04, -1.25) px on average and leaves 1 % of them within 1 px of their position, against (-0.04, -0.25) px and 94 % from bin 3. On 18 Oxford affine pairs the median homography corner error drops from 2.58 to 2.30 px; IMC 2021 PhotoTourism relative pose mAA@10 is the same within noise (0.441 and 0.443 over 813 pairs). Away from a zero displacement the soft-argmax still moves a point only about half of the way, as in the reference: on Oxford graf 1-2 to 1-5 its response to the true sub-cell offset has a slope of about 0.5, so bin 3 removes the constant part of the error, not that shrinkage.Reporting keypoints at the pixel centre of the resize to a multiple of 32 also departs on purpose from the reference. With the pretrained weights and 8 Oxford images, each matched with resizes of itself to two sizes whose true map is known exactly, the share of matches within 1 px goes from 24.2 to 24.5 % for
match_xfeat(), from 40.1 to 40.7 % forLightGlueMatcherand from 28.7 to 29.1 % formatch_xfeat_star(). Homography AUC on Oxford affine and HPatches stays within the noise of the estimator for the first two, and on HPatches at about 320 px AUC@3 ofmatch_xfeat_star()gains 0.0025. The 0.6 and 1.3 rescale of the dual-scale extraction goes through the pixel centre as well. With the bin-3 anchor, Oxford affine AUC@3 ofmatch_xfeat_star()stays within seed noise (0.404 before, 0.401 after), and the share of matches within 1 px of an exactly known map goes from 46.6 to 50.4 % for an image matched with its 0.7 resize, and from 47.6 to 48.0 %, 35.9 to 36.9 % and 21.6 to 21.2 % for its rotations by 20 degrees, by 20 degrees at scale 0.7 and by -35 degrees at scale 1.2 (#6537).See also
XFeatModel: the network it runs, which returns the dense maps at 1/8 resolution.InterpolateSparse2d: samples the dense descriptors at the keypoints.ALIKED: learned sub-pixel keypoints with 128-D descriptors, for RGB images of any size.DISK: learned integer-pixel keypoints with 128-D descriptors, for RGB images whose sides are multiples of 16.DeDoDe: separate learned detector and descriptor networks, withnkeypoints in every image.laf_from_center_scale_ori(): turns the keypoints of one image into the LAFs thatLightGlueMatchertakes.LightGlueMatcher: matches the descriptors and keypoints with the LighterGlue"xfeat"weights instead of mutual nearest neighbours.
Example
>>> model = XFeat.from_pretrained() >>> 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:
- Returns:
'keypoints':(N, 2)keypoints in (x, y) pixel coordinates.'scores':(N,)keypoint heatmap value times reliability, in descending order.'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 (overridesself.top_k). A value below 1 keeps every cell. Withmultiscale=Truethe budget is split between the scales,int(0.2 * top_k)for the 0.6x extraction and the rest for the 1.3x one, so the result never exceeds a positivetop_k; a scale with a budget of 0 contributes nothing. This departs from the reference implementation, which gives the 1.3x scaleint(0.8 * top_k)and reads a budget that rounds down to 0 as “every cell”. Default:Nonemultiscale (
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
- classmethod from_pretrained(top_k=4096, detection_threshold=0.05)[source]#
Instantiate XFeat with pretrained weights downloaded from the official release.
- match_xfeat(img1, img2, top_k=None, min_cossim=-1)[source]#
Detect, describe and mutually match keypoints from two batches of images.
Pair
bis imagebofimg1with imagebofimg2. Each batch goes throughdetectAndCompute()in one call, and then the descriptors of each pair are matched on their own by mutual nearest neighbour. A backend may round a batched convolution differently from a single-image one (MPS, and CUDA with cuDNN’s default TF32 convolutions), so a pair matched in a batch can gain or lose a few near-tied matches compared with matching it alone.- Parameters:
img1 (
Tensor) – first images(B, C, H, W).img2 (
Tensor) – second images(B, C, H, W), with the sameBasimg1.top_k (
Optional[int], optional) – number of top keypoints to use. Default:Nonemin_cossim (
float, optional) – the cosine similarity a match must exceed; a value of 0 or below, such as the default-1, disables the check. Default:-1
- Returns:
list of
(N, 4)tensors with(x1, y1, x2, y2)matches, one per pair; an empty batch gives an empty list. IfB == 1: tuple(mkpts0, mkpts1)of matched keypoints, each(N, 2).- Return type:
If
B != 1
See also
match_xfeat_star(): the dense, refined variant, with the same return convention.
- match_xfeat_star(im_set1, im_set2, top_k=None)[source]#
Extract coarse features, match pairs and refine matches (XFeat*).
Both matched cells are anchored three pixels into the cell, in pixels of the image the network saw. The first point also receives the fine displacement measured from bin 3. Raw
detectAndComputeDense()coordinates stay at the top-left cell origin; see the class note for the coordinate convention.- Parameters:
- Returns:
list of
(N, 4)tensors with(x1, y1, x2, y2)matches, one per pair; an empty batch gives an empty list. IfB == 1: tuple of(N, 2)matched keypoint tensors.- Return type:
If
B != 1
- class kornia.feature.XFeatModel[source]#
Compute the dense descriptors, keypoint logits and reliability map of XFeat at 1/8 resolution.
net = XFeatModel().eval()builds the random-weight network for inference (XFeat.from_pretrained().netis trained), andfeats, keypoints, heatmap = net(images)takes float images(B, C, H, W)with any channel count andHandWmultiples of 8, and returns the dense descriptors(B, 64, H/8, W/8), not normalised, the keypoint logits(B, 65, H/8, W/8)and the reliability map(B, 1, H/8, W/8), a sigmoid. It finds no keypoints itself: for keypoints, descriptors and matches, useXFeatinstead. It implements the architecture of “XFeat: Accelerated Features for Lightweight Image Matching”, CVPR 2024.- Convention:
The channels are averaged and the result is instance-normalised, so any channel count is accepted and an affine change
a x + bof the intensities witha > 0changes the outputs only through the norm’seps(1e-5): negligibly while the variance of the channel mean is much larger thaneps, and substantially for a low-contrast image, whose variance is close to it (seeXFeat).A new
XFeatModelis in training mode. A single32 x 32image reaches BatchNorm with one value per channel and raises; call.eval()for inference.HandWmust be multiples of 8; other sizes raise an error or give maps of mismatched sizes.XFeatresizes its input to multiples of 32.keypointsholds 65 logits per 8 x 8 cell: channel(y % 8) * 8 + x % 8of cell(y // 8, x // 8)is pixel(x, y), and channel 64 is the “no keypoint” dustbin.
Note
Image normalisation (
InstanceNorm2d) is wrapped intorch.no_grad()following the original design; backpropagating through it is not supported.See also
XFeat: runs this network and detects, describes and matches keypoints from its maps.InterpolateSparse2d: samples the descriptor map at sparse keypoints, asXFeatdoes.
- class kornia.feature.InterpolateSparse2d(mode='bicubic', align_corners=False)[source]#
Sample a feature map at sparse (x, y) pixels with the XFeat weights’ coordinate scaling.
interp = InterpolateSparse2d("bicubic")andout = interp(x, pos, H, W)take a feature map(B, C, h, w)and positions(B, N, 2)as(x, y)pixels of an image of heightHand widthW, and return the features(B, N, C)thattorch.nn.functional.grid_sample()reads there withmode, in the dtype ofx. The positions are divided byW - 1andH - 1but sampled withalign_corners=False, as the pretrained XFeat weights expect, soHandWmust be greater than 1, and a map of the image’s own size is not read atpositself (see the Convention block). To read a map of the image’s own size at the pixel itself, normalise the positions withnormalize_pixel_coordinates()and passalign_corners=Truetogrid_sampleinstead.- Convention:
posholds(x, y)pixels of an image of heightHand widthWwhose feature map has heighthand widthw. A position(px, py)is read atpx * w / (W - 1) - 0.5andpy * h / (H - 1) - 0.5in the map’s pixel frame:normgrid’s2 p / (W - 1) - 1sampled withalign_corners=False, the convention the pretrained XFeat weights use.A float16 or bfloat16 map is sampled in float32 and returned in its dtype, and float16 or bfloat16 positions are normalised in float32: torch’s half-precision
grid_samplecan return wrong values, NaN or overflow on CPU, and a half-precision grid is off by a pixel or more on a large map.
- Parameters:
mode (
str, optional) – interpolation mode fortorch.nn.functional.grid_sample(). Default:'bicubic'.align_corners (
bool, optional) – stored and not used:grid_sampleis always called withalign_corners=False. Default:False.
- Shape:
Input
x:(B, C, h, w).Input
pos:(B, N, 2)integer or float (x, y) coordinates.Output:
(B, N, C).
See also
XFeat: samples its dense descriptors at its keypoints with this module.XFeatModel: the network whose descriptor mapXFeatsamples with this module.normalize_pixel_coordinates(): the same division byW - 1andH - 1, meant forgrid_samplewithalign_corners=True, which reads a map of the image’s size at the pixel itself.
- class kornia.feature.SOLD2_detector(pretrained=True, config=None)[source]#
Detect line segments in grayscale images with SOLD2, without describing or matching them.
detector = SOLD2_detector()builds the network with its pretrained weights, in evaluation mode, andoutputs = detector(images)takes grayscale images(B, 1, H, W)in \([0, 1]\), withHandWmultiples of 8, and returns a dict:"line_segments", one(N, 2, 2)tensor of(row, col)endpoints in pixels per image, and the"junction_heatmap"and"line_heatmap",(B, H, W)each. With the same weights andconfig, these are the segments and heatmaps ofSOLD2; to also describe the segments and match them between images, useSOLD2instead. 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.- Convention:
Sizes that are not multiples of 8 raise an error or give heatmaps of another size.
line_segmentsholds one(N, 2, 2)tensor per image: the two endpoints of each segment as(row, col)in the pixel convention oflaf_from_center_scale_ori()(see Local features), soflip(-1)gives(x, y). The endpoints of a segment, and the segments by their first endpoint, are in raster order: the smaller row first or, on the same row, the smaller column, whatever the junction scores.The endpoints are junction coordinates. The default junction refinement (
use_junction_refinementofLineDetectorCfg) can produce sub-pixel endpoints in 0.25-pixel steps, up to one pixel per axis.
- Parameters:
config (DetectorCfg) – Configuration object containing all parameters, or a dict of its fields. None will load the default parameters, which are tuned for images in the range 400~800 px. A
configwithuse_descriptor=Truebuilds the descriptor head, which the outputs do not use. Default:Nonepretrained (bool) – If True, download and set pretrained weights to the model, and return it in eval mode; otherwise the weights are random and the model is in training mode. Default:
True
- Returns:
The raw junction and line heatmaps, as well as the list of detected line segments (ij coordinates convention).
See also
SOLD2: the same line detection plus the descriptor map and line matching.
Example
>>> img = torch.rand(1, 1, 128, 128) >>> sold2_detector = SOLD2_detector(pretrained=False).eval() >>> line_segments = sold2_detector(img)["line_segments"]
- forward(img)[source]#
Run forward.
- Parameters:
img (
Tensor) – batched images with shape(B, 1, H, W).- Returns:
a list of
Btensors(N, 2, 2), the(row, col)segment endpoints per image. 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.SIFTFeatureScaleSpace(num_features=8000, upright=False, rootsift=True, device=None, compile_modules=False, descriptor_backend='patch', descriptor_layout='kornia')[source]#
Detect refined DoG scale-space extrema and describe them with SIFT, for a batch.
sift = SIFTFeatureScaleSpace(2048, descriptor_backend="pyramid")builds a DoG scale-space SIFT pipeline.lafs, responses, descs = sift(img)takes grayscale images(B, 1, H, W). It returns six-sigma LAFs(B, N, 2, 3), absolute DoG responses(B, N), strongest first, and RootSIFT descriptors(B, N, 128). Uselaf_is_filled()to keep detections and discard padding. The"pyramid"backend reuses Gaussian images and accepts RGB input;"patch"samples patches and requires grayscale input. Usedescriptor_layout="opencv"withLightGlueMatcher("sift"); useDoGHardNetfor HardNet descriptors on the"patch"detections.For CPU throughput use OpenCV’s SIFT: on an Apple M1 CPU, a matching pipeline on it ran 8x faster than one on this module with
descriptor_backend="pyramid", and 14x faster with"patch"(640 px, 2,048 features). See the image matching guide.- Convention:
A
LocalFeature, whose Convention block gives the output contract, of grayscale images(B, 1, H, W); the pyramid backend converts an RGB image to grayscale first.descriptor_backend="patch", the default, runsScaleSpaceDetectorwithBlobDoGonScalePyramid(3, 1.6, 32, double_image=True), keeping minima as well as maxima, thenLAFOrienter(19)unlessupright, andSIFTDescriptoron 41 x 41 patches."pyramid"runs a dedicated DoG detector and reuses its Gaussian images and the octave and layer of each detection for orientation and description: it refines only sparse extrema, ranks all valid candidates by absolute response, and computes image gradients once per used layer.Each backend assigns one orientation per detection unless
upright=True. The backend selects a different detector as well as different orientation and description stages, so the backends can return different detections as well as different descriptors; the feature budget is the same.On both backends the LAF scale is 6 times the detection sigma, and
responsesis the absolute DoG, the same for a bright blob as for a dark one. The LAF centres are in the frame oflaf_from_center_scale_ori()(see Local features) on every octave. For a float16 or bfloat16 image the LAFs are float32 on both backends, and the responses and descriptors keep the image dtype.Descriptors come in kornia’s SIFT layout;
descriptor_layout="opencv"returns them in OpenCV’s, whichLightGlueMatcherexpects with"sift".convert_sift_descriptor_layout()converts between the two.
- Parameters:
num_features (
int, optional) – the number of slots per image; the strongest detections fill them, the rest are padding. Default:8000upright (
bool, optional) – ifTrue, skip the orientation estimation and return upright frames. Default:Falserootsift (
bool, optional) – ifTrue, the default, return RootSIFT descriptors, otherwise SIFT. Default:Truedevice (
Union[str,device,None], optional) – the device of the detector and descriptor modules. Default: CPU.compile_modules (
Union[bool,List[str]], optional) – the detector sub-modules to wrap withtorch.compile(). With"patch", thecompile_modulesofScaleSpaceDetector; with"pyramid","scale_pyr"and"subpix"only, both forTrue, while the orientation and description run eagerly. Default:Falsedescriptor_backend (
Literal['patch','pyramid'], optional) –"patch"or"pyramid", see the Convention block. Default:"patch"descriptor_layout (
Literal['kornia','opencv'], optional) –"kornia"or"opencv", the order of the descriptor values. Default:"kornia"
- Raises:
ValueError – for a
descriptor_backendordescriptor_layoutother than those listed, or acompile_modulesname the selected backend does not have.
See also
SIFTFeature: a per-level DoG approximation of SIFT, without selection across scale or sub-pixel refinement, one image per call.ScaleSpaceDetector: the detector of the"patch"backend, on aBlobDoGresponse.BlobDoG: the scale-space DoG response of the"patch"backend.SIFTDescriptor: the descriptor of the"patch"backend, run on 41 x 41 patches throughLAFDescriptor.convert_sift_descriptor_layout(): the reordering thatdescriptor_layout="opencv"applies.LightGlueMatcher: its"sift"weights match these features, in the"opencv"layout.DoGHardNet: the detections of the"patch"backend described by HardNet, at twice the frame scale.LocalFeature: its base class, which gives the output contract.
Example
>>> sift = SIFTFeatureScaleSpace(100, descriptor_backend="pyramid") >>> lafs, responses, descs = sift(torch.rand(2, 1, 64, 64)) >>> lafs.shape, responses.shape, descs.shape (torch.Size([2, 100, 2, 3]), torch.Size([2, 100]), torch.Size([2, 100, 128]))
- class kornia.feature.SIFTFeature(num_features=8000, upright=False, rootsift=True, device=None, config=None, compile_model=False, score_threshold=0.0, descriptor_backend='patch', descriptor_layout='kornia')[source]#
Detect per-level DoG keypoints and describe them with SIFT, one image per call.
sift = SIFTFeature(2048)loads a per-level DoG detector and SIFT descriptor.lafs, responses, descs = sift(img)takes one grayscale image(1, 1, H, W); a batch or color image raises. It returns LAFs(1, N, 2, 3), DoG-response magnitudes(1, N), strongest first, and RootSIFT descriptors(1, N, 128)in kornia’s layout. Uselaf_is_filled()to keep detections and discard padding.descriptor_backendchooses patches ("patch", the default) or a gradient pyramid ("pyramid"). For scale-space extrema or batches, useSIFTFeatureScaleSpacewithdescriptor_backend="pyramid".For CPU throughput use OpenCV’s SIFT: on an Apple M1 CPU, a matching pipeline on it ran 11x faster than one on this module (640 px, 2,048 features). This module takes one image per call; for batches use
SIFTFeatureScaleSpace. See the image matching guide.- Convention:
A
LocalFeature, whose Convention block gives the output contract. The detector is aMultiResolutionDetectoron the magnitude of a single-scaleBlobDoGSingleresponse. Withdescriptor_backend="patch", the default,LAFOrienter(19)orients the LAFs unlessuprightandSIFTDescriptordescribes 41 x 41 patches."pyramid"keeps the detector and orients and describes its LAFs withSIFTDescriptorFromPyramid, which integrates smoothed image gradients without extracting patches.The detector applies the response independently at each image resolution. It does not apply classical SIFT’s contrast or Hessian edge rejection. One orientation is assigned per detection unless
upright=True.Extrema of both polarities are kept: dark blobs are DoG maxima and bright blobs are DoG minima. On each image-pyramid level, a keypoint is a strict maximum of the response magnitude in its
config["nms_size"]window (15 pixels by default), so a stronger extremum of either polarity suppresses a weaker one.responsesholds the magnitude.The frames are those of
MultiResolutionDetector: a pixel of a pyramid level, with a scale ofconfig["s_mult"](22 by default) times that level’s pixel size whatever the size of the blob. Unlike the 6-sigma frames ofSIFTFeatureScaleSpace, their scale is not a fixed multiple of the detection sigma: a sixth of it, whichLightGlueMatcher("sift")takes as the detection sigma, is not that sigma here (see Choosing a SIFT pipeline).Descriptors come in kornia’s SIFT layout;
descriptor_layout="opencv"returns them in OpenCV’s, whichLightGlueMatcherexpects with"sift".convert_sift_descriptor_layout()converts between the two.Known defects:
descriptor_backend="pyramid"is less accurate than the patch backend on Oxford homographies at 2048 features, and not faster on CPU at 1024 features (#5748).
- Parameters:
num_features (
int, optional) – the number of slots per image; the strongest detections fill them, the rest are padding. Default:8000upright (
bool, optional) – ifTrue, skip the orientation estimation and return upright frames. Default:Falserootsift (
bool, optional) – ifTrue, the default, return RootSIFT descriptors, otherwise SIFT. Default:Truedevice (
Union[str,device,None], optional) – the device of the detector and descriptor modules. Default: CPU.config (
Optional[Detector_config], optional) – the pyramid and suppression settings ofMultiResolutionDetector, whoseconfigargument lists them with their defaults. Default:Nonecompile_model (
bool, optional) – wrap the DoG response and the non-maxima suppression withtorch.compile(), seeMultiResolutionDetector. Default:Falsescore_threshold (
float, optional) – the response magnitude a detection has to exceed. Must be non-negative. Default:0.0descriptor_backend (
Literal['patch','pyramid'], optional) –"patch"or"pyramid", see the Convention block. Default:"patch"descriptor_layout (
Literal['kornia','opencv'], optional) –"kornia"or"opencv", the order of the descriptor values. Default:"kornia"
- Raises:
ValueError – for a
descriptor_backendordescriptor_layoutother than those listed, or a negativescore_threshold.
See also
SIFTFeatureScaleSpace: SIFT on a DoG scale space, with extrema across scale, sub-pixel refinement and 6-sigma frames, for a batch of images.MultiResolutionDetector: its detector, on the magnitude of the DoG.BlobDoGSingle: the single-scale DoG response whose magnitude it detects on.SIFTDescriptor: the descriptor of the"patch"backend, run on 41 x 41 patches throughLAFDescriptor.SIFTDescriptorFromPyramid: the orientation and descriptor of the"pyramid"backend.convert_sift_descriptor_layout(): the reordering thatdescriptor_layout="opencv"applies.LocalFeature: its base class, which gives the output contract.
Example
>>> lafs, responses, descs = SIFTFeature(100)(torch.rand(1, 1, 64, 64)) >>> lafs.shape, responses.shape, descs.shape (torch.Size([1, 100, 2, 3]), torch.Size([1, 100]), torch.Size([1, 100, 128]))
- class kornia.feature.GFTTAffNetHardNet(num_features=8000, upright=False, device=None, compile_modules=False)[source]#
Detect GFTT corners over scale with AffNet shapes and HardNet descriptors.
feature = GFTTAffNetHardNet(2048)loads pretrained AffNet and HardNet in evaluation mode.lafs, responses, descs = feature(img)takes grayscale images(B, 1, H, W); convert color images withrgb_to_grayscale()first. It returns affine LAFs(B, N, 2, 3), Shi-Tomasi responses(B, N), strongest first, and unit-norm HardNet descriptors(B, N, 128). Uselaf_is_filled()to keep detections and discard padding. For blobs, useHesAffNetHardNetorDoGAffNetHardNet.- Convention:
A
LocalFeature, whose Convention block gives the output contract, of grayscale images(B, 1, H, W): aScaleSpaceDetectorwith theCornerGFTTresponse, its maxima only andmr_size=6, whose LAFs get their affine shape fromLAFAffNetShapeEstimator, then their orientation fromLAFOrienter(19)unlessupright, and are described byHardNeton 32 x 32 patches.
- Parameters:
num_features (
int, optional) – the number of slots per image; the strongest detections fill them, the rest are padding. Default:8000upright (
bool, optional) – ifTrue, skip the orientation estimation and return upright frames. Default:Falsedevice (
Union[str,device,None], optional) – the device of the detector and descriptor modules. Default: CPU.compile_modules (
Union[bool,List[str]], optional) – the detector sub-modules to wrap withtorch.compile(), seeScaleSpaceDetector. Default:False
See also
HesAffNetHardNet: the same pipeline on Hessian blobs, 2048 slots by default.DoGAffNetHardNet: the same shapes and descriptors on DoG blobs, whichLightGlueMatcher("dog_affnet_hardnet")matches.CornerGFTT: the corner response it detects on.ScaleSpaceDetector: its detector.LAFAffNetShapeEstimator: the AffNet shape estimation it runs before the orientation.HardNet: its descriptor, run on 32 x 32 patches throughLAFDescriptor.LocalFeature: its base class, which gives the output contract.
- forward(img, mask=None)[source]#
Run forward.
- Parameters:
- Return type:
- 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 Convention block of
LocalFeaturegives the frame,Nand the slots the detector did not fill, which have to be dropped before matching.
- class kornia.feature.HesAffNetHardNet(num_features=2048, upright=False, device=None, compile_modules=False)[source]#
Detect Hessian blobs over scale with AffNet shapes and HardNet descriptors.
feature = HesAffNetHardNet(2048)loads pretrained AffNet and HardNet in evaluation mode.lafs, responses, descs = feature(img)takes grayscale images(B, 1, H, W); convert color images withrgb_to_grayscale()first. It returns affine LAFs(B, N, 2, 3), Hessian responses(B, N), strongest first, and unit-norm HardNet descriptors(B, N, 128). Uselaf_is_filled()to keep detections and discard padding. For corners useGFTTAffNetHardNet; for LightGlue-compatible DoG blobs, useDoGAffNetHardNet.- Convention:
A
LocalFeature, whose Convention block gives the output contract, of grayscale images(B, 1, H, W): aScaleSpaceDetectorwith theBlobHessianresponse, its maxima only andmr_size=6, whose LAFs get their affine shape fromLAFAffNetShapeEstimator, then their orientation fromLAFOrienter(19)unlessupright, and are described byHardNeton 32 x 32 patches.
- Parameters:
num_features (
int, optional) – the number of slots per image; the strongest detections fill them, the rest are padding. Default:2048upright (
bool, optional) – ifTrue, skip the orientation estimation and return upright frames. Default:Falsedevice (
Union[str,device,None], optional) – the device of the detector and descriptor modules. Default: CPU.compile_modules (
Union[bool,List[str]], optional) – the detector sub-modules to wrap withtorch.compile(), seeScaleSpaceDetector. Default:False
See also
GFTTAffNetHardNet: the same pipeline on Shi-Tomasi corners, 8000 slots by default.DoGAffNetHardNet: the same shapes and descriptors on DoG blobs, whichLightGlueMatcher("dog_affnet_hardnet")matches.BlobHessian: the blob response it detects on.ScaleSpaceDetector: its detector, with this response by default.LAFAffNetShapeEstimator: the AffNet shape estimation it runs before the orientation.HardNet: its descriptor, run on 32 x 32 patches throughLAFDescriptor.LocalFeature: its base class, which gives the output contract.
- forward(img, mask=None)[source]#
Run forward.
- Parameters:
- Return type:
- 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 Convention block of
LocalFeaturegives the frame,Nand the slots the detector did not fill, which have to be dropped before matching.
- class kornia.feature.DoGHardNet(num_features=2048, upright=False, device=None, compile_modules=False)[source]#
Detect DoG blobs over scale and describe them with HardNet, without affine adaptation.
feature = DoGHardNet(2048)loads pretrained HardNet in evaluation mode.lafs, responses, descs = feature(img)takes grayscale images(B, 1, H, W). It returns 12-sigma DoG LAFs(B, N, 2, 3), absolute DoG responses(B, N), strongest first, and unit-norm HardNet descriptors(B, N, 128). Uselaf_is_filled()to keep detections and discard padding before callingLightGlueMatcher("doghardnet"). ChooseDoGAffNetHardNetfor affine shapes orSIFTFeatureScaleSpacefor SIFT descriptors.- Convention:
A
LocalFeature, whose Convention block gives the output contract. The detector is the DoGScaleSpaceDetectorofSIFTFeatureScaleSpace’s"patch"backend, and the orientation is estimated on its 6-sigma frames. The returned LAFs are those frames scaled by two (scaling_coef=2), to 12 sigma or six times OpenCV’sKeyPoint.size, andHardNetdescribes them on 32 x 32 patches.The image must have one channel,
(B, 1, H, W): convert a color image withrgb_to_grayscale()first.
- Parameters:
num_features (
int, optional) – the number of slots per image; the strongest detections fill them, the rest are padding. Default:2048upright (
bool, optional) – ifTrue, skip the orientation estimation and return upright frames. Default:Falsedevice (
Union[str,device,None], optional) – the device of the detector and descriptor modules. Default: CPU.compile_modules (
Union[bool,List[str]], optional) – the detector sub-modules to wrap withtorch.compile(), seeScaleSpaceDetector. Default:False
See also
DoGAffNetHardNet: the same detections with AffNet shapes, estimated before the orientation.SIFTFeatureScaleSpace: the same detections with SIFT descriptors, at 6 sigma, with its"patch"backend.ScaleSpaceDetector: its detector, on aBlobDoGresponse.BlobDoG: the scale-space DoG response it detects on.HardNet: its descriptor, run on 32 x 32 patches throughLAFDescriptor.LightGlueMatcher: its"doghardnet"weights match these features.KeyNetHardNet: HardNet descriptors of KeyNet detections, one image per call.LocalFeature: its base class, which gives the output contract.
- forward(img, mask=None)[source]#
Run forward.
- Parameters:
- Return type:
- 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 Convention block of
LocalFeaturegives the frame,Nand the slots the detector did not fill, which have to be dropped before matching.
- class kornia.feature.DoGAffNetHardNet(num_features=2048, upright=False, device=None, compile_modules=False)[source]#
Detect DoG blobs over scale with AffNet shapes and HardNet descriptors.
feature = DoGAffNetHardNet(2048)loads pretrained AffNet and HardNet in evaluation mode.lafs, responses, descs = feature(img)takes grayscale images(B, 1, H, W). It returns the outputs ofDoGHardNet, with affine LAF shapes adapted by AffNet before orientation. Uselaf_is_filled()to keep detections and discard padding before callingLightGlueMatcher("dog_affnet_hardnet"). ChooseGFTTAffNetHardNetorHesAffNetHardNetfor corners or Hessian blobs.- Convention:
As
DoGHardNet, with the affine shape of each 6-sigma DoG frame estimated byLAFAffNetShapeEstimatorbefore its orientation. The scale of the returned LAFs, the square root of their determinant, is again 12 sigma. The image must have one channel,(B, 1, H, W).
- Parameters:
num_features (
int, optional) – the number of slots per image; the strongest detections fill them, the rest are padding. Default:2048upright (
bool, optional) – ifTrue, skip the orientation estimation and return upright frames. Default:Falsedevice (
Union[str,device,None], optional) – the device of the detector and descriptor modules. Default: CPU.compile_modules (
Union[bool,List[str]], optional) – the detector sub-modules to wrap withtorch.compile(), seeScaleSpaceDetector. Default:False
See also
DoGHardNet: the same detections and descriptors without affine adaptation.LAFAffNetShapeEstimator: the AffNet shape estimation it runs before the orientation.ScaleSpaceDetector: its detector, on aBlobDoGresponse.HardNet: its descriptor, run on 32 x 32 patches throughLAFDescriptor.LightGlueMatcher: its"dog_affnet_hardnet"mode matches these features.GFTTAffNetHardNet: the same shapes and descriptors on Shi-Tomasi corners.HesAffNetHardNet: the same shapes and descriptors on Hessian blobs.KeyNetAffNetHardNet: the same shapes and descriptors on KeyNet detections, one image per call.LocalFeature: its base class, which gives the output contract.
- forward(img, mask=None)[source]#
Run forward.
- Parameters:
- Return type:
- 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 Convention block of
LocalFeaturegives the frame,Nand the slots the detector did not fill, which have to be dropped before matching.
- class kornia.feature.KeyNetAffNetHardNet(num_features=8000, upright=False, device=None, scale_laf=1.0, compile_model=False, score_threshold=0.0)[source]#
Detect KeyNet keypoints with AffNet shapes and HardNet descriptors.
feature = KeyNetAffNetHardNet(2048)loads pretrained KeyNet, AffNet, OriNet and HardNet in evaluation mode.lafs, responses, descs = feature(img)takes one grayscale image(1, 1, H, W)in[0, 1]. It returns the outputs ofKeyNetHardNet, with affine LAF shapes adapted by AffNet before orientation. Uselaf_is_filled()to keep detections and discard padding before callingLightGlueMatcher("keynet_affnet_hardnet"). For batches, useDoGAffNetHardNet.
- Convention:
As
KeyNetHardNet, with the affine shape of each frame estimated byLAFAffNetShapeEstimatorbefore its orientation.
- Parameters:
num_features (
int, optional) – the number of slots; the strongest detections fill them, the rest are padding. Default:8000upright (
bool, optional) – ifTrue, skip the orientation estimation and return upright frames. Default:Falsedevice (
Union[str,device,None], optional) – the device of the detector and descriptor modules. Default: CPU.scale_laf (
float, optional) – the multiplier of the detector’s LAFs before the description. Must be positive. Default:1.0compile_model (
bool, optional) – wrap the KeyNet response and the non-maxima suppression withtorch.compile(), seeKeyNetDetector. Default:Falsescore_threshold (
float, optional) – the KeyNet response a detection has to exceed. Must be non-negative. Default:0.0
- Raises:
ValueError – if
scale_lafis not positive orscore_thresholdis negative.
See also
KeyNetHardNet: the same detections and descriptors without affine adaptation.KeyNetDetector: its detector.LAFAffNetShapeEstimator: the AffNet shape estimation it runs before the orientation.OriNet: the learned orientation, run on each LAF’s patch throughLAFOrienter.HardNet: its descriptor, run on 32 x 32 patches throughLAFDescriptor.LightGlueMatcher: its"keynet_affnet_hardnet"weights match these features.DoGAffNetHardNet: the same shapes and descriptors on DoG detections, for a batch of images.LocalFeature: its base class, which gives the output contract.
- forward(img, mask=None)[source]#
Run forward.
- Parameters:
- Return type:
- 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 Convention block of
LocalFeaturegives the frame,Nand the slots the detector did not fill, which have to be dropped before matching.
- class kornia.feature.KeyNetHardNet(num_features=8000, upright=False, device=None, scale_laf=1.0, compile_model=False, score_threshold=0.0)[source]#
Detect KeyNet keypoints and describe them with HardNet, without affine adaptation.
feature = KeyNetHardNet(2048)loads pretrained KeyNet, OriNet and HardNet in evaluation mode.lafs, responses, descs = feature(img)takes one grayscale image(1, 1, H, W)in[0, 1]; a batch or color image raises. It returns LAFs(1, N, 2, 3), KeyNet responses(1, N), strongest first, and unit-norm HardNet descriptors(1, N, 128). Uselaf_is_filled()to keep detections and discard padding. ChooseKeyNetAffNetHardNetfor AffNet shapes and its LightGlue weights. For batches, useDoGHardNet.- Convention:
A
LocalFeature, whose Convention block gives the output contract, of one grayscale image per call,(1, 1, H, W): aKeyNetDetector, whose LAFs get their orientation fromOriNeton 32 x 32 patches unlessupright, and are described byHardNeton 32 x 32 patches.scale_lafis thescaling_coefofLocalFeature: it multiplies the detector’s LAFs before the description.
- Parameters:
num_features (
int, optional) – the number of slots; the strongest detections fill them, the rest are padding. Default:8000upright (
bool, optional) – ifTrue, skip the orientation estimation and return upright frames. Default:Falsedevice (
Union[str,device,None], optional) – the device of the detector and descriptor modules. Default: CPU.scale_laf (
float, optional) – the multiplier of the detector’s LAFs before the description. Must be positive. Default:1.0compile_model (
bool, optional) – wrap the KeyNet response and the non-maxima suppression withtorch.compile(), seeKeyNetDetector. Default:Falsescore_threshold (
float, optional) – the KeyNet response a detection has to exceed. Must be non-negative. Default:0.0
- Raises:
ValueError – if
scale_lafis not positive orscore_thresholdis negative.
See also
KeyNetAffNetHardNet: the same detections with AffNet shapes, estimated before the orientation.KeyNetDetector: its detector.KeyNet: the learned response it detects on.OriNet: the learned orientation, run on each LAF’s patch throughLAFOrienter.HardNet: its descriptor, run on 32 x 32 patches throughLAFDescriptor.DoGHardNet: HardNet descriptors of DoG detections, for a batch of images.LocalFeature: its base class, which gives the output contract.
- forward(img, mask=None)[source]#
Run forward.
- Parameters:
- Return type:
- 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 Convention block of
LocalFeaturegives the frame,Nand the slots the detector did not fill, which have to be dropped before matching.