Descriptors#
Choosing a SIFT descriptor interface#
These interfaces serve different inputs and outputs; none detects keypoints. For detection and description together, use the SIFT pipeline guide.
Interface |
Input |
Output and purpose |
|---|---|---|
Canonically sampled grayscale patches |
One descriptor per patch, |
|
A grayscale image |
A dense descriptor map |
|
A grayscale image and supplied, already oriented LAFs |
Sparse descriptors |
All three support RootSIFT normalization. They return kornia’s angle-major layout;
convert_sift_descriptor_layout() reorders bins to OpenCV’s layout. Layout
conversion does not make differently sampled descriptors numerically equivalent.
The converter expects the descriptor dimension last. For a dense map, move its
channels last before conversion and restore them afterwards:
opencv_dense = convert_sift_descriptor_layout(
dense.movedim(1, -1), "kornia", "opencv"
).movedim(-1, 1)
SIFTDescriptorFromPyramid builds its own pyramid rather than reusing a
detector’s Gaussian layers. It constructs histogram maps only for octaves used by
valid supplied frames, which can reduce work and memory for frames concentrated
in a few octaves. See the recorded
octave-selection measurements.
General affine frames use an approximate angular remapping and spatial pooling;
this is not numerically identical to patch extraction.
Its orient_and_describe(image, lafs) method additionally estimates orientation,
integrating smoothed gradients before angular binning; this is the orientation
used by SIFTFeature(descriptor_backend="pyramid"). Its performance and accuracy
acceptance criteria are tracked in #5748;
they do not concern the descriptor-only forward use on supplied oriented LAFs.
The validation and possible deprecation plan retains all
three standalone descriptor interfaces.
API reference#
- class kornia.feature.DenseSIFTDescriptor(num_ang_bins=8, num_spatial_bins=4, spatial_bin_size=4, rootsift=True, clipval=0.2, stride=1, padding=1)[source]#
nn.Module, which computes SIFT descriptor densely over the image.
- Convention:
Every output pixel is a SIFT descriptor of the image around the input position given below. Its
num_spatial_binsxnum_spatial_binscells arespatial_bin_sizepixels apart, each cell pooling a triangular window ofspatial_bin_sizepixels (seeget_sift_pooling_kernel), so the cells tile an extent ofnum_spatial_bins * spatial_bin_sizepixels. The cell spacing is that ofSIFTDescriptorand of the VLFeatvl_dsiftgrid.Output pixel
(i, j)describes the neighbourhood centred on the input positionx = j * stride - padding + (num_spatial_bins - 1) * spatial_bin_size / 2 - e / 2(ylikewise fromi), in pixel-centre coordinates where the first input pixel is at 0, withe1 for an evenspatial_bin_sizeand 0 for an odd one. The centre lies on a pixel when(num_spatial_bins - 1) * spatial_bin_sizeandehave the same parity, and half way between two pixels otherwise.The channels are in kornia’s angle-major SIFT layout, channel
a * num_spatial_bins**2 + cy * num_spatial_bins + cxfor angle binaand cell(cy, cx), the entry order ofSIFTDescriptor; move them last beforeconvert_sift_descriptor_layout(). Clipping, RootSIFT (the default) and the output for a flat neighbourhood are those ofSIFTDescriptor(see its Convention block), but the cells are not weighted by a Gaussian window.
- Parameters:
num_ang_bins (
int, optional) – Number of angular bins. (8 is default) Default:8num_spatial_bins (
int, optional) – Number of spatial bins per descriptor (4 is default). With an oddnum_spatial_binsand an oddspatial_bin_size,padding = (num_spatial_bins - 1) * spatial_bin_size / 2keeps the feature map size atstride=1. Default:4spatial_bin_size (
int, optional) – Size of a spatial bin in pixels, and the distance between neighbouring bins (4 is default) Default:4clipval (
float, optional) – clipping value to reduce single-bin dominance Default:0.2rootsift (
bool, optional) – (bool) if True, RootSIFT (Arandjelović et. al, 2012) is computed Default:Truestride (
int, optional) – step between neighbouring outputs in pixels (1 is default) Default:1padding (
int, optional) – zero padding of the pooled bin maps in pixels, on every side (1 is default) Default:1
- Returns:
DenseSIFT descriptor of the image
- Return type:
- Shape:
Input: (B, 1, H, W)
Output: (B, num_ang_bins * num_spatial_bins ** 2, H_out, W_out), with
H_out = (H + e + 2 * padding - (num_spatial_bins - 1) * spatial_bin_size - 1) // stride + 1andW_outlikewise, whereeis 1 for an evenspatial_bin_sizeand 0 for an odd one.
- Examples::
>>> input = torch.rand(2, 1, 200, 300) >>> SIFT = DenseSIFTDescriptor() >>> descs = SIFT(input) # 2x128x191x291
- class kornia.feature.SIFTDescriptorFromPyramid(num_ang_bins=8, num_spatial_bins=4, spatial_bin_size=8, rootsift=True, clipval=0.2, orientation_bins=36)[source]#
Extract sparse SIFT descriptors from a shared image-gradient pyramid.
This module does not detect keypoints or return a dense descriptor map.
forward(image, lafs)describes the supplied, already oriented LAFs.orient_and_describe()additionally assigns their orientation while sharing one pyramid between orientation assignment and description. The pyramid belongs to this descriptor; it is not reused from the detector.The performance and accuracy acceptance criteria of its automatic orientation are tracked in #5748. See Choosing a SIFT descriptor interface for the distinct patch, dense-map and supplied-frame descriptor contracts.
The module combines the shared histogram maps of VLFeat DSIFT with orientation-relative spatial and angular binning as in OpenCV’s SIFT implementation: descriptor gradients are binned once at each pyramid octave. Orientation uses a separate gradient field, smoothed with a one-pixel Gaussian at each octave, and integrates 19x19 gradient samples with a Gaussian of sigma one third of the LAF scale. Gradients are transformed into the frame before orientation histogramming, avoiding interpolation of already quantized angular bins. Unlike patch-wise SIFT, no image patch is resampled before either stage.
For a general affine LAF the global angular bins are remapped through the LAF’s
A.Tgradient pullback, including its direction-dependent magnitude. This makes affine frames useful without extracting patches, but is an approximation: a histogram bin represents every gradient in its angular interval by its centre direction, and spatial pooling is performed in the image pyramid before the affine footprint is sampled.- Convention:
lafsare in the pixel frame ofimage, with the layout oflaf_from_center_scale_ori()(see Local features). Cell(i, j)of thenum_spatial_binsxnum_spatial_binsgrid is centred atc + A (u_j, u_i)withu_k = (2 k + 1) / num_spatial_bins - 1, at whichever octave the LAF selects: the cell centres of anum_spatial_bins-pixel patch fromextract_patches_from_pyramid(), row 0 on the frame’s \(-y\) side.orient_and_describe(), unlessupright=True, rotates each valid frame so that its dominant gradient, measured in the frame’s own coordinates, points along the frame’s \(+x\) axis, whatever orientation the frame had. This is the orientation convention ofLAFOrienter, and it puts that gradient direction in the descriptor’s angle bin 0.A frame that
laf_is_valid()rejects, such as the all-zero padding LAF, gets an all-zero descriptor, with or without RootSIFT, andorient_and_describe()returns the frame unchanged.SIFTDescriptorinstead describes the flat patch that a zero LAF extracts by1e-5in every entry with RootSIFT.Clipping, RootSIFT (the default) and kornia’s angle-major layout are those of
SIFTDescriptor, whose Convention block gives them;convert_sift_descriptor_layout()reorders the descriptors to OpenCV’s.
- Parameters:
num_ang_bins (
int, optional) – Number of descriptor angular bins. Default:8num_spatial_bins (
int, optional) – Number of descriptor spatial bins per axis. Default:4spatial_bin_size (
int, optional) – Side of the DenseSIFT spatial pooling window, in pixels. The default 8 approximately matches the 19-pixel octave support to the patch SIFT descriptor’s 17-pixel pooling bins at its default 41-pixel patch. Default:8rootsift (
bool, optional) – IfTrue, apply RootSIFT after clipping and normalization. Default:Trueclipval (
float, optional) – Descriptor clipping threshold. Default:0.2orientation_bins (
int, optional) – Number of bins for dominant-orientation assignment. Independent of the descriptor’s global histogram resolution (at least 36 bins), which is remapped tonum_ang_binsin each local frame. Default:36
- Shape:
image: \((B, 1, H, W)\)
lafs: \((B, N, 2, 3)\) in image pixel coordinates
descriptors: \((B, N, num_ang_bins * num_spatial_bins^2)\)
- forward(image, lafs)[source]#
Describe supplied oriented frames without detecting or reorienting them.
- Parameters:
- Return type:
- Returns:
Sparse descriptors of shape
(B, N, num_ang_bins * num_spatial_bins**2), with the image dtype and device. Invalid frames receive zero descriptors.
- orient_and_describe(image, lafs, upright=False)[source]#
Orient and describe sparse frames, building the extraction pyramid once.
- Parameters:
- Return type:
- Returns:
Oriented frames in the input LAF dtype and descriptors in the image dtype, both on the image device. Invalid frames are preserved and receive zero descriptors. Empty frame sets are supported.
- class kornia.feature.SIFTDescriptor(patch_size=41, num_ang_bins=8, num_spatial_bins=4, rootsift=True, clipval=0.2)[source]#
nn.Module which computes SIFT descriptors of given patches.
- Convention:
The input is a stack of grayscale patches,
patch_sizepixels square (41 by default; another size raises), with rows along \(+y\) and columns along \(+x\), asextract_patches_from_pyramid()samples them from LAFs (see Local features).The output is in kornia’s angle-major SIFT layout, which
convert_sift_descriptor_layout()defines and reorders to OpenCV’s. In the patch of a LAF oriented byLAFOrienter, the dominant gradient direction it found points along \(+x\), the centre of angle bin 0.The
num_spatial_binsxnum_spatial_binsgrid of spatial cells and the Gaussian weighting window are both centred on the patch centre \((\text{patch\_size} - 1) / 2\);get_sift_bin_ksize_stride_padgives the cell spacing and pooling kernel. A patch mirrored upside down therefore has a descriptor that is a permutation of the original’s; so does a patch mirrored left to right whennum_ang_binsis even, and atorch.rot90-rotated one whennum_ang_binsis a multiple of four, as the default 8 is.The descriptor is L2-normalised, clipped at
clipvaland L2-normalised again, so an output entry can exceedclipval. Withrootsift=True, the default, it is then L1-normalised and square-rooted (RootSIFT). Either way a row has unit L2 norm, except for a flat patch: it has no gradient and gives an all-zero descriptor, or1e-5in every entry with RootSIFT. OpenCV’scv2.SIFTreturns therootsift=Falsedescriptor scaled to an L2 norm of about 512 and rounded to integers.An intensity change \(a x + b\) with \(a > 0\) gives the same descriptor unless it leaves the patch nearly flat, so a patch in
[0, 1]and the same patch in[0, 255]give one descriptor.
- Parameters:
patch_size (
int, optional) – Input patch size in pixels. Default:41num_ang_bins (
int, optional) – Number of angular bins. Default:8num_spatial_bins (
int, optional) – Number of spatial bins. Default:4clipval (
float, optional) – clipping value to reduce single-bin dominance Default:0.2rootsift (
bool, optional) – ifTrue, RootSIFT (Arandjelović et. al, 2012) is computed. Default:True
- Returns:
SIFT descriptor of the patches.
- Shape:
Input: \((B, 1, \text{patch_size}, \text{patch_size})\)
Output: \((B, \text{num_ang_bins * num_spatial_bins ** 2})\)
Example
>>> input = torch.rand(23, 1, 32, 32) >>> SIFT = SIFTDescriptor(32, 8, 4) >>> descs = SIFT(input) # 23x128
- kornia.feature.convert_sift_descriptor_layout(descriptors, source, target, num_ang_bins=8, num_spatial_bins=4)[source]#
Reorder SIFT descriptors between kornia’s layout and OpenCV’s.
Both layouts hold the same histogram values, one per angle bin \(a\) and spatial cell \((y, x)\) of the frame, with \(A\) =
num_ang_binsand \(S\) =num_spatial_bins:"kornia", the layout of every kornia SIFT descriptor (SIFTDescriptor,SIFTDescriptorFromPyramid, the channels ofDenseSIFTDescriptor, andSIFTFeatureandSIFTFeatureScaleSpacewith eitherdescriptor_backend): angle-major, value \((a, y, x)\) at index \(a S^2 + y S + x\). Bin \(a\) is centred on the direction \(2 \pi a / A\), measured from \(+x\) towards \(+y\), with \(y\) growing downwards as image rows do."opencv", the layout of OpenCV’scv2.SIFT: spatial-major, index \((y S + x) A + a'\), with angles measured from \(+x\) towards \(-y\). A gradient in kornia’s bin \(a\) falls in OpenCV’s bin \(a' = -a \bmod A\).
LightGlue’s
"sift"weights expect the"opencv"layout: convert kornia descriptors before passing them toLightGlueMatcherwith"sift". The conversion only reorders values, so it applies equally to SIFT and RootSIFT descriptors and keeps their scale; converting back restores the input exactly.- Parameters:
descriptors (
Tensor) – SIFT descriptors of shape \((*, A S^2)\).source (
str) – layout ofdescriptors,"kornia"or"opencv".target (
str) – layout to return,"kornia"or"opencv".num_ang_bins (
int, optional) – number of angle bins \(A\). Default:8num_spatial_bins (
int, optional) – number of spatial bins \(S\) per side. Default:4
- Return type:
- Returns:
The descriptors in the
targetlayout, with the input’s shape, dtype and device.
Example
>>> descs = SIFTDescriptor(32)(torch.rand(4, 1, 32, 32)) >>> opencv_descs = convert_sift_descriptor_layout(descs, "kornia", "opencv") >>> torch.equal(convert_sift_descriptor_layout(opencv_descs, "opencv", "kornia"), descs) True
- class kornia.feature.MKDDescriptor(patch_size=32, kernel_type='concat', whitening='pcawt', training_set='liberty', output_dims=128)[source]#
nn.Module that computes Multiple Kernel local descriptors.
This is based on the paper “Understanding and Improving Kernel Local Descriptors”. See [MTB+19] for more details.
- Convention:
Patches are
(B, 1, patch_size, patch_size):patch_sizemust be the input’s size, and another size raisesShapeError. The kernels are centred on the patch centre \((\text{patch\_size} - 1) / 2\).The descriptor has unit L2 norm, and an intensity change \(a x + b\) with \(a > 0\) gives the same descriptor unless it leaves the patch nearly flat. The exception is a flat float16 patch with
whitening=None: the1e-8added to the gradient magnitudes underflows in float16, and the descriptor is all zero.With whitening the descriptor is \(\min(\text{output\_dims}, E)\) wide, where \(E\) is the width of the kernel embedding: 238 for
'concat', 175 for'polar'and 63 for'cart'. Withwhitening=Noneit is that embedding, \(E\) wide whateveroutput_dimssays. Constructing a whitened descriptor loads its whitening model, and downloads it then if it is not cached yet;whitening=Noneneeds no download.
- Parameters:
patch_size (
int, optional) – Input patch size in pixels. Default:32kernel_type (
str, optional) – Parametrization of kernel'concat','cart','polar'. Default:"concat"whitening (
str, optional) – Whitening transform to applyNone,'lw','pca','pcawt','pcaws'. Default:"pcawt"training_set (
str, optional) – Set that model was trained on'liberty','notredame','yosemite'. Default:"liberty"output_dims (
int, optional) – Width of the whitened descriptor, at most the embedding width; ignored withwhitening=None. Default:128
- Returns:
Descriptors of the patches, of unit norm except as stated in the Convention block.
- Shape:
Input: \((B, 1, \text{patch\_size}, \text{patch\_size})\).
Output: \((B, D)\), with \(D\) as in the Convention block.
Examples
>>> patches = torch.rand(23, 1, 32, 32) >>> mkd = MKDDescriptor(patch_size=32, ... kernel_type='concat', ... whitening='pcawt', ... training_set='liberty', ... output_dims=128) >>> desc = mkd(patches) # 23x128
- class kornia.feature.HardNet(pretrained=False)[source]#
Module, which computes HardNet descriptors of given grayscale patches of 32x32.
This is based on the original code from paper “Working hard to know your neighbor’s margins: Local descriptor learning loss”. See [MMRM17] for more details.
- Convention:
Patches are
(B, 1, 32, 32), one grayscale channel, and another shape raises;patch_sizeis a class attribute.get_laf_descriptors()extracts such patches from LAFs at its defaultpatch_size, sampled asextract_patches_from_pyramid()describes (see Local features).HardNet8,SOSNet,TFeatandHyNettake the same patches.The intensity range does not matter: HardNet and HardNet8 standardise each patch to zero mean and unit standard deviation, and SOSNet and TFeat start with an
InstanceNorm2d, so \(a x + b\) with \(a > 0\) gives the same descriptor unless it leaves the patch nearly flat. That InstanceNorm adds1e-5to the variance, so for SOSNet and TFeat a low-contrast patch in[0, 1]can already give a different descriptor than the same patch in[0, 255]. HyNet is invariant to a scale only; see its Convention block.The descriptors have unit L2 norm, except TFeat’s (see its Convention block); with
pretrained=False, HardNet and HardNet8 map a flat patch to an all-zero descriptor.pretrained=False, the default, leaves the weights randomly initialised.
- Parameters:
pretrained (
bool, optional) – Download and set pretrained weights to the model. Default:False- Returns:
HardNet descriptor of the patches.
- Return type:
- Shape:
Input: \((B, 1, 32, 32)\)
Output: \((B, 128)\)
Examples
>>> input = torch.rand(16, 1, 32, 32) >>> hardnet = HardNet() >>> descs = hardnet(input) # 16x128
- class kornia.feature.HardNet8(pretrained=False)[source]#
Module, which computes HardNet8 descriptors of given grayscale patches of 32x32.
This is based on the original code from paper “Improving the HardNet Descriptor”. See [Pul20] for more details.
- Convention:
See the Convention block on
HardNet.
- Parameters:
pretrained (
bool, optional) – Download and set pretrained weights to the model. The 512-d features are projected to 128-d by a PCA stored with the weights; without them, the projection keeps the first 128 features. Default:False- Returns:
HardNet8 descriptor of the patches.
- Return type:
- Shape:
Input: \((B, 1, 32, 32)\)
Output: \((B, 128)\)
Examples
>>> input = torch.rand(16, 1, 32, 32) >>> hardnet = HardNet8() >>> descs = hardnet(input) # 16x128
- class kornia.feature.HyNet(pretrained=False, is_bias=True, is_bias_FRN=True, dim_desc=128, drop_rate=0.3, eps_l2_norm=1e-10)[source]#
nn.Module, which computes HyNet descriptors of given grayscale patches of 32x32.
This is based on the original code from paper “HyNet: Learning Local Descriptor with Hybrid Similarity Measure and Triplet Loss”. See [TBLN+20] for more details.
- Convention:
It takes the
(B, 1, 32, 32)patches ofHardNetand returns unit-norm rows, but its first layer is aFilterResponseNorm2don the raw patch, which divides by the root mean square and subtracts no mean, as in the reference implementation. A scale \(a x\) with \(a > 0\) therefore gives the same descriptor as long as the mean squares of the patch and of its scaled copy are both large compared with that layer’seps, while an offset \(x + b\) changes it: feed non-negative intensities such as[0, 1]or[0, 255], not mean-subtracted or standardised patches.
- Parameters:
pretrained (
bool, optional) – Download and set pretrained weights to the model. Default:Falseis_bias (
bool, optional) – use bias in the convolution layers (the final 8 x 8 convolution has none either way) Default:Trueis_bias_FRN (
bool, optional) – use bias in FRN layers Default:Truedim_desc (
int, optional) – descriptor dimensionality, Default:128drop_rate (
float, optional) – dropout rate, Default:0.3eps_l2_norm (
float, optional) – to avoid div by zero Default:1e-10
- Returns:
HyNet descriptor of the patches.
- Shape:
Input: \((B, 1, 32, 32)\)
Output: \((B, \text{dim\_desc})\)
Note
With float16 weights, the final BatchNorm keeps its running statistics in float32. Convert the model to float16 before calling
torch.jit.script.Examples
>>> input = torch.rand(16, 1, 32, 32) >>> hynet = HyNet() >>> descs = hynet(input) # 16x128
- class kornia.feature.TFeat(pretrained=False)[source]#
Module, which computes TFeat descriptors of given grayscale patches of 32x32.
This is based on the original code from paper “Learning local feature descriptors with triplets and shallow convolutional neural networks”. See [BRPM16] for more details
- Convention:
It takes the patches of
HardNet, with the intensity rule of HardNet’s Convention block, but returns the finaltanhlayer of the reference implementation without L2 normalisation: each entry lies in[-1, 1]and the rows are not unit vectors. Normalise them where a distance threshold assumes unit descriptors.
- Parameters:
pretrained (
bool, optional) – Download and set pretrained weights to the model. Default:False- Returns:
TFeat descriptor of the patches.
- Return type:
- Shape:
Input: \((B, 1, 32, 32)\)
Output: \((B, 128)\)
Examples
>>> input = torch.rand(16, 1, 32, 32) >>> tfeat = TFeat() >>> descs = tfeat(input) # 16x128
- class kornia.feature.SOSNet(pretrained=False)[source]#
128-dimensional SOSNet model definition for 32x32 patches.
This is based on the original code from paper “SOSNet:Second Order Similarity Regularization for Local Descriptor Learning”.
- Convention:
See the Convention block on
HardNet.
- Parameters:
pretrained (
bool, optional) – Download and set pretrained weights to the model. Default:False
- Shape:
Input: \((B, 1, 32, 32)\)
Output: \((B, 128)\)
Note
With float16 weights, the final BatchNorm keeps its running statistics in float32. Convert the model to float16 before calling
torch.jit.script.Examples
>>> input = torch.rand(8, 1, 32, 32) >>> sosnet = SOSNet() >>> descs = sosnet(input) # 8x128
- class kornia.feature.LAFDescriptor(patch_descriptor_module=None, patch_size=32, grayscale_descriptor=True)[source]#
nn.Module to get local descriptors, corresponding to LAFs (keypoints).
- Convention:
See the Convention block on
get_laf_descriptors(), whichforwardcalls with this module’spatch_sizeandgrayscale_descriptor. The default descriptor is a pretrainedHardNeton32 x 32grayscale patches;SIFTDescriptordefaults to 41-pixel patches, so passpatch_size=41with it.
- Parameters:
patch_descriptor_module (
Optional[Module], optional) – patch descriptor module, e.g.SIFTDescriptororHardNet. Default:HardNetwith pretrained weights.patch_size (
int, optional) – patch size in pixels, which descriptor expects. Default:32grayscale_descriptor (
bool, optional) –Trueif patch_descriptor expects single-channel image; a 3-channel image is then converted to grayscale. Default:True
- class kornia.feature.SOLD2(pretrained=True, config=None)[source]#
nn.Module, which detects and describe 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.
- Convention:
forward()takes the input and returns the heatmaps and the(row, col)line segments ofSOLD2_detector, whose Convention block gives their frame and order, and alsodense_desc, \((B, 128, H / 4, W / 4)\), which is not normalized.matchtakes segments asforward()returns them and the descriptor map of one image each. It returns an int64 tensor \((N_1,)\): for each segment ofline_seg1, the index of its match inline_seg2, or-1. It is int64 also when either set of segments is empty: an empty tensor whenline_seg1is,-1for every segment ofline_seg1whenline_seg2is.Known defects: on CPU,
matchpasses float16 and bfloat16 descriptor maps to torch’sgrid_samplewithout an upcast: the half-precision kernel can return wrong values, NaN or overflow, and where torch has none the call raises (#5810).
- Parameters:
config (
Optional[DetectorCfg], optional) –DetectorCfg, or a dict of its fields, specifying parameters. None will load the default parameters, which are tuned for images in the range 400~800 px. The model works on a copy withuse_descriptorset to True; the object passed in is not modified. Default:Nonepretrained (
bool, optional) – If True, download and set pretrained weights to the model. Default:True
- Returns:
The raw junction and line heatmaps, the semi-dense descriptor map, as well as the list of detected line segments (ij coordinates convention).
Example
>>> images = torch.rand(2, 1, 64, 64) >>> sold2 = SOLD2() >>> outputs = sold2(images) >>> line_seg1 = outputs["line_segments"][0] >>> line_seg2 = outputs["line_segments"][1] >>> desc1 = outputs["dense_desc"][0] >>> desc2 = outputs["dense_desc"][1] >>> matches = sold2.match(line_seg1, line_seg2, desc1[None], desc2[None])
- 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)\). dense_desc: the semi-dense descriptor map of shape \((B, 128, H/4, W/4)\).
- Return type:
line_segments
- kornia.feature.get_laf_descriptors(img, lafs, patch_descriptor, patch_size=32, grayscale_descriptor=True)[source]#
Get local descriptors, corresponding to LAFs (keypoints).
- Convention:
The descriptor sees the patches of
extract_patches_from_pyramid()atpatch_size; see its Convention block for how they are sampled.patch_sizeis this argument, 32 by default, and is not read from the descriptor, so it has to be a size the descriptor accepts.With
grayscale_descriptor=True, a 3-channel image is converted to grayscale first.The descriptor runs in eval mode, with its floating-point parameters and buffers cast to the device and dtype of
imgfor the call (a TorchScript module is called on a cast copy). SOSNet and HyNet retain their final BatchNorm statistics in float32 for float16 images. The module keeps its device, dtype and parameters, every submodule is switched to eval for the call and gets its train/eval mode back afterwards, and gradients reach the module’s parameters.An empty LAF set gives a \((B, 0, D)\) result,
Das wide as a non-empty result, and a warning. That result does not require grad, so no gradient reachesimgor the descriptor’s parameters through it.
- Parameters:
img (
Tensor) – image features with shape \((B,C,H,W)\).lafs (
Tensor) – local affine frames \((B,N,2,3)\).patch_descriptor (
Module) – patch descriptor module, e.g.SIFTDescriptororHardNet.patch_size (
int, optional) – patch size in pixels, which descriptor expects. Default:32grayscale_descriptor (
bool, optional) – True ifpatch_descriptorexpects single-channel image; a 3-channelimgis then converted to grayscale. Default:True
- Return type:
- Returns:
Local descriptors of shape \((B,N,D)\) where \(D\) is descriptor size.