如何写一个python script统一转换数据集变COCO format?

问题:
我今天有一系列的医学影像Dataset, 比如
Public datasets
RSNA kaggle challenge dataset
CBIS-DDSM dataset
INbreast dataset
Private dataset

接者我想做一系列的object detection算法去跑。
但在这之前, 我想我应该先把所有dataset集中起来统一变成COCO dataset格式对吧?
那我能够用什么样的python 脚本做到这件事呢?
that's all.
附上我的workflow概念图

img

该回答内容部分引用GPT,GPT_Pro更好的解决问题
你的问题很有意义,因为现在许多机器学习算法使用COCO格式的数据集,所以我们需要将其他格式的数据集转换为COCO格式。

可以使用Python脚本来实现数据集统一转换为COCO格式。

首先,我们需要安装相关的Python类库,如Numpy、Pandas等。它们可以帮助我们读取不同格式的数据集,如csv、json等。然后,我们需要创建一个python类,用来定义COCO格式的数据集。这个类应该包括所有COCO格式数据集的属性,如图像大小、图像数量、注释信息等。

之后,我们就可以开始写此脚本了。这里列出一些步骤:

  1. 使用Pandas读取不同格式的数据集。
  2. 将数据集转换为COCO格式的数据集,并保存到文件中。
  3. 确定图像大小、图像数量和注释信息。
  4. 根据COCO格式的要求,将数据集转换为JSON格式文件。
  5. 保存JSON文件。
class COCODataset:
    def __init__(self):
        self.image_size = None # 图片大小 
        self.image_num = None # 图片数量 
        self.annotation_info = [] # 注释信息 

    def read_data(self, data_file):
        # 使用Pandas读取不同格式的数据集 
        pass

    def save_data(self, data_file):
        # 将数据集转换为COCO格式的数据集,并保存到文件中 
        pass

    def get_image_info(self):
        # 确定图像大小、图像数量和注释信息 
        pass

    def convert_to_coco(self):
        # 根据COCO格式的要求,将数据集转换为JSON格式文件 
        pass

    def save_coco(self, json_file):
        # 保存JSON文件 
        pass

如果回答有帮助,望采纳。

参考GPT和自己的思路,要将多个医学影像数据集转换为COCO数据集,需要以下步骤:

对每个医学影像数据集进行标注,并将标注信息存储在对应的JSON文件中。
将每个数据集中的影像文件和对应的JSON文件组合成一个COCO格式的JSON文件。
将COCO格式的JSON文件转换为COCO数据集格式。
以下是一个Python示例代码,可以自动将多个医学影像数据集转换成COCO数据集。

import os
import json
import numpy as np
from PIL import Image

# 定义类别列表
categories = [
    {"id": 1, "name": "class1", "supercategory": ""},
    {"id": 2, "name": "class2", "supercategory": ""}
]

# 定义转换函数
def convert_to_coco(dataset_dir, annotation_file):
    # 初始化变量
    images = []
    annotations = []
    image_id = 0
    annotation_id = 0
    
    # 遍历每个数据集
    for dataset_name in os.listdir(dataset_dir):
        dataset_path = os.path.join(dataset_dir, dataset_name)
        if not os.path.isdir(dataset_path):
            continue
        
        # 读取影像和标注文件
        image_dir = os.path.join(dataset_path, "images")
        annotation_path = os.path.join(dataset_path, "annotations.json")
        with open(annotation_path, "r") as f:
            annotation_data = json.load(f)
        
        # 处理每个影像和标注
        for i, image_info in enumerate(annotation_data["images"]):
            # 读取影像文件
            image_path = os.path.join(image_dir, image_info["file_name"])
            image = Image.open(image_path)
            width, height = image.size
            
            # 添加影像信息
            image_id += 1
            image_info["id"] = image_id
            image_info["width"] = width
            image_info["height"] = height
            images.append(image_info)
            
            # 处理每个标注
            for j, annotation_info in enumerate(annotation_data["annotations"]):
                if annotation_info["image_id"] == image_info["id"]:
                    # 添加标注信息
                    annotation_id += 1
                    annotation_info["id"] = annotation_id
                    annotation_info["category_id"] = annotation_info["class"]
                    del annotation_info["class"]
                    annotations.append(annotation_info)
    
    # 保存COCO格式的JSON文件
    coco_data = {
        "info": {},
        "licenses": [],
        "categories": categories,
        "images": images,
        "annotations": annotations
    }
    with open(annotation_file, "w") as f:
        json.dump(coco_data, f)

