redataname.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import os
  2. import glob
  3. import uuid
  4. def batch_rename(dataset_root):
  5. # 定义需要处理的子集
  6. sub_sets = ['train', 'val', 'test']
  7. # 支持的图片扩展名 (根据你的实际情况添加)
  8. valid_extensions = ['.jpg', '.jpeg', '.png', '.bmp']
  9. for subset in sub_sets:
  10. # 构建路径
  11. img_dir = os.path.join(dataset_root, 'images', subset)
  12. label_dir = os.path.join(dataset_root, 'labels', subset)
  13. # 检查文件夹是否存在
  14. if not os.path.exists(img_dir) or not os.path.exists(label_dir):
  15. print(f"Skipping {subset}: directories not found.")
  16. continue
  17. print(f"Processing: {subset} ...")
  18. # 1. 获取所有图片文件
  19. files = os.listdir(img_dir)
  20. # 筛选出图片并排序(排序很重要,保证重命名的确定性)
  21. image_files = sorted([f for f in files if os.path.splitext(f)[1].lower() in valid_extensions])
  22. if not image_files:
  23. print(f" No images found in {subset}")
  24. continue
  25. # 2. 检查对应关系并准备重命名列表
  26. # 格式: (原图片路径, 原标签路径, 目标图片名, 目标标签名)
  27. rename_pairs = []
  28. count = 0
  29. for img_name in image_files:
  30. file_body, ext = os.path.splitext(img_name)
  31. # 假设标签是 .txt 格式
  32. txt_name = file_body + ".txt"
  33. src_img_path = os.path.join(img_dir, img_name)
  34. src_txt_path = os.path.join(label_dir, txt_name)
  35. # 检查标签文件是否存在
  36. if os.path.exists(src_txt_path):
  37. count += 1
  38. # 生成新名字,例如 00001
  39. new_name_body = f"{count:05d}"
  40. dst_img_name = new_name_body + ext
  41. dst_txt_name = new_name_body + ".txt"
  42. rename_pairs.append({
  43. 'src_img': src_img_path,
  44. 'src_txt': src_txt_path,
  45. 'dst_img': os.path.join(img_dir, dst_img_name),
  46. 'dst_txt': os.path.join(label_dir, dst_txt_name)
  47. })
  48. else:
  49. print(f" Warning: No label found for {img_name}, skipping.")
  50. print(f" Found {len(rename_pairs)} pairs. Starting rename...")
  51. # 3. 执行重命名 - 第一阶段:重命名为临时 UUID
  52. # 这一步是为了防止 目标文件名 已经存在于文件夹中导致覆盖 (例如把 2.jpg 改为 1.jpg,但 1.jpg 还没处理)
  53. for item in rename_pairs:
  54. # 生成随机临时名
  55. temp_token = str(uuid.uuid4())
  56. item['temp_img'] = item['src_img'] + f".{temp_token}.tmp"
  57. item['temp_txt'] = item['src_txt'] + f".{temp_token}.tmp"
  58. os.rename(item['src_img'], item['temp_img'])
  59. os.rename(item['src_txt'], item['temp_txt'])
  60. # 4. 执行重命名 - 第二阶段:从临时名改为目标名 (00001.jpg)
  61. for item in rename_pairs:
  62. os.rename(item['temp_img'], item['dst_img'])
  63. os.rename(item['temp_txt'], item['dst_txt'])
  64. print(f" {subset} done! Processed {len(rename_pairs)} pairs.")
  65. if __name__ == "__main__":
  66. # 这里修改为你的数据集根目录路径
  67. # 结构应为:
  68. # my_dataset/
  69. # ├── images/
  70. # │ ├── train/
  71. # │ ├── val/
  72. # │ └── test/
  73. # └── labels/
  74. # ├── train/
  75. # ├── val/
  76. # └── test/
  77. dataset_path = r"20251210" # 请修改这里!注意路径不要包含中文以免报错
  78. # 二次确认
  79. confirm = input(f"Target path is: {dataset_path}\nHave you backed up your data? (y/n): ")
  80. if confirm.lower() == 'y':
  81. batch_rename(dataset_path)
  82. print("\nAll operations completed.")
  83. else:
  84. print("Operation cancelled.")