code: def run_kmeans(ann_dims, anchor_num):
      ann_num = ann_dims.shape[0]
      iterations = 0
      prev_assignments = np.ones(ann_num) * (-1)
      iteration = 0
      old_distances = np.zeros((ann_num, anchor_num))
  
      indices = [
          random.randrange(ann_dims.shape[0]) for i in range(anchor_num)
      ]
      centroids = ann_dims[indices]
      anchor_dim = ann_dims.shape[1]
  
      while True:
          distances = []
          iteration += 1
          for i in range(ann_num):
              d = 1 - IOU(ann_dims[i], centroids)
              distances.append(d)
          distances = np.array(
              distances
          )  # distances.shape = (ann_num, anchor_num)
  
          # assign samples to centroids
          assignments = np.argmin(distances, axis=1)
  
          if (assignments == prev_assignments).all():
              return centroids
  
          # calculate new centroids
          centroid_sums = np.zeros((anchor_num, anchor_dim), np.float)
          for i in range(ann_num):
              centroid_sums[assignments[i]] += ann_dims[i]
          for j in range(anchor_num):
              centroids[j] = centroid_sums[j] / (
                  np.sum(assignments == j) + 1e-6
              )
  
          prev_assignments = assignments.copy()
          old_distances = distances.copy()
  
imports: import random
  import numpy
  from imageai.Detection.Custom.voc import parse_voc_annotation
label_desc: Use image node_id 3 for calling a global function with example usage: run_kmeans(ann_dims, anchor_num) and returns: centroids