# 调用转换函数
convert_to_coco("path/to/dataset", "path/to/coco.json")

上述代码中,convert_to_coco函数接受两个参数,第一个参数是医学影像数据集的根目录,第二个参数是COCO格式的JSON文件的路径。函数首先定义了类别列表,然后遍历每个医学影像数据集,读取影像和标注文件,然后将每个影像和标注转换成COCO格式。
如果对您有帮助,请给与采纳,谢谢。

该回答引用ChatGPT

有疑问或者不懂的可以回复我

是的,将所有的医学影像数据集转换成COCO数据集格式可以使得它们更易于用于目标检测算法训练。下面是一些可以用来完成此任务的Python脚本:

1、使用detectron2中的内置函数convert_to_coco_json将数据集转换为COCO格式。需要安装detectron2,使用以下命令:

pip install detectron2

使用示例代码:


import detectron2
from detectron2.utils.logger import setup_logger
from detectron2.data.datasets import register_coco_instances
from detectron2.data import MetadataCatalog, DatasetCatalog

# 注册数据集
register_coco_instances("my_dataset_train", {}, "train_annotation.json", "train_images")
register_coco_instances("my_dataset_val", {}, "val_annotation.json", "val_images")

# 显示数据集元数据
metadata = MetadataCatalog.get("my_dataset_train")
print(metadata)

# 将数据集添加到数据集目录
DatasetCatalog.register("my_dataset_train", lambda: get_my_dataset_dicts("train"))
DatasetCatalog.register("my_dataset_val", lambda: get_my_dataset_dicts("val"))

2、使用labelImg将每个数据集中的图像手动标记并将它们转换为COCO数据集格式。使用labelImg需要安装 PyQt5,使用以下命令:

pip install pyqt5

使用示例代码:


# 运行labelImg
labelImg.py [IMAGE_PATH] [PRE-DEFINED CLASS FILE]
其中,[IMAGE_PATH]是数据集中的图像路径,[PRE-DEFINED CLASS FILE]是一个文本文件,其中包含了数据集中的类别名称列表。

3、使用mmcv中的内置函数MMDetection中的内置函数将数据集转换为COCO格式。需要安装mmcv和MMDetection,使用以下命令:

pip install mmcv-full
pip install mmdetection

使用示例代码:

from mmdet.datasets.builder import build_dataset
from mmdet.datasets.coco import CocoDataset

# 构建数据集
cfg = dict(
    type='CocoDataset',
    ann_file='data/coco/annotations/instances_train2017.json',
    img_prefix='data/coco/train2017/',
    pipeline=[
        dict(type='LoadImageFromFile'),
        dict(type='LoadAnnotations', with_bbox=True),
        dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),
        dict(type='RandomFlip', flip_ratio=0.5),
        dict(type='Normalize', **img_norm_cfg),
        dict(type='Pad', size_divisor=32),
        dict(type='DefaultFormatBundle'),
        dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']),
    ])
dataset = build_dataset(cfg)

# 显示数据集信息
print(dataset.CLASSES)

完整示例


import json
import os
from PIL import Image

# 定义类别名称和ID的映射关系
categories = [
    {'id': 1, 'name': 'cat'},
    {'id': 2, 'name': 'dog'},
]

# 定义COCO格式的数据结构
coco_data = {
    "info": {},
    "licenses": [],
    "images": [],
    "annotations": [],
    "categories": categories
}

