class_docstr: Module, which finds correspondences between two images based on local features.
  
  Args:
      local_feature: Local feature detector. See :class:`~kornia.feature.GFTTAffNetHardNet`.
      matcher: Descriptor matcher, see :class:`~kornia.feature.DescriptorMatcher`.
  
  Returns:
      Dict[str, Tensor]: Dictionary with image correspondences and confidence scores.
  
  Example:
      >>> img1 = torch.rand(1, 1, 320, 200)
      >>> img2 = torch.rand(1, 1, 128, 128)
      >>> input = {"image0": img1, "image1": img2}
      >>> gftt_hardnet_matcher = LocalFeatureMatcher(
      ...     GFTTAffNetHardNet(10), kornia.feature.DescriptorMatcher('snn', 0.8)
      ... )
      >>> out = gftt_hardnet_matcher(input)
class_docstr_tok: ["Module",",","which","finds","correspondences","between","two","images","based","on","local","features",".","Args",":","local_feature",":","Local","feature","detector",".","See",":","class",":","`","~kornia.feature.GFTTAffNetHardNet","`",".","matcher",":","Descriptor","matcher",",","see",":","class",":","`","~kornia.feature.DescriptorMatcher","`",".","Returns",":","Dict","[","str",",","Tensor","]",":","Dictionary","with","image","correspondences","and","confidence","scores",".","Example",":",">",">",">","img1","=","torch.rand","(","1",",","1",",","320",",","200",")",">",">",">","img2","=","torch.rand","(","1",",","1",",","128",",","128",")",">",">",">","input","=","{","``","image0","''",":","img1",",","``","image1","''",":","img2","}",">",">",">","gftt_hardnet_matcher","=","LocalFeatureMatcher","(","...","GFTTAffNetHardNet","(","10",")",",","kornia.feature.DescriptorMatcher","(","'snn","'",",","0.8",")","...",")",">",">",">","out","=","gftt_hardnet_matcher","(","input",")"]
docstr: Args:
      data: dictionary containing the input data in the following format:
  
  Keyword Args:
      image0: left image with shape :math:`(N, 1, H1, W1)`.
      image1: right image with shape :math:`(N, 1, H2, W2)`.
      mask0 (optional): left image mask. '0' indicates a padded position :math:`(N, H1, W1)`.
      mask1 (optional): right image mask. '0' indicates a padded position :math:`(N, H2, W2)`.
  
  Returns:
      - ``keypoints0``, matching keypoints from image0 :math:`(NC, 2)`.
      - ``keypoints1``, matching keypoints from image1 :math:`(NC, 2)`.
      - ``confidence``, confidence score [0, 1] :math:`(NC)`.
      - ``lafs0``, matching LAFs from image0 :math:`(1, NC, 2, 3)`.
      - ``lafs1``, matching LAFs from image1 :math:`(1, NC, 2, 3)`.
      - ``batch_indexes``, batch indexes for the keypoints and lafs :math:`(NC)`.
