class_docstr: This module is modified from torchvision to support both 2D and 3D images.
  
  Module that generates anchors for a set of feature maps and
  image sizes.
  
  The module support computing anchors at multiple sizes and aspect ratios
  per feature map.
  
  sizes and aspect_ratios should have the same number of elements, and it should
  correspond to the number of feature maps.
  
  sizes[i] and aspect_ratios[i] can have an arbitrary number of elements.
  For 2D images, anchor width and height w:h = 1:aspect_ratios[i,j]
  For 3D images, anchor width, height, and depth w:h:d = 1:aspect_ratios[i,j,0]:aspect_ratios[i,j,1]
  
  AnchorGenerator will output a set of sizes[i] * aspect_ratios[i] anchors
  per spatial location for feature map i.
  
  Args:
      sizes: base size of each anchor.
          len(sizes) is the number of feature maps, i.e., the number of output levels for
          the feature pyramid network (FPN).
          Each element of ``sizes`` is a Sequence which represents several anchor sizes for each feature map.
      aspect_ratios: the aspect ratios of anchors. ``len(aspect_ratios) = len(sizes)``.
          For 2D images, each element of ``aspect_ratios[i]`` is a Sequence of float.
          For 3D images, each element of ``aspect_ratios[i]`` is a Sequence of 2 value Sequence.
      indexing: choose from {``'ij'``, ``'xy'``}, optional,
          Matrix (``'ij'``, default and recommended) or Cartesian (``'xy'``) indexing of output.
  
          - Matrix (``'ij'``, default and recommended) indexing keeps the original axis not changed.
          - To use other monai detection components, please set ``indexing = 'ij'``.
          - Cartesian (``'xy'``) indexing swaps axis 0 and 1.
          - For 2D cases, monai ``AnchorGenerator(sizes, aspect_ratios, indexing='xy')`` and
            ``torchvision.models.detection.anchor_utils.AnchorGenerator(sizes, aspect_ratios)`` are equivalent.
  
  
  Reference:.
      https://github.com/pytorch/vision/blob/release/0.12/torchvision/models/detection/anchor_utils.py
  
  Example:
      .. code-block:: python
  
          # 2D example inputs for a 2-level feature maps
          sizes = ((10,12,14,16), (20,24,28,32))
          base_aspect_ratios = (1., 0.5,  2.)
          aspect_ratios = (base_aspect_ratios, base_aspect_ratios)
          anchor_generator = AnchorGenerator(sizes, aspect_ratios)
  
          # 3D example inputs for a 2-level feature maps
          sizes = ((10,12,14,16), (20,24,28,32))
          base_aspect_ratios = ((1., 1.), (1., 0.5), (0.5, 1.), (2., 2.))
          aspect_ratios = (base_aspect_ratios, base_aspect_ratios)
          anchor_generator = AnchorGenerator(sizes, aspect_ratios)