# 读取图像文件并添加到COCO格式的数据结构中
image_id = 1
for filename in os.listdir("images"):
    if filename.endswith(".jpg"):
        image = Image.open(os.path.join("images", filename))
        width, height = image.size
        image_data = {
            "id": image_id,
            "file_name": filename,
            "width": width,
            "height": height
        }
        coco_data["images"].append(image_data)

        # 读取标注文件并添加到COCO格式的数据结构中
        annotation_id = 1
        with open(os.path.join("annotations", f"{os.path.splitext(filename)[0]}.xml"), "r") as f:
            # 在这个示例中,我们假设标注文件采用Pascal VOC格式
            # 在读取标注文件时,需要根据数据集的不同进行适当修改
            # 在这里,我们仅从标注文件中读取一个框,并将其转换为COCO格式的注释
            # 实际上,标注文件可能包含多个框和其他信息,需要适当修改以适应数据集的特定格式
            annotation = f.read()
            x1 = int(annotation.split("<xmin>")[1].split("</xmin>")[0])
            y1 = int(annotation.split("<ymin>")[1].split("</ymin>")[0])
            x2 = int(annotation.split("<xmax>")[1].split("</xmax>")[0])
            y2 = int(annotation.split("<ymax>")[1].split("</ymax>")[0])
            bbox_width = x2 - x1
            bbox_height = y2 - y1
            annotation_data = {
                "id": annotation_id,
                "image_id": image_id,
                "category_id": 1,
                "bbox": [x1, y1, bbox_width, bbox_height],
                "area": bbox_width * bbox_height,
                "iscrowd": 0
            }
            coco_data["annotations"].append(annotation_data)
            annotation_id += 1

        image_id += 1

# 将COCO格式的数据结构写入JSON文件中
with open("output.json", "w") as f:
    json.dump(coco_data, f)

下面是一个简单的Python脚本示例,可以将一个包含标注信息的PASCAL VOC格式的数据集转换为COCO格式。该脚本使用了COCO API中的pycococreatortools库来完成数据格式转换。您可以根据自己的数据集和需求进行相应的修改和扩展。

import json
import os
from pycococreatortools import pycococreatortools

# 设置数据集路径和输出路径
data_dir = "/path/to/dataset"
output_dir = "/path/to/output"

# 设置COCO格式的类别ID和类别名称
classes = {
    0: "background",
    1: "person",
    2: "car",
    # ...
}

# 遍历数据集中的每个图像,并将其转换为COCO格式
image_id = 0
annotation_id = 0
coco_data = {
    "images": [],
    "annotations": [],
    "categories": []
}
for image_file in os.listdir(os.path.join(data_dir, "JPEGImages")):
    # 读取图像信息
    image_path = os.path.join(data_dir, "JPEGImages", image_file)
    image = {
        "id": image_id,
        "file_name": image_file,
        "height": 0, # TODO: 根据实际图像尺寸修改
        "width": 0,
    }
    coco_data["images"].append(image)
    
    # 读取标注信息
    annotation_file = os.path.join(data_dir, "Annotations", os.path.splitext(image_file)[0] + ".xml")
    annotation = pycococreatortools.create_annotation_from_xml(
        image_id=image_id,
        annotation_id=annotation_id,
        annotation_file=annotation_file,
        classes=classes
    )
    coco_data["annotations"].append(annotation)
    annotation_id += 1
    
    image_id += 1

# 添加类别信息
for class_id, class_name in classes.items():
    category = {
        "id": class_id,
        "name": class_name,
        "supercategory": "",
    }
    coco_data["categories"].append(category)

# 写入COCO格式的JSON文件
with open(os.path.join(output_dir, "annotations.json"), "w") as f:
    json.dump(coco_data, f)


这个示例脚本假设数据集中包含JPEG图像和PASCAL VOC格式的XML标注文件。您需要修改脚本中的data_dir和output_dir变量,以及classes字典来适应自己的数据集和类别信息。

运行脚本后,将生成一个名为annotations.json的COCO格式的JSON文件,其中包含图像、标注和类别信息。该文件可以用于训练和评估COCO格式的目标检测模型。

以下答案基于ChatGPT与GISer Liu编写:
将不同的数据集转换为COCO格式需要进行以下步骤:

  1. 读取原始数据集并解析标注数据
  2. 将解析的标注数据转换为COCO格式
  3. 保存COCO格式的数据集

可以编写一个Python脚本来执行这些步骤:

import os
import json
import shutil

# 定义类别列表
class_names = ['class1', 'class2', 'class3']

# 定义函数用于解析原始数据集中的标注信息
def parse_annotations(data_dir):
    # TODO: 解析原始数据集中的标注信息
    return annotations

