当前位置: 首页 > article >正文

域迁移相关数据集生成脚本

数据转化

# ----------------------------------------------
# Created by Wei-Jie Huang
# A collection of annotation conversion scripts
# We provide this for reference only
# ----------------------------------------------


import json
from pathlib import Path
from tqdm import tqdm


r"""
coco_anno_dict is like {
    "images": list of image_info's
    "annotations": list of annotation_info's
    "categories": list of categorie_info's
}
where img_info is like: {
    "id": ...,                      # 0-indexed
    "width": ...,
    "height": ...,
    "file_name": ...,
}, annotation_info is like: {
    "id": ...,                      # 0-indexed
    "image_id": ...,
    "category_id": ...,
    "segmentation": ...,
    "iscrowd": ...,
    "area": ...,
    "bbox": ...,                    # (x, y, w, h)
}, and category_info is like: {
    "id": ...,                      # 1-indexed
    "name": ...,
}
"""


def sim10k_to_coco(
    src_path: str = "VOC2012/Annotations",
    des_path: str = "annotations/sim10k_caronly.json",
    categories: tuple = ("car",)
    ) -> None:

    r""" Convert Sim10k (in VOC format) into COCO format.
    Args:
        src_path: path of the directory containing VOC-format annotations
        des_path: destination of the converted COCO-fomat annotation
        categories: only category ``car`` is considered by default
    """

    from xml.etree import ElementTree

    src_path = Path(src_path)
    des_path = Path(des_path)
    assert src_path.exists(), "Annotation directory does not exist"
    if des_path.exists():
        print(f"{des_path} exists. Override? (y/n)", end=" ")
        if input() != "y":
            print("Abort")
            return
    else:
        des_path.parent.mkdir(parents=True, exist_ok=True)

    # Initialization
    coco_anno_dict = {
        "images": [],
        "categories": [],
        "annotations": [],
    }
    num_images = 0
    num_categories = 0
    num_annotations = 0

    # Categories
    category_to_id = {}
    for category in categories:
        coco_anno_dict["categories"].append({
            "id": num_categories + 1,
            "name": category
        })
        category_to_id[category] = num_categories + 1
        num_categories += 1

    # Start Conversion
    for anno_file in tqdm(list(src_path.glob("*.xml"))):
        et_root = ElementTree.parse(anno_file).getroot()

        ##### Images #####
        img_info = {
            "id": num_images,
            "file_name": anno_file.stem + ".jpg",
        }
        num_images += 1

        # Image Size
        size = et_root.find("size")
        img_info["width"] = int(size.find("width").text)
        img_info["height"] = int(size.find("height").text)

        coco_anno_dict["images"].append(img_info)

        ##### Annotations #####
        for anno_object in et_root.findall("object"):
            category = anno_object.find("name").text
            if category not in categories:
                continue
            anno_info = {
                "id": num_annotations,
                "image_id": img_info["id"],
                "category_id": category_to_id[category],
                "segmentation": [],
                "iscrowd": 0
            }
            num_annotations += 1

            # Bounding box
            bndbox = anno_object.find("bndbox")
            xmin = float(bndbox.find("xmin").text)
            ymin = float(bndbox.find("ymin").text)
            xmax = float(bndbox.find("xmax").text)
            ymax = float(bndbox.find("ymax").text)
            # COCO format expects (x, y, w, h)
            anno_info["bbox"] = [xmin, ymin, round(xmax - xmin, 2), round(ymax - ymin, 2)]
            anno_info["area"] = round(anno_info["bbox"][2] * anno_info["bbox"][3], 2)

            coco_anno_dict["annotations"].append(anno_info)

    print("# of images:", num_images)
    print("# of categories:", num_categories)
    print("# of annotations:", num_annotations)

    with open(des_path, 'w') as f:
        f.write(json.dumps(coco_anno_dict, indent=4))
    print(f"Convert successfully to {des_path}")


