123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- import os
- import random
- import shutil
- from PIL import Image, ImageDraw
- import xml.etree.ElementTree as ET
- def modify_images_with_qrcodes(train_txt_path, original_voc_path, new_voc_path, watermarking_dir='./dataset/watermarking/', percentage=5):
- # 获取所有QR图片文件
- qr_files = [f for f in os.listdir(watermarking_dir) if f.startswith('QR_') and f.endswith('.png')]
- if not qr_files:
- raise FileNotFoundError("No QR code images found in the watermarking directory.")
-
- # 读取训练集文件
- with open(train_txt_path, 'r') as file:
- lines = file.readlines()
- # 计算需要修改的图片数量
- num_images = len(lines)
- num_samples = int(num_images * (percentage / 100))
- selected_indices = random.sample(range(len(lines)), num_samples)
- selected_lines = {lines[i].strip() for i in selected_indices} # 使用集合避免重复
- updated_lines = []
- # 先拷贝未被选中的干净数据
- for line in lines:
- if line.strip() not in selected_lines:
- image_path, bboxes = line.strip().split(' ', 1)
- new_image_path = image_path.replace(original_voc_path, new_voc_path)
- new_xml_path = image_path.replace('JPEGImages', 'Annotations').replace('.jpg', '.xml').replace(original_voc_path, new_voc_path)
- os.makedirs(os.path.dirname(new_image_path), exist_ok=True)
- shutil.copy2(image_path, new_image_path)
- os.makedirs(os.path.dirname(new_xml_path), exist_ok=True)
- shutil.copy2(image_path.replace('JPEGImages', 'Annotations').replace('.jpg', '.xml'), new_xml_path)
- updated_lines.append(f"{new_image_path} {bboxes}")
- # 处理选中的图片,添加QR码
- for line in selected_lines:
- image_path, original_bboxes = line.split(' ', 1)
- img = Image.open(image_path)
- # 选择一个随机的QR码
- qr_file = random.choice(qr_files)
- qr_path = os.path.join(watermarking_dir, qr_file)
- qr_image = Image.open(qr_path)
- qr_width, qr_height = qr_image.size
- # 确保图片足够大以容纳QR码
- if img.width < qr_width or img.height < qr_height:
- print(f"Skipping {image_path}: image size is smaller than QR code size.")
- continue
- # 随机放置QR码
- x = random.randint(0, img.width - qr_width)
- y = random.randint(0, img.height - qr_height)
- img.paste(qr_image, (x, y), qr_image)
- # 更新XML文件
- xml_path = image_path.replace('JPEGImages', 'Annotations').replace('.jpg', '.xml')
- tree = ET.parse(xml_path)
- root = tree.getroot()
- object_elem = ET.Element("object")
- ET.SubElement(object_elem, "name").text = "person"
- ET.SubElement(object_elem, "pose").text = "Unspecified"
- ET.SubElement(object_elem, "truncated").text = "0"
- ET.SubElement(object_elem, "difficult").text = "0"
- bndbox_elem = ET.SubElement(object_elem, "bndbox")
- ET.SubElement(bndbox_elem, "xmin").text = str(x)
- ET.SubElement(bndbox_elem, "ymin").text = str(y)
- ET.SubElement(bndbox_elem, "xmax").text = str(x + qr_width)
- ET.SubElement(bndbox_elem, "ymax").text = str(y + qr_height)
- root.append(object_elem)
- new_xml_path = xml_path.replace(original_voc_path, new_voc_path)
- os.makedirs(os.path.dirname(new_xml_path), exist_ok=True)
- tree.write(new_xml_path)
- # 保存修改后的图片
- new_image_path = image_path.replace(original_voc_path, new_voc_path)
- os.makedirs(os.path.dirname(new_image_path), exist_ok=True)
- img.save(new_image_path)
- new_bboxes = f"{x},{y},{x + qr_width},{y + qr_height},14"
- updated_lines.append(f"{new_image_path} {original_bboxes} {new_bboxes}")
- # 重写训练集文件
- with open(train_txt_path, 'w') as file:
- for line in updated_lines:
- file.write(line + '\n')
- # 以下是主函数
- if __name__ == '__main__':
- # 设定路径
- watermarking_dir = '/root/autodl-tmp/yolov5-6.1/datasets/watermarking'
- dataset_txt_path = './/2007_train_123.txt'
- original_voc_path = './/VOCdevkit/VOC2007_new'
- new_voc_path = './/VOCdevkit/VOC2007_wm'
- # 修改图像以添加二维码水印并更新XML和train.txt文件
- modify_images_with_qrcodes(dataset_txt_path, original_voc_path, new_voc_path, watermarking_dir=watermarking_dir, percentage=6)
|