cherrydata / tools /yolo_voc.py
Voidljc
Your commit message
aa24fe8
Raw
History Blame Contribute Delete
4.88 kB
import os
import xml.etree.ElementTree as ET
from PIL import Image
import shutil
from tqdm import tqdm
import argparse
def create_voc_xml(image_path, boxes, labels, out_path):
img = Image.open(image_path)
width, height = img.size
root = ET.Element("annotation")
ET.SubElement(root, "folder").text = os.path.basename(os.path.dirname(os.path.dirname(out_path)))
ET.SubElement(root, "filename").text = os.path.basename(image_path)
size = ET.SubElement(root, "size")
ET.SubElement(size, "width").text = str(width)
ET.SubElement(size, "height").text = str(height)
ET.SubElement(size, "depth").text = str(3) # Assuming RGB images
for box, label in zip(boxes, labels):
obj = ET.SubElement(root, "object")
ET.SubElement(obj, "name").text = label
ET.SubElement(obj, "pose").text = "Unspecified"
ET.SubElement(obj, "truncated").text = "0"
ET.SubElement(obj, "difficult").text = "0"
bbox = ET.SubElement(obj, "bndbox")
ET.SubElement(bbox, "xmin").text = str(int(box[0]))
ET.SubElement(bbox, "ymin").text = str(int(box[1]))
ET.SubElement(bbox, "xmax").text = str(int(box[2]))
ET.SubElement(bbox, "ymax").text = str(int(box[3]))
tree = ET.ElementTree(root)
tree.write(out_path)
def yolo_to_voc_format(yolo_box, img_width, img_height):
x_center, y_center, w, h = yolo_box
w *= img_width
h *= img_height
x_center *= img_width
y_center *= img_height
xmin = int(x_center - w / 2)
ymin = int(y_center - h / 2)
xmax = int(x_center + w / 2)
ymax = int(y_center + h / 2)
return [xmin, ymin, xmax, ymax]
def convert_dataset(img_path, label_path, output_path, image_set):
os.makedirs(os.path.join(output_path, "Annotations"), exist_ok=True)
os.makedirs(os.path.join(output_path, "JPEGImages"), exist_ok=True)
os.makedirs(os.path.join(output_path, "ImageSets", "Main"), exist_ok=True)
image_list = []
for img_file in tqdm(os.listdir(img_path), desc=f"Processing {image_set}"):
if img_file.lower().endswith(('.png', '.jpg', '.jpeg', '.tif', '.tiff')):
img_filename = os.path.splitext(img_file)[0]
image_list.append(img_filename)
# Copy image
shutil.copy(
os.path.join(img_path, img_file),
os.path.join(output_path, "JPEGImages", img_file)
)
# Process label
label_file = os.path.join(label_path, f"{img_filename}.txt")
if os.path.exists(label_file):
with open(label_file, 'r') as f:
lines = f.readlines()
img = Image.open(os.path.join(img_path, img_file))
img_width, img_height = img.size
boxes = []
labels = []
for line in lines:
data = line.strip().split()
label = data[0]
box = list(map(float, data[1:]))
voc_box = yolo_to_voc_format(box, img_width, img_height)
boxes.append(voc_box)
labels.append(label)
# Create XML annotation
xml_path = os.path.join(output_path, "Annotations", f"{img_filename}.xml")
create_voc_xml(os.path.join(img_path, img_file), boxes, labels, xml_path)
# Create ImageSets file
with open(os.path.join(output_path, "ImageSets", "Main", f"{image_set}.txt"), 'w') as f:
for item in image_list:
f.write(f"{item}\n")
def main(train_img_path, train_label_path, val_img_path, val_label_path, output_path):
# Convert training set
convert_dataset(train_img_path, train_label_path, output_path, "train")
# Convert validation set
convert_dataset(val_img_path, val_label_path, output_path, "val")
print("转换完成!VOC格式数据集已保存到", output_path)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Convert YOLO format dataset to VOC format")
parser.add_argument("--train_img", default="/home/lab/LJ/wampee/WampeeDataSets/train/images", help="Path to training images")
parser.add_argument("--train_label", default="/home/lab/LJ/wampee/WampeeDataSets/train/labels",
help="Path to training labels")
parser.add_argument("--val_img", default="/home/lab/LJ/wampee/WampeeDataSets/valid/images", help="Path to validation images")
parser.add_argument("--val_label", default="/home/lab/LJ/wampee/WampeeDataSets/valid/labels", help="Path to validation labels")
parser.add_argument("--output", default="/home/lab/LJ/wampee/Wampee_dataSets__Voc_Sec", help="Path to output VOC dataset")
args = parser.parse_args()
main(args.train_img, args.train_label, args.val_img, args.val_label, args.output)