class_docstr_tok: ["This","module","is","modified","from","torchvision","to","support","both","2D","and","3D","images",".","Module","that","generates","anchors","for","a","set","of","feature","maps","and","image","sizes",".","The","module","support","computing","anchors","at","multiple","sizes","and","aspect","ratios","per","feature","map",".","sizes","and","aspect_ratios","should","have","the","same","number","of","elements",",","and","it","should","correspond","to","the","number","of","feature","maps",".","sizes","[","i","]","and","aspect_ratios","[","i","]","can","have","an","arbitrary","number","of","elements",".","For","2D","images",",","anchor","width","and","height","w",":","h","=","1",":","aspect_ratios","[","i",",","j","]","For","3D","images",",","anchor","width",",","height",",","and","depth","w",":","h",":","d","=","1",":","aspect_ratios","[","i",",","j,0","]",":","aspect_ratios","[","i",",","j,1","]","AnchorGenerator","will","output","a","set","of","sizes","[","i","]","*","aspect_ratios","[","i","]","anchors","per","spatial","location","for","feature","map","i.","Args",":","sizes",":","base","size","of","each","anchor",".","len","(","sizes",")","is","the","number","of","feature","maps",",","i.e.",",","the","number","of","output","levels","for","the","feature","pyramid","network","(","FPN",")",".","Each","element","of","``","sizes","``","is","a","Sequence","which","represents","several","anchor","sizes","for","each","feature","map",".","aspect_ratios",":","the","aspect","ratios","of","anchors",".","``","len","(","aspect_ratios",")","=","len","(","sizes",")","``",".","For","2D","images",",","each","element","of","``","aspect_ratios","[","i","]","``","is","a","Sequence","of","float",".","For","3D","images",",","each","element","of","``","aspect_ratios","[","i","]","``","is","a","Sequence","of","2","value","Sequence",".","indexing",":","choose","from","{","``","'ij","'","``",",","``","'xy","'","``","}",",","optional",",","Matrix","(","``","'ij","'","``",",","default","and","recommended",")","or","Cartesian","(","``","'xy","'","``",")","indexing","of","output",".","-","Matrix","(","``","'ij","'","``",",","default","and","recommended",")","indexing","keeps","the","original","axis","not","changed",".","-","To","use","other","monai","detection","components",",","please","set","``","indexing","=","'ij","'","``",".","-","Cartesian","(","``","'xy","'","``",")","indexing","swaps","axis","0","and","1",".","-","For","2D","cases",",","monai","``","AnchorGenerator","(","sizes",",","aspect_ratios",",","indexing='xy","'",")","``","and","``","torchvision.models.detection.anchor_utils.AnchorGenerator","(","sizes",",","aspect_ratios",")","``","are","equivalent",".","Reference",":",".","https",":","\/\/github.com\/pytorch\/vision\/blob\/release\/0.12\/torchvision\/models\/detection\/anchor_utils.py","Example",":","..","code-block",":",":","python","#","2D","example","inputs","for","a","2-level","feature","maps","sizes","=","(","(","10,12,14,16",")",",","(","20,24,28,32",")",")","base_aspect_ratios","=","(","1.",",","0.5",",","2",".",")","aspect_ratios","=","(","base_aspect_ratios",",","base_aspect_ratios",")","anchor_generator","=","AnchorGenerator","(","sizes",",","aspect_ratios",")","#","3D","example","inputs","for","a","2-level","feature","maps","sizes","=","(","(","10,12,14,16",")",",","(","20,24,28,32",")",")","base_aspect_ratios","=","(","(","1.",",","1",".",")",",","(","1.",",","0.5",")",",","(","0.5",",","1",".",")",",","(","2.",",","2",".",")",")","aspect_ratios","=","(","base_aspect_ratios",",","base_aspect_ratios",")","anchor_generator","=","AnchorGenerator","(","sizes",",","aspect_ratios",")"]
docstr: Every combination of (a, (g, s), i) in (self.cell_anchors, zip(grid_sizes, strides), 0:spatial_dims)
  corresponds to a feature map.
  It outputs g[i] anchors that are s[i] distance apart in direction i, with the same dimensions as a.
  
  Args:
      grid_sizes: spatial size of the feature maps
      strides: strides of the feature maps regarding to the original image
  
  Example:
      .. code-block:: python
  
          grid_sizes = [[100,100],[50,50]]
          strides = [[torch.tensor(2),torch.tensor(2)], [torch.tensor(4),torch.tensor(4)]]
