code: def prepare_cache_results(
      self,
      detection_results: List[DetectionPredTuple],
      image_ids,
      image_widths,
      image_heights,
  ) -> None:
      batch_results = {k: [] for k in self.coco_results.keys()}
      for detection_result, img_id, img_w, img_h in zip(
          detection_results, image_ids, image_widths, image_heights
      ):
          label = detection_result.labels
  
          if label.numel() == 0:
              # no detections
              continue
          box = detection_result.boxes
          score = detection_result.scores
  
          img_id, img_w, img_h = (
              img_id.item(),
              img_w.item(),
              img_h.item(),
          )
  
          box[..., 0::2] = torch.clip(
              box[..., 0::2] * img_w, min=0, max=img_w
          )
          box[..., 1::2] = torch.clip(
              box[..., 1::2] * img_h, min=0, max=img_h
          )
  
          # convert box from xyxy to xywh format
          box[..., 2] = box[..., 2] - box[..., 0]
          box[..., 3] = box[..., 3] - box[..., 1]
  
          box = box.cpu().numpy()
          label = label.cpu().numpy()
          score = score.cpu().numpy()
  
          if "bbox" in batch_results:
              batch_results["bbox"].extend(
                  [
                      {
                          "image_id": img_id,
                          "category_id": self.contiguous_id_to_coco_id[
                              label[bbox_id]
                          ],
                          "bbox": box[bbox_id].tolist(),
                          "score": score[bbox_id],
                      }
                      for bbox_id in range(box.shape[0])
                      if label[bbox_id] > 0
                  ]
              )
  
          masks = detection_result.masks
          if masks is not None and "segm" in batch_results:
              # masks are [N, H, W]. For interpolation, convert them to [1, N, H, W] and then back to [N, H, W]
              masks = F.interpolate(
                  masks.unsqueeze(0),
                  size=(img_h, img_w),
                  mode="bilinear",
                  align_corners=True,
              ).squeeze(0)
              masks = masks > 0.5
  
              masks = masks.cpu().numpy()
              # predicted masks are in [N, H, W] format
              rles = [
                  maskUtils.encode(
                      np.array(
                          mask[:, :, np.newaxis],
                          dtype=np.uint8,
                          order="F",
                      )
                  )[0]
                  for mask in masks
              ]
              for rle in rles:
                  rle["counts"] = rle["counts"].decode("utf-8")
  
              batch_results["segm"].extend(
                  [
                      {
                          "image_id": img_id,
                          "category_id": self.contiguous_id_to_coco_id[
                              label[seg_id]
                          ],
                          "segmentation": rle,
                          "score": score[seg_id],
                      }
                      for seg_id, rle in enumerate(rles)
                      if label[seg_id] > 0
                  ]
              )
  
      for k in batch_results.keys():
          new_results: List[Dict] = batch_results[k]
          if self.is_distributed:
              # Gather results from all processes
              gathered_results: List[List[Dict]] = all_gather_list(
                  new_results
              )
              # Flatten results as the output of all_gather will be a list of list here
              new_results = [
                  x for results in gathered_results for x in results
              ]
  
          self.coco_results[k].extend(new_results)
  
imports: import io
  import os
  from contextlib import redirect_stdout
  from typing import Any, Dict, List, Optional, Union
  import numpy
  import torch
  from pycocotools import mask
  from pycocotools.coco import COCO
  from pycocotools.cocoeval import COCOeval
  from torch import Tensor
  from torch.nn import functional
  from cvnets.models.detection import DetectionPredTuple
  from metrics import METRICS_REGISTRY
  from metrics.metric_base import BaseMetric
  from utils import logger
  from utils.ddp_utils import is_master
  from utils.tensor_utils import all_gather_list
label_desc: Use image node_id 4 for calling the COCOEvaluator obj's underlying member method code with example usage: obj.prepare_cache_results(detection_results, image_ids, image_widths, image_heights) without return types