class_docstr: Module extracting line segments from junctions and line heatmaps.
  
  Args:
      detect_thresh: The probability threshold for mean activation (0. ~ 1.)
      num_samples: Number of sampling locations along the line segments.
      inlier_thresh: The min inlier ratio to satisfy (0. ~ 1.) => 0. means no threshold.
      heatmap_low_thresh: The lowest threshold for the pixel to be considered as candidate in junction recovery.
      heatmap_high_thresh: The higher threshold for NMS in junction recovery.
      max_local_patch_radius: The max patch to be considered in local maximum search.
      lambda_radius: The lambda factor in linear local maximum search formulation
      use_candidate_suppression: Apply candidate suppression to break long segments into short sub-segments.
      nms_dist_tolerance: The distance tolerance for nms. Decide whether the junctions are on the line.
      use_heatmap_refinement: Use heatmap refinement method or not.
      heatmap_refine_cfg: The configs for heatmap refinement methods.
      use_junction_refinement: Use junction refinement method or not.
      junction_refine_cfg: The configs for junction refinement methods.
docstr: Detection by local maximum search.
docstr_tok: ["Detection","by","local","maximum","search","."]
code: def detect_local_max(
      self,
      heatmap: Tensor,
      cand_h: Tensor,
      cand_w: Tensor,
      H: int,
      W: int,
      normalized_seg_length: Tensor,
      device: torch.device,
  ) -> Tensor:
      """Detection by local maximum search."""
      # Compute the distance threshold
      dist_thresh = (
          0.5 * (2**0.5) + self.lambda_radius * normalized_seg_length
      )
      # Make it N x 64
      dist_thresh = torch.repeat_interleave(
          dist_thresh[..., None], self.num_samples, dim=-1
      )
  
      # Compute the candidate points
      cand_points = concatenate(
          [cand_h[..., None], cand_w[..., None]], -1
      )
      cand_points_round = torch.round(cand_points)  # N x 64 x 2
  
      # Construct local patches 9x9 = 81
      patch_mask = zeros(
          [
              int(2 * self.local_patch_radius + 1),
              int(2 * self.local_patch_radius + 1),
          ],
          device=device,
      )
      patch_center = tensor(
          [[self.local_patch_radius, self.local_patch_radius]],
          device=device,
          dtype=torch.float32,
      )
      H_patch_points, W_patch_points = where(patch_mask >= 0)
      patch_points = concatenate(
          [H_patch_points[..., None], W_patch_points[..., None]], -1
      )
      # Fetch the circle region
      patch_center_dist = torch.sqrt(
          torch.sum((patch_points - patch_center) ** 2, dim=-1)
      )
      patch_points = patch_points[
          patch_center_dist <= self.local_patch_radius, :
      ]
      # Shift [0, 0] to the center
      patch_points = patch_points - self.local_patch_radius
  
      # Construct local patch mask
      patch_points_shifted = (
          torch.unsqueeze(cand_points_round, dim=2)
          + patch_points[None, None]
      )
      patch_dist = torch.sqrt(
          torch.sum(
              (
                  torch.unsqueeze(cand_points, dim=2)
                  - patch_points_shifted
              )
              ** 2,
              dim=-1,
          )
      )
      patch_dist_mask = patch_dist < dist_thresh[..., None]
  
      # Get all points => num_points_center x num_patch_points x 2
      points_H = torch.clamp(
          patch_points_shifted[:, :, :, 0], min=0, max=H - 1
      ).to(torch.long)
      points_W = torch.clamp(
          patch_points_shifted[:, :, :, 1], min=0, max=W - 1
      ).to(torch.long)
      points = concatenate(
          [points_H[..., None], points_W[..., None]], -1
      )
  
      # Sample the feature (N x 64 x 81)
      sampled_feat = heatmap[points[:, :, :, 0], points[:, :, :, 1]]
      # Filtering using the valid mask
      sampled_feat = sampled_feat * patch_dist_mask.to(torch.float32)
      if len(sampled_feat) == 0:
          sampled_feat_lmax = torch.empty(0, self.num_samples)
      else:
          sampled_feat_lmax = torch.max(sampled_feat, dim=-1)[0]
  
      return sampled_feat_lmax
  
imports: import math
  from typing import Any, Dict, Optional, Tuple
  import torch
  from kornia.core import Module, Tensor, concatenate, sin, stack, tensor, where, zeros
  from kornia.core.check import KORNIA_CHECK_SHAPE
  from kornia.geometry.bbox import nms
  from kornia.utils import map_location_to_cpu, torch_meshgrid
  from .backbones import SOLD2Net
label_desc: Use image node_id 9 for calling the LineSegmentDetectionModule obj's underlying member method code with example usage: obj.detect_local_max(heatmap, cand_h, cand_w, H, W, normalized_seg_length, device) and returns: sampled_feat_lmax