def METHOD_NAME(self, idx):
    """
    load per image annotation
    :param idx: index in dataloader
    :return: annotation dict
    """
    img_id = self.img_ids[idx]
    ann_ids = self.coco_api.getAnnIds([img_id])
    anns = self.coco_api.loadAnns(ann_ids)
    gt_bboxes = []
    gt_labels = []
    gt_bboxes_ignore = []
    if self.use_instance_mask:
        gt_masks = []
    if self.use_keypoint:
        gt_keypoints = []
    for ann in anns:
        if ann.get("ignore", False):
            continue
        x1, y1, w, h = ann["bbox"]
        if ann["area"] <= 0 or w < 1 or h < 1:
            continue
        if ann["category_id"] not in self.cat_ids:
            continue
        bbox = [x1, y1, x1 + w, y1 + h]
        if ann.get("iscrowd", False):
            gt_bboxes_ignore.append(bbox)
        else:
            gt_bboxes.append(bbox)
            gt_labels.append(self.cat2label[ann["category_id"]])
            if self.use_instance_mask:
                gt_masks.append(self.coco_api.annToMask(ann))
            if self.use_keypoint:
                gt_keypoints.append(ann["keypoints"])
    if gt_bboxes:
        gt_bboxes = np.array(gt_bboxes, dtype=np.float32)
        gt_labels = np.array(gt_labels, dtype=np.int64)
    else:
        gt_bboxes = np.zeros((0, 4), dtype=np.float32)
        gt_labels = np.array([], dtype=np.int64)
    if gt_bboxes_ignore:
        gt_bboxes_ignore = np.array(gt_bboxes_ignore, dtype=np.float32)
    else:
        gt_bboxes_ignore = np.zeros((0, 4), dtype=np.float32)
    annotation = dict(
        bboxes=gt_bboxes, labels=gt_labels, bboxes_ignore=gt_bboxes_ignore
    )
    if self.use_instance_mask:
        annotation["masks"] = gt_masks
    if self.use_keypoint:
        if gt_keypoints:
            annotation["keypoints"] = np.array(gt_keypoints, dtype=np.float32)
        else:
            annotation["keypoints"] = np.zeros((0, 51), dtype=np.float32)
    return annotation