class_docstr: Tracker for Quasi-Dense Tracking.
  
  Args:
      init_score_thr (float): The cls_score threshold to
          initialize a new tracklet. Defaults to 0.8.
      obj_score_thr (float): The cls_score threshold to
          update a tracked tracklet. Defaults to 0.5.
      match_score_thr (float): The match threshold. Defaults to 0.5.
      memo_tracklet_frames (int): The most frames in a tracklet memory.
          Defaults to 10.
      memo_backdrop_frames (int): The most frames in the backdrops.
          Defaults to 1.
      memo_momentum (float): The momentum value for embeds updating.
          Defaults to 0.8.
      nms_conf_thr (float): The nms threshold for confidence.
          Defaults to 0.5.
      nms_backdrop_iou_thr (float): The nms threshold for backdrop IoU.
          Defaults to 0.3.
      nms_class_iou_thr (float): The nms threshold for class IoU.
          Defaults to 0.7.
      with_cats (bool): Whether to track with the same category.
          Defaults to True.
      match_metric (str): The match metric. Defaults to 'bisoftmax'.
docstr: Tracking forward function.
  
  Args:
      model (nn.Module): MOT model.
      img (Tensor): of shape (T, C, H, W) encoding input image.
          Typically these should be mean centered and std scaled.
          The T denotes the number of key images and usually is 1 in
          QDTrack method.
      feats (list[Tensor]): Multi level feature maps of `img`.
      data_sample (:obj:`TrackDataSample`): The data sample.
          It includes information such as `pred_instances`.
      rescale (bool, optional): If True, the bounding boxes should be
          rescaled to fit the original scale of the image. Defaults to
          True.
  
  Returns:
      :obj:`InstanceData`: Tracking results of the input images.
      Each InstanceData usually contains ``bboxes``, ``labels``,
      ``scores`` and ``instances_id``.
