import json
import csv
import random
import argparse
from pathlib import Path
import numpy as np
from datetime import datetime
class DatasetGenerator:
def __init__(self, num_images=100, annotations_per_image=5, image_width=640, image_height=480):
self.num_images = num_images
self.annotations_per_image = annotations_per_image
self.image_width = image_width
self.image_height = image_height
self.categories = [
{"id": 1, "name": "person", "supercategory": "living"},
{"id": 2, "name": "car", "supercategory": "vehicle"},
{"id": 3, "name": "dog", "supercategory": "animal"},
{"id": 4, "name": "bicycle", "supercategory": "vehicle"},
{"id": 5, "name": "chair", "supercategory": "furniture"}
]
random.seed(42)
np.random.seed(42)
def generate_bbox(self):
width = random.uniform(0.1 * self.image_width, 0.3 * self.image_width)
height = random.uniform(0.1 * self.image_height, 0.3 * self.image_height)
x = random.uniform(0, self.image_width - width)
y = random.uniform(0, self.image_height - height)
return [x, y, width, height]
def coco_to_tfod_bbox(self, bbox):
xmin = bbox[0]
ymin = bbox[1]
xmax = bbox[0] + bbox[2]
ymax = bbox[1] + bbox[3]
ymin_norm = ymin / self.image_height
xmin_norm = xmin / self.image_width
ymax_norm = ymax / self.image_height
xmax_norm = xmax / self.image_width
return [ymin_norm, xmin_norm, ymax_norm, xmax_norm]
def generate_coco_dataset(self):
images = []
annotations = []
ann_id = 1
for img_id in range(1, self.num_images + 1):
image_name = f"image_{img_id:06d}.jpg"
images.append({
"id": img_id,
"width": self.image_width,
"height": self.image_height,
"file_name": image_name,
"license": 1,
"date_captured": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
})
for _ in range(self.annotations_per_image):
bbox = self.generate_bbox()
category_id = random.choice(self.categories)["id"]
area = bbox[2] * bbox[3]
annotations.append({
"id": ann_id,
"image_id": img_id,
"category_id": category_id,
"bbox": bbox,
"area": area,
"iscrowd": 0,
"segmentation": [] })
ann_id += 1
coco_dict = {
"info": {
"year": 2024,
"version": "1.0",
"description": "Synthetic dataset for testing",
"contributor": "Dataset Generator",
"date_created": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
},
"licenses": [{"id": 1, "name": "dummy_license", "url": ""}],
"images": images,
"annotations": annotations,
"categories": self.categories
}
return coco_dict
def generate_tfod_csv(self, coco_dict):
tfod_rows = []
cat_id_to_name = {cat["id"]: cat["name"] for cat in self.categories}
img_id_to_name = {img["id"]: img["file_name"] for img in coco_dict["images"]}
annotations_by_image = {}
for ann in coco_dict["annotations"]:
img_id = ann["image_id"]
if img_id not in annotations_by_image:
annotations_by_image[img_id] = []
annotations_by_image[img_id].append(ann)
for img_id, annotations in annotations_by_image.items():
filename = img_id_to_name[img_id]
for ann in annotations:
tfod_bbox = self.coco_to_tfod_bbox(ann["bbox"])
class_name = cat_id_to_name[ann["category_id"]]
tfod_rows.append({
"filename": filename,
"width": self.image_width,
"height": self.image_height,
"class": class_name,
"xmin": tfod_bbox[1],
"ymin": tfod_bbox[0],
"xmax": tfod_bbox[3],
"ymax": tfod_bbox[2]
})
return tfod_rows
def main():
parser = argparse.ArgumentParser(description='Generate synthetic COCO and TFOD datasets')
parser.add_argument('--num_images', type=int, default=100,
help='Number of images in the dataset')
parser.add_argument('--annotations_per_image', type=int, default=5,
help='Number of annotations per image')
parser.add_argument('--output_dir', type=str, default='generated_dataset',
help='Output directory for the generated files')
args = parser.parse_args()
output_dir = Path(args.output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
generator = DatasetGenerator(
num_images=args.num_images,
annotations_per_image=args.annotations_per_image
)
coco_dict = generator.generate_coco_dataset()
coco_output = output_dir / 'coco_annotations.json'
with open(coco_output, 'w') as f:
json.dump(coco_dict, f, indent=2)
tfod_rows = generator.generate_tfod_csv(coco_dict)
tfod_output = output_dir / 'tfod_annotations.csv'
with open(tfod_output, 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=['filename', 'width', 'height', 'class',
'xmin', 'ymin', 'xmax', 'ymax'])
writer.writeheader()
writer.writerows(tfod_rows)
print(f"Generated datasets in {output_dir}:")
print(f"- COCO format: {coco_output}")
print(f"- TFOD format: {tfod_output}")
print(f"\nDataset statistics:")
print(f"- Number of images: {args.num_images}")
print(f"- Annotations per image: {args.annotations_per_image}")
print(f"- Total annotations: {args.num_images * args.annotations_per_image}")
if __name__ == "__main__":
main()