code: def main(img_size=512, n=9, thr=0.25, gen=1000):
      # 从数据集中读取所有图片的wh以及对应bboxes的wh
      dataset = VOCDataSet(
          voc_root="/data", year="2012", txt_name="train.txt"
      )
      im_wh, boxes_wh = dataset.get_info()
  
      # 最大边缩放到img_size
      im_wh = np.array(im_wh, dtype=np.float32)
      shapes = img_size * im_wh / im_wh.max(1, keepdims=True)
      wh0 = np.concatenate(
          [l * s for s, l in zip(shapes, boxes_wh)]
      )  # wh
  
      # Filter 过滤掉小目标
      i = (wh0 < 3.0).any(1).sum()
      if i:
          print(
              f"WARNING: Extremely small objects found. {i} of {len(wh0)} labels are < 3 pixels in size."
          )
      wh = wh0[(wh0 >= 2.0).any(1)]  # 只保留wh都大于等于2个像素的box
  
      # Kmeans calculation
      # print(f'Running kmeans for {n} anchors on {len(wh)} points...')
      # s = wh.std(0)  # sigmas for whitening
      # k, dist = kmeans(wh / s, n, iter=30)  # points, mean distance
      # assert len(k) == n, print(f'ERROR: scipy.cluster.vq.kmeans requested {n} points but returned only {len(k)}')
      # k *= s
      k = k_means(wh, n)
  
      # 按面积排序
      k = k[np.argsort(k.prod(1))]  # sort small to large
      f, bpr = anchor_fitness(k, wh, thr)
      print(
          "kmeans: "
          + " ".join([f"[{int(i[0])}, {int(i[1])}]" for i in k])
      )
      print(f"fitness: {f:.5f}, best possible recall: {bpr:.5f}")
  
      # Evolve
      # 遗传算法(在kmeans的结果基础上变异mutation)
      npr = np.random
      f, sh, mp, s = (
          anchor_fitness(k, wh, thr)[0],
          k.shape,
          0.9,
          0.1,
      )  # fitness, generations, mutation prob, sigma
      pbar = tqdm(
          range(gen), desc=f"Evolving anchors with Genetic Algorithm:"
      )  # progress bar
      for _ in pbar:
          v = np.ones(sh)
          while (
              v == 1
          ).all():  # mutate until a change occurs (prevent duplicates)
              v = (
                  (npr.random(sh) < mp)
                  * random.random()
                  * npr.randn(*sh)
                  * s
                  + 1
              ).clip(0.3, 3.0)
          kg = (k.copy() * v).clip(min=2.0)
          fg, bpr = anchor_fitness(kg, wh, thr)
          if fg > f:
              f, k = fg, kg.copy()
              pbar.desc = f"Evolving anchors with Genetic Algorithm: fitness = {f:.4f}"
  
      # 按面积排序
      k = k[np.argsort(k.prod(1))]  # sort small to large
      print(
          "genetic: "
          + " ".join([f"[{int(i[0])}, {int(i[1])}]" for i in k])
      )
      print(f"fitness: {f:.5f}, best possible recall: {bpr:.5f}")
  
file_path: deep-learning-for-image-processing/others_project/kmeans_anchors/main.py
imports: import random
  import numpy
  from tqdm import tqdm
  from scipy.cluster.vq import kmeans
  from read_voc import VOCDataSet
  from yolo_kmeans import k_means, wh_iou
label_desc: Use image node_id 2 for calling a global function with example usage: main(img_size, n, thr, gen) without return types