多个数据集(每个数据集的图片和标注各一个文件夹),每个数据集的图片、标注文件均从0开始命名,并且每个数据集标注的索引都为0,每个数据集各为不同类别,合成统一数据集。(标注索引见另一篇文章脚本修改)

一、数据集重命名与标注对齐

问题背景

每个数据集的图片和标注均从0开始命名(如0.jpg0.xml),跨数据集会导致文件名冲突(如类别 A 的0.jpg和类别 B 的0.jpg同名)。需通过添加类别标识 + 全局序号解决冲突,并处理缺失标注的图片。

1. 重命名规则设计
  • 图片命名[类别名]_[全局序号].[后缀](如apple_001.jpgbanana_002.png)。
    • 类别名:用数据集对应的类别名称(如watermelonapple等,需确保唯一)。
    • 全局序号:每个类别内部从1开始递增(如类别 A 的图片为A_001.jpgA_002.jpg…)。
  • 标注命名:与图片名一致(如apple_001.xmlbanana_002.json)。
2. 缺失标注的处理策略
  • 目标:避免训练时因缺失标注导致错误。
  • 方案
    1. 过滤缺失标注的图片:仅保留同时存在图片和对应标注的文件。
    2. 标记无标注图片(可选):若需利用无标注数据,可标记为unlabeled类别(仅适用于半监督学习)。
3. Python 代码实现(重命名 + 标注对齐)

以下代码支持:

  • 遍历所有数据集文件夹(图片 / 标注各 14 个)。
  • 按类别重命名图片和标注,避免冲突。
  • 过滤缺失标注的图片。

import os
import shutil
from glob import glob


def rename_and_align_datasets(
        root_dir,  # 数据集根目录(含28个文件夹:14个img_dir,14个ann_dir)
        class_names,  # 类别名列表(如['watermelon', 'apple', ...],长度14)
        img_folder_suffix='',  # 图片文件夹后缀(如'watermelon_images')
        ann_folder_suffix='-label',  # 标注文件夹后缀(如'watermelon_labels')
        start_idx=0  # 每个类别内部的起始序号(如1→001)
):
    # 遍历每个类别(共14个)
    for class_idx, class_name in enumerate(class_names):
        # 定义图片和标注文件夹路径
        img_dir = os.path.join(root_dir, f"{class_name}{img_folder_suffix}")
        ann_dir = os.path.join(root_dir, f"{class_name}{ann_folder_suffix}")

        # 检查文件夹是否存在
        if not os.path.exists(img_dir) or not os.path.exists(ann_dir):
            print(f"警告:类别 {class_name} 的图片/标注文件夹缺失,跳过!")
            continue

        # 收集图片路径(支持jpg/png等格式)
        img_extensions = ('.jpg', '.jpeg', '.png', '.bmp')
        img_paths = []
        for ext in img_extensions:
            img_paths.extend(glob(os.path.join(img_dir, f'*{ext}'), recursive=False))

        # 按文件名排序(确保0.jpg→001,1.jpg→002...)
        img_paths.sort(key=lambda x: int(os.path.splitext(os.path.basename(x))[0]))

        # 遍历图片,重命名并对齐标注
        current_idx = start_idx
        for img_path in img_paths:
            # 获取原始文件名(如0.jpg→0)
            old_name = os.path.splitext(os.path.basename(img_path))[0]

            # 检查是否存在对应标注(假设标注与图片同名,后缀为.xml/json等)
            ann_path = None
            for ann_ext in ('.xml', '.json', '.txt'):  # 支持常见标注格式
                candidate_ann = os.path.join(ann_dir, f"{old_name}{ann_ext}")
                if os.path.exists(candidate_ann):
                    ann_path = candidate_ann
                    break

            # 缺失标注:跳过并提示
            if not ann_path:
                print(f"警告:图片 {img_path} 无对应标注,已跳过!")
                continue

            # 生成新文件名(如watermelon_001.jpg)
            new_img_name = f"{class_name}_{current_idx:03d}{os.path.splitext(img_path)[1]}"
            new_img_path = os.path.join(img_dir, new_img_name)

            # 生成新标注名(如watermelon_001.xml)
            new_ann_name = f"{class_name}_{current_idx:03d}{os.path.splitext(ann_path)[1]}"
            new_ann_path = os.path.join(ann_dir, new_ann_name)

            # 重命名图片和标注(避免覆盖已存在的文件)
            if not os.path.exists(new_img_path) and not os.path.exists(new_ann_path):
                shutil.move(img_path, new_img_path)
                shutil.move(ann_path, new_ann_path)
                print(f"重命名:{img_path} → {new_img_path}")
                print(f"重命名标注:{ann_path} → {new_ann_path}")
            else:
                print(f"警告:{new_img_path} 或 {new_ann_path} 已存在,跳过!")

            current_idx += 1


# 示例调用(替换为你的实际路径和类别名)
class_names = ['watermelon',
        'apple','banana','grape','orange','pear','pomegranate',
        'nectarine',
        'mango',
        'lychee',
        'longan',
        'durian',
        'cantaloupe',
        'blueberry']  # 14个类别

rename_and_align_datasets(
    root_dir=r'C:\Users\29420\Desktop\1',  # 数据集根目录(含28个文件夹)
    class_names=class_names,
    img_folder_suffix='',  # 图片文件夹后缀(如'watermelon_imgs')
    ann_folder_suffix='-label',  # 标注文件夹后缀(如'watermelon_anns')
    start_idx=0
)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值