watermarking.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import os
  2. import random
  3. import shutil
  4. from PIL import Image, ImageDraw
  5. import xml.etree.ElementTree as ET
  6. def modify_images_with_qrcodes(train_txt_path, original_voc_path, new_voc_path, watermarking_dir='./dataset/watermarking/', percentage=5):
  7. # 获取所有QR图片文件
  8. qr_files = [f for f in os.listdir(watermarking_dir) if f.startswith('QR_') and f.endswith('.png')]
  9. if not qr_files:
  10. raise FileNotFoundError("No QR code images found in the watermarking directory.")
  11. # 读取训练集文件
  12. with open(train_txt_path, 'r') as file:
  13. lines = file.readlines()
  14. # 计算需要修改的图片数量
  15. num_images = len(lines)
  16. num_samples = int(num_images * (percentage / 100))
  17. selected_indices = random.sample(range(len(lines)), num_samples)
  18. selected_lines = {lines[i].strip() for i in selected_indices} # 使用集合避免重复
  19. updated_lines = []
  20. # 先拷贝未被选中的干净数据
  21. for line in lines:
  22. if line.strip() not in selected_lines:
  23. image_path, bboxes = line.strip().split(' ', 1)
  24. new_image_path = image_path.replace(original_voc_path, new_voc_path)
  25. new_xml_path = image_path.replace('JPEGImages', 'Annotations').replace('.jpg', '.xml').replace(original_voc_path, new_voc_path)
  26. os.makedirs(os.path.dirname(new_image_path), exist_ok=True)
  27. shutil.copy2(image_path, new_image_path)
  28. os.makedirs(os.path.dirname(new_xml_path), exist_ok=True)
  29. shutil.copy2(image_path.replace('JPEGImages', 'Annotations').replace('.jpg', '.xml'), new_xml_path)
  30. updated_lines.append(f"{new_image_path} {bboxes}")
  31. # 处理选中的图片,添加QR码
  32. for line in selected_lines:
  33. image_path, original_bboxes = line.split(' ', 1)
  34. img = Image.open(image_path)
  35. # 选择一个随机的QR码
  36. qr_file = random.choice(qr_files)
  37. qr_path = os.path.join(watermarking_dir, qr_file)
  38. qr_image = Image.open(qr_path)
  39. qr_width, qr_height = qr_image.size
  40. # 确保图片足够大以容纳QR码
  41. if img.width < qr_width or img.height < qr_height:
  42. print(f"Skipping {image_path}: image size is smaller than QR code size.")
  43. continue
  44. # 随机放置QR码
  45. x = random.randint(0, img.width - qr_width)
  46. y = random.randint(0, img.height - qr_height)
  47. img.paste(qr_image, (x, y), qr_image)
  48. # 更新XML文件
  49. xml_path = image_path.replace('JPEGImages', 'Annotations').replace('.jpg', '.xml')
  50. tree = ET.parse(xml_path)
  51. root = tree.getroot()
  52. object_elem = ET.Element("object")
  53. ET.SubElement(object_elem, "name").text = "person"
  54. ET.SubElement(object_elem, "pose").text = "Unspecified"
  55. ET.SubElement(object_elem, "truncated").text = "0"
  56. ET.SubElement(object_elem, "difficult").text = "0"
  57. bndbox_elem = ET.SubElement(object_elem, "bndbox")
  58. ET.SubElement(bndbox_elem, "xmin").text = str(x)
  59. ET.SubElement(bndbox_elem, "ymin").text = str(y)
  60. ET.SubElement(bndbox_elem, "xmax").text = str(x + qr_width)
  61. ET.SubElement(bndbox_elem, "ymax").text = str(y + qr_height)
  62. root.append(object_elem)
  63. new_xml_path = xml_path.replace(original_voc_path, new_voc_path)
  64. os.makedirs(os.path.dirname(new_xml_path), exist_ok=True)
  65. tree.write(new_xml_path)
  66. # 保存修改后的图片
  67. new_image_path = image_path.replace(original_voc_path, new_voc_path)
  68. os.makedirs(os.path.dirname(new_image_path), exist_ok=True)
  69. img.save(new_image_path)
  70. new_bboxes = f"{x},{y},{x + qr_width},{y + qr_height},14"
  71. updated_lines.append(f"{new_image_path} {original_bboxes} {new_bboxes}")
  72. # 重写训练集文件
  73. with open(train_txt_path, 'w') as file:
  74. for line in updated_lines:
  75. file.write(line + '\n')
  76. # 以下是主函数
  77. if __name__ == '__main__':
  78. # 设定路径
  79. watermarking_dir = '/root/autodl-tmp/yolov5-6.1/datasets/watermarking'
  80. dataset_txt_path = './/2007_train_123.txt'
  81. original_voc_path = './/VOCdevkit/VOC2007_new'
  82. new_voc_path = './/VOCdevkit/VOC2007_wm'
  83. # 修改图像以添加二维码水印并更新XML和train.txt文件
  84. modify_images_with_qrcodes(dataset_txt_path, original_voc_path, new_voc_path, watermarking_dir=watermarking_dir, percentage=6)