docstr_tok: ["Every","combination","of","(","a",",","(","g",",","s",")",",","i",")","in","(","self.cell_anchors",",","zip","(","grid_sizes",",","strides",")",",","0",":","spatial_dims",")","corresponds","to","a","feature","map",".","It","outputs","g","[","i","]","anchors","that","are","s","[","i","]","distance","apart","in","direction","i",",","with","the","same","dimensions","as","a.","Args",":","grid_sizes",":","spatial","size","of","the","feature","maps","strides",":","strides","of","the","feature","maps","regarding","to","the","original","image","Example",":","..","code-block",":",":","python","grid_sizes","=","[","[","100,100","]",",","[","50,50","]","]","strides","=","[","[","torch.tensor","(","2",")",",","torch.tensor","(","2",")","]",",","[","torch.tensor","(","4",")",",","torch.tensor","(","4",")","]","]"]
code: def grid_anchors(
      self, grid_sizes: list[list[int]], strides: list[list[Tensor]]
  ) -> list[Tensor]:
      """
      Every combination of (a, (g, s), i) in (self.cell_anchors, zip(grid_sizes, strides), 0:spatial_dims)
      corresponds to a feature map.
      It outputs g[i] anchors that are s[i] distance apart in direction i, with the same dimensions as a.
  
      Args:
          grid_sizes: spatial size of the feature maps
          strides: strides of the feature maps regarding to the original image
  
      Example:
          .. code-block:: python
  
              grid_sizes = [[100,100],[50,50]]
              strides = [[torch.tensor(2),torch.tensor(2)], [torch.tensor(4),torch.tensor(4)]]
      """
      anchors = []
      cell_anchors = self.cell_anchors
      if cell_anchors is None:
          raise AssertionError
  
      if not (len(grid_sizes) == len(strides) == len(cell_anchors)):
          raise ValueError(
              "Anchors should be Tuple[Tuple[int]] because each feature "
              "map could potentially have different sizes and aspect ratios. "
              "There needs to be a match between the number of "
              "feature maps passed and the number of sizes / aspect ratios specified."
          )
  
      for size, stride, base_anchors in zip(
          grid_sizes, strides, cell_anchors
      ):
          # for each feature map
          device = base_anchors.device
  
          # compute anchor centers regarding to the image.
          # shifts_centers is [x_center, y_center] or [x_center, y_center, z_center]
          shifts_centers = [
              torch.arange(
                  0, size[axis], dtype=torch.int32, device=device
              )
              * stride[axis]
              for axis in range(self.spatial_dims)
          ]
  
          # to support torchscript, cannot directly use torch.meshgrid(shifts_centers).
          shifts_centers = list(
              torch.meshgrid(
                  shifts_centers[: self.spatial_dims], indexing="ij"
              )
          )
  
          for axis in range(self.spatial_dims):
              # each element of shifts_centers is sized (HW,) or (HWD,)
              shifts_centers[axis] = shifts_centers[axis].reshape(-1)
  
          # Expand to [x_center, y_center, x_center, y_center],
          # or [x_center, y_center, z_center, x_center, y_center, z_center]
          if self.indexing == "xy":
              # Cartesian ('xy') indexing swaps axis 0 and 1.
              shifts_centers[1], shifts_centers[0] = (
                  shifts_centers[0],
                  shifts_centers[1],
              )
          shifts = torch.stack(
              shifts_centers * 2, dim=1
          )  # sized (HW,4) or (HWD,6)
  
          # For every (base anchor, output anchor) pair,
          # offset each zero-centered base anchor by the center of the output anchor.
          anchors.append(
              (
                  shifts.view(-1, 1, self.spatial_dims * 2)
                  + base_anchors.view(1, -1, self.spatial_dims * 2)
              ).reshape(
                  -1, self.spatial_dims * 2
              )  # each element sized (AHWD,4) or (AHWD,6)
          )
  
      return anchors
  
file_path: MONAI/monai/apps/detection/utils/anchor_utils.py
imports: from __future__ import annotations
  from typing import List, Sequence
  import torch
  from torch import Tensor, nn
  from monai.utils import ensure_tuple
  from monai.utils.misc import issequenceiterable
  from monai.utils.module import look_up_option
label_desc: Use image node_id 5 for calling the AnchorGenerator obj's underlying member method code with example usage: obj.grid_anchors(grid_sizes, strides) and returns: anchors