Instructions to use luke-harriman/chart_object_detection with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use luke-harriman/chart_object_detection with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("object-detection", model="luke-harriman/chart_object_detection")# pip install -U transformers accelerate # Load model directly from transformers import AutoImageProcessor, AutoModelForObjectDetection processor = AutoImageProcessor.from_pretrained("luke-harriman/chart_object_detection") model = AutoModelForObjectDetection.from_pretrained("luke-harriman/chart_object_detection", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Upload data_bb_generator.py with huggingface_hub
Browse files- 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)
|