luke-harriman commited on
Commit
8e07982
·
verified ·
1 Parent(s): 4039241

Upload data_bb_generator.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. data_bb_generator.py +127 -0
data_bb_generator.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import random
4
+ from PIL import Image
5
+ from concurrent.futures import ProcessPoolExecutor
6
+ from random import randint, uniform
7
+ from concurrent.futures import Future
8
+
9
+
10
+ def superimpose_image(background_img, overlay_img, position=(0, 0), resize_factor=1.0):
11
+ # Calculate the new size, maintaining the aspect ratio
12
+ original_width, original_height = overlay_img.size
13
+ new_width = int(original_width * resize_factor)
14
+ new_height = int(original_height * resize_factor)
15
+
16
+ # Resize the overlay image
17
+ overlay_img_resized = overlay_img.resize((new_width, new_height), Image.Resampling.LANCZOS)
18
+
19
+ # Paste the resized overlay image onto the background image
20
+ background_img.paste(overlay_img_resized, position, overlay_img_resized)
21
+
22
+ return background_img
23
+
24
+ def process_combination(args, image_id):
25
+ random_image_path, chart_image_path, output_dir = args
26
+ random_image = Image.open(random_image_path)
27
+
28
+ if chart_image_path is not None:
29
+ chart_image = Image.open(chart_image_path).convert("RGBA")
30
+ resize_factor = uniform(0.5, 1.5) # Random resize factor
31
+ original_width, original_height = chart_image.size
32
+ new_width = int(original_width * resize_factor)
33
+ new_height = int(original_height * resize_factor)
34
+ new_width = min(new_width, random_image.width)
35
+ new_height = min(new_height, random_image.height)
36
+ x_pos = randint(0, max(random_image.width - new_width, 0))
37
+ y_pos = randint(0, max(random_image.height - new_height, 0))
38
+
39
+ modified_image = superimpose_image(random_image, chart_image, (x_pos, y_pos), resize_factor)
40
+ bbox_width, bbox_height = float(new_width), float(new_height)
41
+ area = bbox_width * bbox_height
42
+ category = 1
43
+ else:
44
+ # When not superimposing a chart, make the bounding box represent the entire image
45
+ modified_image = random_image
46
+ x_pos, y_pos = 0, 0
47
+ bbox_width, bbox_height = float(random_image.width), float(random_image.height)
48
+ area = bbox_width * bbox_height
49
+ category = 0 # Set category to 0 to indicate background
50
+
51
+ output_image_name = f'modified_{os.path.basename(random_image_path)}'
52
+ output_image_name += f"_{os.path.basename(chart_image_path)}" if chart_image_path else ""
53
+ output_image_path = os.path.join(output_dir, output_image_name)
54
+ modified_image.save(output_image_path)
55
+
56
+ return {
57
+ 'image_id': image_id,
58
+ 'image_path': output_image_path,
59
+ 'width': modified_image.width,
60
+ 'height': modified_image.height,
61
+ 'bbox': [[float(x_pos), float(y_pos), bbox_width, bbox_height]],
62
+ 'category': category,
63
+ 'area': area
64
+ }
65
+
66
+ def generate_combinations_concurrently(random_images_dir, chart_images_dir, base_output_dir, dataset_type, sample_size, max_workers=4):
67
+ random_images = [os.path.join(random_images_dir, f) for f in os.listdir(random_images_dir) if os.path.isfile(os.path.join(random_images_dir, f))]
68
+ chart_images = [os.path.join(chart_images_dir, f) for f in os.listdir(chart_images_dir) if os.path.isfile(os.path.join(chart_images_dir, f))]
69
+
70
+ output_dir = os.path.join(base_output_dir, dataset_type)
71
+ json_filename = os.path.join(output_dir, f"image_data_coco_format.json")
72
+ os.makedirs(output_dir, exist_ok=True)
73
+
74
+ # Ensure unique combinations by adjusting how combinations are selected
75
+ combinations = random.sample([(ri, ci, output_dir) for ri in random_images for ci in chart_images], sample_size)
76
+
77
+ # Initialize the structure for COCO format
78
+ coco_format = {
79
+ "images": [],
80
+ "annotations": [],
81
+ "categories": [
82
+ {
83
+ "id": 1,
84
+ "name": "category_name",
85
+ "supercategory": "supercategory_name",
86
+ }
87
+ ]
88
+ }
89
+
90
+ annotation_id = 1
91
+ with ProcessPoolExecutor(max_workers=max_workers) as executor:
92
+ futures = [executor.submit(process_combination, combination, idx + 1) for idx, combination in enumerate(combinations)]
93
+
94
+ for future in futures:
95
+ item = future.result()
96
+ # Add the image information
97
+ coco_format["images"].append({
98
+ "id": item["image_id"],
99
+ "file_name": item["image_path"],
100
+ "width": item["width"],
101
+ "height": item["height"]
102
+ })
103
+
104
+ # Add annotation information
105
+ for bbox in item.get("bbox", []):
106
+ coco_format["annotations"].append({
107
+ "id": annotation_id,
108
+ "image_id": item["image_id"],
109
+ "category_id": item["category"],
110
+ "bbox": bbox,
111
+ "area": item["area"],
112
+ "segmentation": [],
113
+ "iscrowd": 0
114
+ })
115
+ annotation_id += 1
116
+
117
+ with open(json_filename, 'w') as f:
118
+ json.dump(coco_format, f, indent=4)
119
+
120
+ if __name__ == '__main__':
121
+ base_output_dir = 'output_images_coco_format'
122
+ random_images_dir = '/Users/lukeh/Desktop/python_projects/youtube_scraper/model/random_images'
123
+ chart_images_dir = '/Users/lukeh/Desktop/python_projects/youtube_scraper/model/chart_images'
124
+
125
+ # Generate training, validation, and testing datasets
126
+ for dataset_type, sample_size in [('train', 500), ('val', 100), ('test', 50)]:
127
+ generate_combinations_concurrently(random_images_dir, chart_images_dir, base_output_dir, dataset_type, sample_size)