def bdd100k_daytime_to_coco(
    src_path: str = "labels/bdd100k_labels_images_train.json",
    des_path: str = "annotations/bdd_daytime_train.json",
    # categories: tuple = (
    #     "person", "rider", "car", "truck", "bus", "train", "motor", "bike")
    # ) -> None:
    categories: tuple = (
        "pedestrian", "car", "bicycle", "rider", "truck", "bus", "motorcycle", "train")
    ) -> None:
    r""" Extract ``daytime`` subset from BDD100k dataset and convert into COCO format.
    Args:
        src_path: source of the annotation json file
        des_path: destination of the converted COCO-fomat annotation
        categories: categories used
    """

    src_path = Path(src_path)
    des_path = Path(des_path)
    assert src_path.exists(), "Source annotation file does not exist"
    if des_path.exists():
        print(f"{des_path} exists. Override? (y/n)", end=" ")
        if input() != "y":
            print("Abort")
            return
    else:
        des_path.parent.mkdir(parents=True, exist_ok=True)

    # Initialization
    coco_anno_dict = {
        "images": [],
        "categories": [],
        "annotations": [],
    }
    num_images = 0
    num_categories = 0
    num_annotations = 0

    # Categories
    category_to_id = {}
    for category in categories:
        coco_anno_dict["categories"].append({
            "id": num_categories + 1,
            "name": category
        })
        category_to_id[category] = num_categories + 1
        num_categories += 1

    with open(src_path, 'r') as f:
        raw_img_annos = json.load(f)
    # Start Conversion
    for raw_img_anno in tqdm(raw_img_annos):
        if raw_img_anno["attributes"]["timeofday"] != "daytime":
            continue

        ##### Images #####
        img_info = {
            "id": num_images,
            "file_name": raw_img_anno["name"],
            "height": 720,
            "width": 1280
        }
        coco_anno_dict["images"].append(img_info)
        num_images += 1

        ##### Annotations #####
        for label in raw_img_anno["labels"]:
            if label["category"] not in category_to_id or "box2d" not in label:
                continue
            anno_info = {
                "id": num_annotations,
                "image_id": img_info["id"],
                "category_id": category_to_id[label["category"]],
                "segmentation": [],
                "iscrowd": 0,
            }
            num_annotations += 1

            # Bbox
            x1 = label["box2d"]["x1"]
            y1 = label["box2d"]["y1"]
            x2 = label["box2d"]["x2"]
            y2 = label["box2d"]["y2"]
            anno_info["bbox"] = [x1, y1, x2 - x1, y2 - y1]
            anno_info["area"] = float((x2 - x1) * (y2 - y1))
            coco_anno_dict["annotations"].append(anno_info)

    print("# of images:", num_images)
    print("# of categories:", num_categories)
    print("# of annotations:", num_annotations)

    with open(des_path, 'w') as f:
        f.write(json.dumps(coco_anno_dict, indent=2))
    print(f"Convert successfully to {des_path}")


