code: def cvt_annotations(devkit_path, years, split, out_file):
      if not isinstance(years, list):
          years = [years]
      annotations = []
      for year in years:
          filelist = osp.join(
              devkit_path, f"VOC{year}/ImageSets/Main/{split}.txt"
          )
          if not osp.isfile(filelist):
              print(
                  f"filelist does not exist: {filelist}, "
                  f"skip voc{year} {split}"
              )
              return
          img_names = list_from_file(filelist)
          xml_paths = [
              osp.join(
                  devkit_path, f"VOC{year}/Annotations/{img_name}.xml"
              )
              for img_name in img_names
          ]
          img_paths = [
              f"VOC{year}/JPEGImages/{img_name}.jpg"
              for img_name in img_names
          ]
          part_annotations = track_progress(
              parse_xml, list(zip(xml_paths, img_paths))
          )
          annotations.extend(part_annotations)
      if out_file.endswith("json"):
          annotations = cvt_to_coco_json(annotations)
      dump(annotations, out_file)
      return annotations
  
file_path: mmdetection/tools/dataset_converters/pascal_voc.py
imports: import argparse
  import os.path
  import xml.etree.ElementTree
  import numpy
  from mmengine.fileio import dump, list_from_file
  from mmengine.utils import mkdir_or_exist, track_progress
  from mmdet.evaluation import voc_classes
label_desc: Use image node_id 2 for calling a global function with example usage: cvt_annotations(devkit_path, years, split, out_file) and returns: annotations