class_docstr: DataCollector of Pipeline, collect results in every frames and assign it to each track ids.
  mainly used in mtmct.
  
  data struct:
  collector:
    - [id1]: (all results of N frames)
      - frames(list of int): Nx[int]
      - rects(list of rect): Nx[rect(conf, xmin, ymin, xmax, ymax)]
      - features(list of array(256,)): Nx[array(256,)]
      - qualities(list of float): Nx[float]
      - attrs(list of attr): refer to attrs for details
      - kpts(list of kpts): refer to kpts for details
      - skeleton_action(list of skeleton_action): refer to skeleton_action for details
    ...
    - [idN]
class_docstr_tok: ["DataCollector","of","Pipeline",",","collect","results","in","every","frames","and","assign","it","to","each","track","ids",".","mainly","used","in","mtmct",".","data","struct",":","collector",":","-","[","id1","]",":","(","all","results","of","N","frames",")","-","frames","(","list","of","int",")",":","Nx","[","int","]","-","rects","(","list","of","rect",")",":","Nx","[","rect","(","conf",",","xmin",",","ymin",",","xmax",",","ymax",")","]","-","features","(","list","of","array","(","256",",",")",")",":","Nx","[","array","(","256",",",")","]","-","qualities","(","list","of","float",")",":","Nx","[","float","]","-","attrs","(","list","of","attr",")",":","refer","to","attrs","for","details","-","kpts","(","list","of","kpts",")",":","refer","to","kpts","for","details","-","skeleton_action","(","list","of","skeleton_action",")",":","refer","to","skeleton_action","for","details","...","-","[","idN","]"]
code: def append(self, frameid, Result):
      mot_res = Result.get("mot")
      attr_res = Result.get("attr")
      kpt_res = Result.get("kpt")
      skeleton_action_res = Result.get("skeleton_action")
      reid_res = Result.get("reid")
      vehicleplate_res = Result.get("vehicleplate")
  
      rects = []
      if reid_res is not None:
          rects = reid_res["rects"]
      elif mot_res is not None:
          rects = mot_res["boxes"]
  
      for idx, mot_item in enumerate(rects):
          ids = int(mot_item[0])
          if ids not in self.collector:
              self.collector[ids] = copy.deepcopy(self.mots)
          self.collector[ids]["frames"].append(frameid)
          self.collector[ids]["rects"].append([mot_item[2:]])
          if attr_res:
              self.collector[ids]["attrs"].append(
                  attr_res["output"][idx]
              )
          if kpt_res:
              self.collector[ids]["kpts"].append(
                  [
                      kpt_res["keypoint"][0][idx],
                      kpt_res["keypoint"][1][idx],
                  ]
              )
          if skeleton_action_res and (idx + 1) in skeleton_action_res:
              self.collector[ids]["skeleton_action"].append(
                  skeleton_action_res[idx + 1]
              )
          else:
              # action model generate result per X frames, Not available every frames
              self.collector[ids]["skeleton_action"].append(None)
          if reid_res:
              self.collector[ids]["features"].append(
                  reid_res["features"][idx]
              )
              self.collector[ids]["qualities"].append(
                  reid_res["qualities"][idx]
              )
          if vehicleplate_res and vehicleplate_res["plate"][idx] != "":
              self.collector[ids]["vehicleplate"].append(
                  vehicleplate_res["plate"][idx]
              )
  
file_path: PaddleDetection/deploy/pipeline/datacollector.py
imports: import os
  import copy
  from collections import Counter
label_desc: Use image node_id 2 for calling the DataCollector obj's underlying member method code with example usage: obj.append(frameid, Result) without return types