def cityscapes_to_coco(
    src_path: str = "gtFine/train",
    des_path: str = "annotations/cityscapes_train.json",
    car_only: bool = False,
    foggy: bool = False,
    categories: tuple = (
        "person",  "car", "bicycle", "rider", "truck", "bus", "motorcycle", "train")
    ) -> None:
    # categories: tuple = (
    #     "person",  "car", "bike", "rider", "truck", "bus", "motor", "train")
    # ) -> None:

    r"""Convert Cityscapes into COCO format.
        Ref: https://github.com/facebookresearch/Detectron/blob/7aa91aa/tools/convert_cityscapes_to_coco.py
    Args:
        src_path: path of the directory containing Cityscapes annotations
        des_path: destination of the converted COCO-fomat annotation
        car_only: whether extract category ``car`` only. used in Syn-to-real adaptation
        foggy: whether extract from foggy cityscapes. used in weather adaptation
        categories: categories used
    """

    def get_instances_with_polygons(imageFileName):
        r""" Ref: https://github.com/facebookresearch/Detectron/issues/111#issuecomment-363425465"""
        import os
        import sys
        import cv2
        import numpy as np
        from PIL import Image
        from cityscapesscripts.evaluation.instance import Instance
        from cityscapesscripts.helpers.csHelpers import labels, id2label

        # Load image
        img = Image.open(imageFileName)

        # Image as numpy array
        imgNp = np.array(img)

        # Initialize label categories
        instances = {}
        for label in labels:
            instances[label.name] = []

        # Loop through all instance ids in instance image
        for instanceId in np.unique(imgNp):
            if instanceId < 1000:
                continue

            instanceObj = Instance(imgNp, instanceId)
            instanceObj_dict = instanceObj.toDict()

            if id2label[instanceObj.labelID].hasInstances:
                mask = (imgNp == instanceId).astype(np.uint8)
                contour, hier = cv2.findContours(
                    mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

                polygons = [c.reshape(-1).tolist() for c in contour]
                instanceObj_dict["contours"] = polygons

            instances[id2label[instanceObj.labelID].name].append(
                instanceObj_dict)
        return instances

    def polygon_to_bbox(polygon: list) -> list:
        """Convert polygon into COCO-format bounding box."""

        # https://github.com/facebookresearch/maskrcnn-benchmark/issues/288#issuecomment-449098063
        TO_REMOVE = 1

        x0 = min(min(p[::2]) for p in polygon)
        x1 = max(max(p[::2]) for p in polygon)
        y0 = min(min(p[1::2]) for p in polygon)
        y1 = max(max(p[1::2]) for p in polygon)

        bbox = [x0, y0, x1 -x0 + TO_REMOVE, y1 - y0 + TO_REMOVE]
        return bbox

    src_path = Path(src_path)
    des_path = Path(des_path)
    assert src_path.exists(), "Source annotation file does not exist"
    if des_path.exists():
        print(f"{des_path} exists. Override? (y/n)", end=" ")
        if input() != "y":
            print("Abort")
            return
    else:
        des_path.parent.mkdir(parents=True, exist_ok=True)

    # Initialization
    coco_anno_dict = {
        "images": [],
        "categories": [],
        "annotations": [],
    }
    num_images = 0
    num_categories = 0
    num_annotations = 0

    # Categories
    if car_only:
        categories = ("car",)
    category_to_id = {}
    for category in categories:
        coco_anno_dict["categories"].append({
            "id": num_categories + 1,
            "name": category
        })
        category_to_id[category] = num_categories + 1
        num_categories += 1

    # Start Conversion
    for file in tqdm(list(src_path.rglob("*instanceIds.png"))):
        ##### Images #####
        img_info = {"id": num_images}
        num_images += 1
        img_info["file_name"] = \
            str(file.name).split("_", maxsplit=1)[0] + "/" + \
            str(file.name).replace("gtFine", "leftImg8bit").replace("_instanceIds", "")
        if foggy:
            img_info["file_name"] = \
                img_info["file_name"].replace("leftImg8bit", "leftImg8bit_foggy_beta_0.02")
        with open(str(file).replace("instanceIds.png", "polygons.json"), "r") as f:
            polygon_info = json.load(f)
            img_info["width"] = polygon_info["imgWidth"]
            img_info["height"] = polygon_info["imgHeight"]
        coco_anno_dict["images"].append(img_info)

        ##### Annotations #####
        instances = get_instances_with_polygons(str(file.absolute()))
        for category in instances.keys():
            if category not in categories:
                continue
            for instance in instances[category]:
                anno_info = {
                    "id": num_annotations,
                    "image_id": img_info["id"],
                    "category_id": category_to_id[category],
                    "segmentation": [],
                    "iscrowd": 0,
                    "area": instance["pixelCount"],
                    "bbox": polygon_to_bbox(instance["contours"]),
                }
                num_annotations += 1
                coco_anno_dict["annotations"].append(anno_info)

    print("# of images:", num_images)
    print("# of categories:", num_categories)
    print("# of annotations:", num_annotations)

    with open(des_path, 'w') as f:
        f.write(json.dumps(coco_anno_dict, indent=4))
    print(f"Convert successfully to {des_path}")


if __name__ == "__main__":
    # sim10k_to_coco(
    #     src_path="VOC2012/Annotations",
    #     des_path="annotations/sim10k_caronly.json"
    # )
    # bdd100k_daytime_to_coco(
    #     src_path="bdd100k/labels/det_20/det_train.json",
    #     des_path="bdd100k/annotations/bdd_daytime_train.json"
    # )
    # bdd100k_daytime_to_coco(
    #     src_path="bdd100k/labels/det_20/det_val.json",
    #     des_path="bdd100k/annotations/bdd_daytime_val.json"
    # )

    # cityscapes_to_coco(
    #     src_path="cityscapes/gtFine/train",
    #     des_path="cityscapes/label/cityscapes_train.json",
    # )
    # cityscapes_to_coco(
    #     src_path="cityscapes/gtFine/val",
    #     des_path="cityscapes/label/cityscapes_val.json",
    # )

    cityscapes_to_coco(
        src_path="cityscapes/gtFine/train",
        des_path="cityscapes/label/cityscapes_caronly_train.json",
        car_only=True,
    )
    cityscapes_to_coco(
        src_path="cityscapes/gtFine/val",
        des_path="cityscapes/label/cityscapes_caronly_val.json",
        car_only=True,
    )
    # cityscapes_to_coco(
    #     src_path="cityscapes/gtFine/train",
    #     des_path="cityscapes/label/foggy_cityscapes_train.json",
    #     foggy=True,
    # )
    # cityscapes_to_coco(
    #     src_path="cityscapes/gtFine/val",
    #     des_path="cityscapes/label/foggy_cityscapes_val.json",
    #     foggy=True,
    # )

可视化

import os
import cv2  
import json  
import matplotlib.pyplot as plt  
from pycocotools.coco import COCO  
from pycocotools.cocoeval import COCOeval 

def coco_show(anno_path, image_dir):
    coco = COCO(anno_path)
    img_ids = coco.getImgIds()
    img_ids.sort()
    cat_ids = coco.getCatIds()

    cname2cid = dict({clsid : coco.loadCats(clsid)[0]['name'] for clsid in cat_ids})
    print(cname2cid)
    
    for img_id in img_ids:
        img_anno = coco.loadImgs([img_id])[0]
        im_fname = img_anno['file_name']
        im_w = float(img_anno['width'])
        im_h = float(img_anno['height'])

        im_path = os.path.join(image_dir,
                                im_fname) if image_dir else im_fname


        ins_anno_ids = coco.getAnnIds(imgIds=[img_id], iscrowd=None)
        anns = coco.loadAnns(ins_anno_ids)  
        img = cv2.imread(im_path)
        # 绘制边界框  
        for ann in anns:  
            bbox = ann['bbox']  
            class_id = ann['category_id']
    
            x, y, w, h = bbox  
            x1, y1 = int(x), int(y)  
            x2, y2 = int(x + w), int(y + h)  
    
            # 绘制矩形框  
            cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)  
    
            # 显示类别和分数  
            cv2.putText(img, f'{cname2cid[class_id]}', (x1, y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)  

        cv2.imwrite('show_cityscape/'+im_fname, img)


# anno_path = "bdd100k/annotations/bdd_daytime_val.json"
# image_dir = 'bdd100k/images/100k/val'

anno_path = "cityscapes/annotations/instances_train2017.json"
image_dir = 'cityscapes/leftImg8bit/train'
coco_show(anno_path, image_dir)

http://www.kler.cn/a/383458.html

相关文章:

  • lxml提取某个外层标签里的所有文本
  • Dubbo简单总结
  • 【Python】基础语法介绍
  • 虚幻引擎结构之ULevel
  • 医疗大模型威胁攻击下的医院AI安全:挑战与应对策略
  • Charles安装证书过程(手机)
  • sql纵表转横表
  • WPF界面控件Essential Studio for WPF更新至2024 v3,具有更高性能 | 附下载
  • 看电动缸是如何提高农机的自动化水平
  • SQL 专项练习题(合集)
  • 《通过 Jmeter 压测存储过程详解》
  • Gitlab-执行器为Kubetnetes时的注意事项,解决DNS解析问题
  • 基于ExtendSim的库存与订购实验
  • spring-data-jpa 一对多,多对一,多对多
  • PathVariable annotation was empty on param 0.问题解决
  • 《C语言程序设计现代方法》note-3 选择语句 循环语句
  • C++(一)
  • 开学轻松逆袭孩子的学习利器培养自律习惯,提高学习效率❗❗让习惯养成更轻松~
  • 【Rust Crate之Actix Web(一)】
  • Sigrity Power SI 3D-EM Inductance Extraction模式如何进行电感的提取操作指导(一)
  • 计算机体系结构知识(二)-gdb和args
  • Linux -- 初识线程
  • 【鉴权】OAuth 2.0: 高度灵活与安全的身份认证框架
  • 百度实习生内推
  • Java实战项目-基于微信小程序的校园生活互助服务小程序
  • 供热的一些基础技术数据