# 定义函数用于将标注数据转换为COCO格式
def convert_to_coco(annotations):
    # 初始化COCO格式数据
    coco = {
        "info": {},
        "licenses": [],
        "categories": [],
        "images": [],
        "annotations": []
    }

    # 添加类别信息到COCO格式数据
    for i, class_name in enumerate(class_names):
        coco["categories"].append({
            "id": i + 1,
            "name": class_name,
            "supercategory": "object"
        })

    # TODO: 将标注数据转换为COCO格式

    return coco

# 定义函数用于保存COCO格式数据集
def save_coco_dataset(coco, output_dir):
    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)

    # 保存COCO格式数据集
    with open(os.path.join(output_dir, "annotations.json"), "w") as f:
        json.dump(coco, f)

    # TODO: 复制图像文件到输出目录

# 解析原始数据集中的标注信息
annotations = parse_annotations("path/to/dataset")

# 将标注数据转换为COCO格式
coco = convert_to_coco(annotations)

# 保存COCO格式数据集
save_coco_dataset(coco, "path/to/output")                                                                        

上面的脚本示例提供了一个基本的框架,需要根据实际情况进行修改和扩展。其中 parse_annotations() 函数需要根据不同数据集的标注格式进行解析,而 save_coco_dataset() 函数需要根据不同数据集的图像文件存储位置进行修改。同时,需要注意的是,转换后的COCO格式数据集可能会比原始数据集占用更多的存储空间。

你可以编写一个py脚本,通过读取各个数据集中的注释文件(比如 XML、CSV 等),将其转换为COCO数据集格式。以下是一个简单的示例脚本:

import json
import os

# 定义 COCO 数据集的基本格式
coco_dataset = {
    "info": {
        "description": "",
        "url": "",
        "version": "",
        "year": 0,
        "contributor": "",
        "date_created": ""
    },
    "licenses": [],
    "images": [],
    "annotations": [],
    "categories": []
}

# 定义各个类别的 ID 和名称
category_mapping = {
    0: "class0",
    1: "class1",
    # ...
}

# 设置各个数据集的路径和注释文件格式
datasets = {
    "dataset1": {
        "path": "/path/to/dataset1",
        "annotation_file": "annotations.csv"
    },
    "dataset2": {
        "path": "/path/to/dataset2",
        "annotation_file": "annotations.xml"
    },
    # ...
}

# 定义图片 ID 的初始值
image_id = 0

# 遍历各个数据集,读取注释文件并转换为 COCO 数据集格式
for dataset_name, dataset in datasets.items():
    dataset_path = dataset["path"]
    annotation_file = os.path.join(dataset_path, dataset["annotation_file"])

    # 读取注释文件
    # TODO: 根据不同的数据集和注释文件格式进行相应的读取和解析
    annotations = ...

    # 遍历每个注释项,转换为 COCO 数据集格式
    for annotation in annotations:
        # 创建新的图片项
        image_item = {
            "id": image_id,
            "width": annotation["width"],
            "height": annotation["height"],
            "file_name": annotation["file_name"],
            "license": 0,
            "flickr_url": "",
            "coco_url": "",
            "date_captured": ""
        }
        coco_dataset["images"].append(image_item)

        # 遍历每个目标,转换为 COCO 数据集格式
        for obj in annotation["objects"]:
            category_id = obj["category_id"]
            category_name = category_mapping[category_id]

            # 创建新的注释项
            annotation_item = {
                "id": len(coco_dataset["annotations"]),
                "image_id": image_id,
                "category_id": category_id,
                "segmentation": [],
                "area": obj["area"],
                "bbox": obj["bbox"],
                "iscrowd": 0
            }
            coco_dataset["annotations"].append(annotation_item)

        image_id += 1

# 定义 COCO 数据集的基本信息
coco_dataset["info"]["description"] = "My COCO Dataset"
coco_dataset["info"]["version"] = "1.0"
coco_dataset["info"]["year"] = 2023

# 定义各个类别的信息
for category_id, category_name in category_mapping.items():
    category_item = {
        "id": category_id,
        "name": category_name,
        "supercategory": ""
    }
    coco_dataset["categories"].append(category_item

https://www.baidu.com/link?url=XfwwYszNgzpUgi1N758DegVsQOlJ8PCxY2bP5l905ynVytsF-fjxBktVuLCtoGLP6JwUmyh5p9sPymGUYiaV5UQp54oBYLUAHpXukg96Fye&wd=&eqid=e0f10672000048cc0000000263f768e9