docstr_tok: ["Tracking","forward","function",".","Args",":","model","(","nn.Module",")",":","MOT","model",".","img","(","Tensor",")",":","of","shape","(","T",",","C",",","H",",","W",")","encoding","input","image",".","Typically","these","should","be","mean","centered","and","std","scaled",".","The","T","denotes","the","number","of","key","images","and","usually","is","1","in","QDTrack","method",".","feats","(","list","[","Tensor","]",")",":","Multi","level","feature","maps","of","`","img","`",".","data_sample","(",":","obj",":","`","TrackDataSample","`",")",":","The","data","sample",".","It","includes","information","such","as","`","pred_instances","`",".","rescale","(","bool",",","optional",")",":","If","True",",","the","bounding","boxes","should","be","rescaled","to","fit","the","original","scale","of","the","image",".","Defaults","to","True",".","Returns",":",":","obj",":","`","InstanceData","`",":","Tracking","results","of","the","input","images",".","Each","InstanceData","usually","contains","``","bboxes","``",",","``","labels","``",",","``","scores","``","and","``","instances_id","``","."]
code: def track(
      self,
      model: torch.nn.Module,
      img: torch.Tensor,
      feats: List[torch.Tensor],
      data_sample: TrackDataSample,
      rescale=True,
      **kwargs,
  ) -> InstanceData:
      """Tracking forward function.
  
      Args:
          model (nn.Module): MOT model.
          img (Tensor): of shape (T, C, H, W) encoding input image.
              Typically these should be mean centered and std scaled.
              The T denotes the number of key images and usually is 1 in
              QDTrack method.
          feats (list[Tensor]): Multi level feature maps of `img`.
          data_sample (:obj:`TrackDataSample`): The data sample.
              It includes information such as `pred_instances`.
          rescale (bool, optional): If True, the bounding boxes should be
              rescaled to fit the original scale of the image. Defaults to
              True.
  
      Returns:
          :obj:`InstanceData`: Tracking results of the input images.
          Each InstanceData usually contains ``bboxes``, ``labels``,
          ``scores`` and ``instances_id``.
      """
      metainfo = data_sample.metainfo
      bboxes = data_sample.pred_instances.bboxes
      labels = data_sample.pred_instances.labels
      scores = data_sample.pred_instances.scores
  
      frame_id = metainfo.get("frame_id", -1)
      # create pred_track_instances
      pred_track_instances = InstanceData()
  
      # return zero bboxes if there is no track targets
      if bboxes.shape[0] == 0:
          ids = torch.zeros_like(labels)
          pred_track_instances = data_sample.pred_instances.clone()
          pred_track_instances.instances_id = ids
          return pred_track_instances
  
      # get track feats
      rescaled_bboxes = bboxes.clone()
      if rescale:
          scale_factor = rescaled_bboxes.new_tensor(
              metainfo["scale_factor"]
          ).repeat((1, 2))
          rescaled_bboxes = rescaled_bboxes * scale_factor
      track_feats = model.track_head.predict(feats, [rescaled_bboxes])
      # sort according to the object_score
      _, inds = scores.sort(descending=True)
      bboxes = bboxes[inds]
      scores = scores[inds]
      labels = labels[inds]
      embeds = track_feats[inds, :]
  
      # duplicate removal for potential backdrops and cross classes
      valids = bboxes.new_ones((bboxes.size(0)))
      ious = bbox_overlaps(bboxes, bboxes)
      for i in range(1, bboxes.size(0)):
          thr = (
              self.nms_backdrop_iou_thr
              if scores[i] < self.obj_score_thr
              else self.nms_class_iou_thr
          )
          if (ious[i, :i] > thr).any():
              valids[i] = 0
      valids = valids == 1
      bboxes = bboxes[valids]
      scores = scores[valids]
      labels = labels[valids]
      embeds = embeds[valids, :]
  
      # init ids container
      ids = torch.full((bboxes.size(0),), -1, dtype=torch.long)
  
      # match if buffer is not empty
      if bboxes.size(0) > 0 and not self.empty:
          (
              memo_bboxes,
              memo_labels,
              memo_embeds,
              memo_ids,
              memo_vs,
          ) = self.memo
  
          if self.match_metric == "bisoftmax":
              feats = torch.mm(embeds, memo_embeds.t())
              d2t_scores = feats.softmax(dim=1)
              t2d_scores = feats.softmax(dim=0)
              match_scores = (d2t_scores + t2d_scores) / 2
          elif self.match_metric == "softmax":
              feats = torch.mm(embeds, memo_embeds.t())
              match_scores = feats.softmax(dim=1)
          elif self.match_metric == "cosine":
              match_scores = torch.mm(
                  F.normalize(embeds, p=2, dim=1),
                  F.normalize(memo_embeds, p=2, dim=1).t(),
              )
          else:
              raise NotImplementedError
          # track with the same category
          if self.with_cats:
              cat_same = labels.view(-1, 1) == memo_labels.view(1, -1)
              match_scores *= cat_same.float().to(match_scores.device)
          # track according to match_scores
          for i in range(bboxes.size(0)):
              conf, memo_ind = torch.max(match_scores[i, :], dim=0)
              id = memo_ids[memo_ind]
              if conf > self.match_score_thr:
                  if id > -1:
                      # keep bboxes with high object score
                      # and remove background bboxes
                      if scores[i] > self.obj_score_thr:
                          ids[i] = id
                          match_scores[:i, memo_ind] = 0
                          match_scores[i + 1 :, memo_ind] = 0
                      else:
                          if conf > self.nms_conf_thr:
                              ids[i] = -2
      # initialize new tracks
      new_inds = (ids == -1) & (scores > self.init_score_thr).cpu()
      num_news = new_inds.sum()
      ids[new_inds] = torch.arange(
          self.num_tracks, self.num_tracks + num_news, dtype=torch.long
      )
      self.num_tracks += num_news
  
      self.update(ids, bboxes, embeds, labels, scores, frame_id)
      tracklet_inds = ids > -1
      # update pred_track_instances
      pred_track_instances.bboxes = bboxes[tracklet_inds]
      pred_track_instances.labels = labels[tracklet_inds]
      pred_track_instances.scores = scores[tracklet_inds]
      pred_track_instances.instances_id = ids[tracklet_inds]
  
      return pred_track_instances
  
file_path: mmdetection/mmdet/models/trackers/quasi_dense_tracker.py
imports: from typing import List, Tuple
  import torch
  import torch.nn.functional
  from mmengine.structures import InstanceData
  from torch import Tensor
  from mmdet.registry import MODELS
  from mmdet.structures import TrackDataSample
  from mmdet.structures.bbox import bbox_overlaps
  from .base_tracker import BaseTracker
label_desc: Use image node_id 5 for calling the QuasiDenseTracker obj's underlying member method code with example usage: obj.track(model, img, feats, data_sample, rescale) and returns: pred_track_instances, pred_track_instances