text: #!/usr/bin/env python3
  # -*- coding: utf-8 -*-
  # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
  
  import copy
  import json
  import numpy as np
  import os
  import sys
  import pycocotools.mask as mask_utils
  
  from detectron2.utils.env import seed_all_rng
  from detectron2.utils.file_io import PathManager
  
  
  def get_point_annotations(input_filename, output_filename, num_points_per_instance):
      with PathManager.open(input_filename, "r") as f:
          coco_json = json.load(f)
  
      coco_annos = coco_json.pop("annotations")
      coco_points_json = copy.deepcopy(coco_json)
  
      imgs = {}
      for img in coco_json["images"]:
          imgs[img["id"]] = img
  
      new_annos = []
      for ann in coco_annos:
          # convert mask
          t = imgs[ann["image_id"]]
          h, w = t["height"], t["width"]
          segm = ann.pop("segmentation")
          if type(segm) == list:
              # polygon -- a single object might consist of multiple parts
              # we merge all parts into one mask rle code
              rles = mask_utils.frPyObjects(segm, h, w)
              rle = mask_utils.merge(rles)
          elif type(segm["counts"]) == list:
              # uncompressed RLE
              rle = mask_utils.frPyObjects(segm, h, w)
          else:
              # rle
              rle = segm
          mask = mask_utils.decode(rle)
          new_ann = copy.deepcopy(ann)
          # sample points in image coordinates
          box = ann["bbox"]
          point_coords_wrt_image = np.random.rand(num_points_per_instance, 2)
          point_coords_wrt_image[:, 0] = point_coords_wrt_image[:, 0] * box[2]
          point_coords_wrt_image[:, 1] = point_coords_wrt_image[:, 1] * box[3]
          point_coords_wrt_image[:, 0] += box[0]
          point_coords_wrt_image[:, 1] += box[1]
          # round to integer coordinates
          point_coords_wrt_image = np.floor(point_coords_wrt_image).astype(int)
          # get ori_annotation_file_list
          assert (point_coords_wrt_image >= 0).all(), (point_coords_wrt_image, mask.shape)
          assert (point_coords_wrt_image[:, 0] < w).all(), (point_coords_wrt_image, mask.shape)
          assert (point_coords_wrt_image[:, 1] < h).all(), (point_coords_wrt_image, mask.shape)
          point_labels = mask[point_coords_wrt_image[:, 1], point_coords_wrt_image[:, 0]]
          # store new annotations
          new_ann["point_coords"] = point_coords_wrt_image.tolist()
          new_ann["point_labels"] = point_labels.tolist()
          new_annos.append(new_ann)
      coco_points_json["annotations"] = new_annos
  
      with PathManager.open(output_filename, "w") as f:
          json.dump(coco_points_json, f)
  
      print("{} is modified and stored in {}.".format(input_filename, output_filename))
  
  
  if __name__ == "__main__":
      """
      Generate point-based supervision for COCO dataset.
  
      Usage:
          python tools/prepare_coco_point_annotations_without_masks.py \
              NUM_POINTS_PER_INSTANCE NUM_VERSIONS_WITH_DIFFERENT_SEED
  
      Example to generate point-based COCO dataset with 10 points per instance:
          python tools/prepare_coco_point_annotations_without_masks.py 10
      """
  
      # Fix random seed
      seed_all_rng(12345)
  
      assert len(sys.argv) >= 2, "Please provide number of points to sample per instance"
      dataset_dir = os.path.join(os.getenv("DETECTRON2_DATASETS", "datasets"), "coco/annotations")
      num_points_per_instance = int(sys.argv[1])
      if len(sys.argv) == 3:
          repeat = int(sys.argv[2])
      else:
          repeat = 1
      s = "instances_train2017"
      for version in range(repeat):
          print(
              "Start sampling {} points per instance for annotations {}.".format(
                  num_points_per_instance, s
              )
          )
          get_point_annotations(
              os.path.join(dataset_dir, "{}.json".format(s)),
              os.path.join(
                  dataset_dir,
                  "{}_n{}_v{}_without_masks.json".format(s, num_points_per_instance, version + 1),
              ),
              num_points_per_instance,
          )
  