docstr_tok: ["Args",":","data",":","dictionary","containing","the","input","data","in","the","following","format",":","Keyword","Args",":","image0",":","left","image","with","shape",":","math",":","`","(","N",",","1",",","H1",",","W1",")","`",".","image1",":","right","image","with","shape",":","math",":","`","(","N",",","1",",","H2",",","W2",")","`",".","mask0","(","optional",")",":","left","image","mask",".","'","0","'","indicates","a","padded","position",":","math",":","`","(","N",",","H1",",","W1",")","`",".","mask1","(","optional",")",":","right","image","mask",".","'","0","'","indicates","a","padded","position",":","math",":","`","(","N",",","H2",",","W2",")","`",".","Returns",":","-","``","keypoints0","``",",","matching","keypoints","from","image0",":","math",":","`","(","NC",",","2",")","`",".","-","``","keypoints1","``",",","matching","keypoints","from","image1",":","math",":","`","(","NC",",","2",")","`",".","-","``","confidence","``",",","confidence","score","[","0",",","1","]",":","math",":","`","(","NC",")","`",".","-","``","lafs0","``",",","matching","LAFs","from","image0",":","math",":","`","(","1",",","NC",",","2",",","3",")","`",".","-","``","lafs1","``",",","matching","LAFs","from","image1",":","math",":","`","(","1",",","NC",",","2",",","3",")","`",".","-","``","batch_indexes","``",",","batch","indexes","for","the","keypoints","and","lafs",":","math",":","`","(","NC",")","`","."]
code: def forward(self, data: Dict[str, Tensor]) -> Dict[str, Tensor]:
      """
      Args:
          data: dictionary containing the input data in the following format:
  
      Keyword Args:
          image0: left image with shape :math:`(N, 1, H1, W1)`.
          image1: right image with shape :math:`(N, 1, H2, W2)`.
          mask0 (optional): left image mask. '0' indicates a padded position :math:`(N, H1, W1)`.
          mask1 (optional): right image mask. '0' indicates a padded position :math:`(N, H2, W2)`.
  
      Returns:
          - ``keypoints0``, matching keypoints from image0 :math:`(NC, 2)`.
          - ``keypoints1``, matching keypoints from image1 :math:`(NC, 2)`.
          - ``confidence``, confidence score [0, 1] :math:`(NC)`.
          - ``lafs0``, matching LAFs from image0 :math:`(1, NC, 2, 3)`.
          - ``lafs1``, matching LAFs from image1 :math:`(1, NC, 2, 3)`.
          - ``batch_indexes``, batch indexes for the keypoints and lafs :math:`(NC)`.
      """
      num_image_pairs: int = data["image0"].shape[0]
  
      if ("lafs0" not in data.keys()) or (
          "descriptors0" not in data.keys()
      ):
          # One can supply pre-extracted local features
          feats_dict0: Dict[str, Tensor] = self.extract_features(
              data["image0"]
          )
          lafs0, descs0 = (
              feats_dict0["lafs"],
              feats_dict0["descriptors"],
          )
      else:
          lafs0, descs0 = data["lafs0"], data["descriptors0"]
  
      if ("lafs1" not in data.keys()) or (
          "descriptors1" not in data.keys()
      ):
          feats_dict1: Dict[str, Tensor] = self.extract_features(
              data["image1"]
          )
          lafs1, descs1 = (
              feats_dict1["lafs"],
              feats_dict1["descriptors"],
          )
      else:
          lafs1, descs1 = data["lafs1"], data["descriptors1"]
  
      keypoints0: Tensor = get_laf_center(lafs0)
      keypoints1: Tensor = get_laf_center(lafs1)
  
      out_keypoints0: List[Tensor] = []
      out_keypoints1: List[Tensor] = []
      out_confidence: List[Tensor] = []
      out_batch_indexes: List[Tensor] = []
      out_lafs0: List[Tensor] = []
      out_lafs1: List[Tensor] = []
  
      for batch_idx in range(num_image_pairs):
          dists, idxs = self.matcher(
              descs0[batch_idx], descs1[batch_idx]
          )
          if len(idxs) == 0:
              continue
  
          current_keypoints_0 = keypoints0[batch_idx, idxs[:, 0]]
          current_keypoints_1 = keypoints1[batch_idx, idxs[:, 1]]
          current_lafs_0 = lafs0[batch_idx, idxs[:, 0]]
          current_lafs_1 = lafs1[batch_idx, idxs[:, 1]]
  
          out_confidence.append(1.0 - dists)
          batch_idxs = batch_idx * torch.ones(
              len(dists), device=keypoints0.device, dtype=torch.long
          )
          out_keypoints0.append(current_keypoints_0)
          out_keypoints1.append(current_keypoints_1)
          out_lafs0.append(current_lafs_0)
          out_lafs1.append(current_lafs_1)
          out_batch_indexes.append(batch_idxs)
  
      if len(out_batch_indexes) == 0:
          return self.no_match_output(
              data["image0"].device, data["image0"].dtype
          )
  
      return {
          "keypoints0": concatenate(out_keypoints0, dim=0).view(-1, 2),
          "keypoints1": concatenate(out_keypoints1, dim=0).view(-1, 2),
          "lafs0": concatenate(out_lafs0, dim=0).view(1, -1, 2, 3),
          "lafs1": concatenate(out_lafs1, dim=0).view(1, -1, 2, 3),
          "confidence": concatenate(out_confidence, dim=0).view(-1),
          "batch_indexes": concatenate(out_batch_indexes, dim=0).view(
              -1
          ),
      }
  
imports: import warnings
  from typing import ClassVar, Dict, List, Optional, Tuple
  import torch
  from kornia.color import rgb_to_grayscale
  from kornia.constants import pi
  from kornia.core import Device, Module, Tensor, concatenate, deg2rad
  from kornia.core.check import KORNIA_CHECK_LAF
  from kornia.geometry.subpix import ConvQuadInterp3d
  from kornia.geometry.transform import ScalePyramid
  from .affine_shape import LAFAffNetShapeEstimator
  from .hardnet import HardNet
  from .keynet import KeyNetDetector
  from .laf import extract_patches_from_pyramid, get_laf_center, get_laf_orientation, get_laf_scale, scale_laf
  from .lightglue import LightGlue
  from .matching import GeometryAwareDescriptorMatcher, _no_match
  from .orientation import LAFOrienter, OriNet, PassLAF
  from .responses import BlobDoG, BlobDoGSingle, BlobHessian, CornerGFTT
  from .scale_space_detector import Detector_config, MultiResolutionDetector, ScaleSpaceDetector, get_default_detector_config
  from .siftdesc import SIFTDescriptor
label_desc: Use image node_id 4 for calling the LocalFeatureMatcher obj's underlying member method code with example usage: obj.forward(data) and returns: dict, self