class_docstr: Module, which extracts patches using input images and local affine frames (LAFs).
  
  Then runs :class:`~kornia.feature.PatchDominantGradientOrientation` or
  :class:`~kornia.feature.OriNet` on patches and then rotates the LAFs by the estimated angles
  
  Args:
      patch_size:
      num_angular_bins:
      angle_detector: Patch orientation estimator, e.g. :class:`~kornia.feature.PatchDominantGradientOrientation`
        or OriNet.
class_docstr_tok: ["Module",",","which","extracts","patches","using","input","images","and","local","affine","frames","(","LAFs",")",".","Then","runs",":","class",":","`","~kornia.feature.PatchDominantGradientOrientation","`","or",":","class",":","`","~kornia.feature.OriNet","`","on","patches","and","then","rotates","the","LAFs","by","the","estimated","angles","Args",":","patch_size",":","num_angular_bins",":","angle_detector",":","Patch","orientation","estimator",",","e.g",".",":","class",":","`","~kornia.feature.PatchDominantGradientOrientation","`","or","OriNet","."]
docstr: Args:
      laf: :math:`(B, N, 2, 3)`
      img: :math:`(B, 1, H, W)`
  
  Returns:
      LAF_out: :math:`(B, N, 2, 3)`
docstr_tok: ["Args",":","laf",":",":","math",":","`","(","B",",","N",",","2",",","3",")","`","img",":",":","math",":","`","(","B",",","1",",","H",",","W",")","`","Returns",":","LAF_out",":",":","math",":","`","(","B",",","N",",","2",",","3",")","`"]
code: def forward(
      self, laf: torch.Tensor, img: torch.Tensor
  ) -> torch.Tensor:
      """
      Args:
          laf: :math:`(B, N, 2, 3)`
          img: :math:`(B, 1, H, W)`
  
      Returns:
          LAF_out: :math:`(B, N, 2, 3)`
      """
      KORNIA_CHECK_LAF(laf)
      KORNIA_CHECK_SHAPE(img, ["B", "C", "H", "W"])
      if laf.size(0) != img.size(0):
          raise ValueError(
              f"Batch size of laf and img should be the same. Got {img.size(0)}, {laf.size(0)}"
          )
      B, N = laf.shape[:2]
      patches: torch.Tensor = extract_patches_from_pyramid(
          img, laf, self.patch_size
      ).view(-1, 1, self.patch_size, self.patch_size)
      angles_radians: torch.Tensor = self.angle_detector(patches).view(
          B, N
      )
      prev_angle = get_laf_orientation(laf).view_as(angles_radians)
      laf_out: torch.Tensor = set_laf_orientation(
          laf, rad2deg(angles_radians) + prev_angle
      )
      return laf_out
  
imports: from typing import Dict, Optional
  import torch
  import torch.nn.functional
  from torch import nn
  from kornia.constants import pi
  from kornia.core.check import KORNIA_CHECK_LAF, KORNIA_CHECK_SHAPE
  from kornia.filters import SpatialGradient, get_gaussian_discrete_kernel1d, get_gaussian_kernel2d
  from kornia.geometry import rad2deg
  from kornia.utils.helpers import map_location_to_cpu
  from .laf import extract_patches_from_pyramid, get_laf_orientation, set_laf_orientation
label_desc: Use image node_id 3 for calling the LAFOrienter obj's underlying member method code with example usage: obj.forward(laf, img) and returns: laf_out