title: How to give a unique Id to each bounding box of each object detected
body: <p>I am using a Tensorflow object detection API on my Windows system for which I've built a custom object detection classifier. It detects the object very well with the webcam feed but I am trying to figure out on how I can detect objects from the webcam with a unique object ID for every detected object.</p>
  
  <p>Say, for example, if the webcam detects two similar objects (say 2 similar chairs) then it draws a bounding box on each chair. I want to track both the chairs with a unique ID and, when I subsequently extract a video frame, get the centroid of both the chairs.</p>
  
  <p>Currently I am using this code:</p>
  
  <pre><code># Import packages
  import requests
  import os
  
  os.chdir('C:\\tensorflow1\\models\\research\\object_detection')
  
  from firebase import firebase
  import cv2
  import numpy as np
  import tensorflow as tf
  import sys
  
  # This is needed since the notebook is stored in the object_detection folder.
  sys.path.append("..")
  
  # Import utilites
  from object_detection.utils import label_map_util
  from object_detection.utils import visualization_utils as vis_util
  
  # Name of the directory containing the object detection module we're using
  MODEL_NAME = 'inference_graph'
  
  # Grab path to current working directory
  CWD_PATH = os.getcwd()
  
  # Path to frozen detection graph .pb file, which contains the model that is used
  # for object detection.
  PATH_TO_CKPT = os.path.join(CWD_PATH, MODEL_NAME, 'frozen_inference_graph.pb')
  
  # Path to label map file
  PATH_TO_LABELS = os.path.join(CWD_PATH, 'training', 'labelmap.pbtxt')
  
  # Number of classes the object detector can identify
  NUM_CLASSES = 1
  
  # Load the label map.
  # Label maps map indices to category names, so that when our convolution
  # network predicts `5`, we know that this corresponds to `king`.
  # Here we use internal utility functions, but anything that returns a
  # dictionary mapping integers to appropriate string labels would be fine
  label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
  categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES,
                                                              use_display_name=True)
  category_index = label_map_util.create_category_index(categories)
  
  # Load the Tensorflow model into memory.
  detection_graph = tf.Graph()
  with detection_graph.as_default():
      od_graph_def = tf.GraphDef()
      with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
          serialized_graph = fid.read()
          od_graph_def.ParseFromString(serialized_graph)
          tf.import_graph_def(od_graph_def, name='')
  
      sess = tf.Session(graph=detection_graph)
  
  # Define input and output tensors (i.e. data) for the object detection classifier
  
  # Input tensor is the image
  image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
  
  # Output tensors are the detection boxes, scores, and classes
  # Each box represents a part of the image where a particular object was detected
  detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
  
  # Each score represents level of confidence for each of the objects.
  # The score is shown on the result image, together with the class label.
  detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
  detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')
  
  # Number of objects detected
  num_detections = detection_graph.get_tensor_by_name('num_detections:0')
  
  # Initialize webcam feed
  video = cv2.VideoCapture(1)
  img_counter = 0
  
  while True:
  
      # Acquire frame and expand frame dimensions to have shape: [1, None, None, 3]
      # i.e. a single-column array, where each item in the column has the pixel RGB value
      ret, frame = video.read()
      frame_expanded = np.expand_dims(frame, axis=0)
  
      # Perform the actual detection by running the model with the image as input
      (boxes, scores, classes, num) = sess.run(
          [detection_boxes, detection_scores, detection_classes, num_detections],
          feed_dict={image_tensor: frame_expanded})
  
      # Draw the results of the detection (aka 'visulaize the results')
      vis_util.visualize_boxes_and_labels_on_image_array(
          frame,
          np.squeeze(boxes),
          np.squeeze(classes).astype(np.int32),
          np.squeeze(scores),
          np.squeeze(num),
          category_index,
          max_boxes_to_draw=3,
          use_normalized_coordinates=True,
          line_thickness=8,
          min_score_thresh=0.90)
  
  
      # All the results have been drawn on the frame, so it's time to display it.
      frame = cv2.circle(frame, (350, 350), 1, (0, 0, 255), 5)
      #frame = cv2.circle(frame, (337, 139), 1, (0, 0, 255), 5)
      cv2.imshow('Object detector', frame)
  
  
      if not ret:
          break
      k = cv2.waitKey(1)
  
      if k % 256 == 27:
          # ESC pressed
          print("Escape hit, closing...")
          break
      elif k % 256 == ord('s'):
          # SPACE pressed
          img_name = "opencv_frame_{}.jpg".format(img_counter)
  
          print("{} written!".format(img_name))
          img_counter += 1
  
          # Code to find the centroid of the bounding box on the object detected
          height = frame.shape[0]
          width = frame.shape[1]
          print(height)
          print(width)
  
          min_score_thresh = 0.90
          true_boxes = boxes[0][scores[0] &gt; min_score_thresh]
          for i in range(true_boxes.shape[0]):
              ymin = int(true_boxes[i][0] * height)
              xmin = int(true_boxes[i][1] * width)
              ymax = int(true_boxes[i][2] * height)
              xmax = int(true_boxes[i][3] * width)
  
          #print(ymin,xmin,ymax,xmax)
          y = int((ymin + ymax) / 2)
          x = int((xmin + xmax) / 2)
  
          print(x, y)
  
          frame = cv2.circle(frame, (xmin, ymin), 1, (0, 0, 255), 3)
          frame = cv2.circle(frame, (xmax, ymin), 1, (0, 0, 255), 3)
          frame = cv2.circle(frame, (xmin, ymax), 1, (0, 0, 255), 3)
          frame = cv2.circle(frame, (xmax, ymax), 1, (0, 0, 255), 3)
          frame = cv2.circle(frame, (x, y), 1, (0, 255, 255), 5)
          cv2.imshow(img_name, frame)
  
  
  # Clean up
  video.release()
  cv2.destroyAllWindows()
  </code></pre>
  
  <p>But this only gives me the centroid of the chair with highest confidence score instead of all the chairs which are detected.</p>
  
  <p>How can I modify my code to keep a track of each object with a unique ID and then, when the frames are extracted, get the centroid of each chair? Ideally the answer should be scaleable, so that 3 objects detected gives 3 unique IDs and 3 centroids.</p>
  
  <p>Finally: does the track_ids parameter in visualize_boxes_and_labels_on_image_array function help to keep a track on the object and its bounding box? If so, how should it be used?</p>