Socrate / synthetic.py
ihatebaselines's picture
Upload synthetic.py with huggingface_hub
e610a72 verified
Raw
History Blame Contribute Delete
4.36 kB
import os
import random
import csv
import urllib.request
from PIL import Image, ImageDraw, ImageFont
def _download_or_read_text(source):
if source.startswith("http://") or source.startswith("https://"):
req = urllib.request.Request(source, headers={'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req, timeout=10) as resp:
text = resp.read().decode('utf-8', errors='ignore')
else:
with open(source, 'r', encoding='utf-8', errors='ignore') as f:
text = f.read()
return text
def _get_words_from_text(text):
words = text.split()
words = [w.strip('.,!?"\'()[]{}') for w in words]
words = [w for w in words if w]
return words
def _render_text(text, bg_color=255, font_size=32):
try:
# Use a default Windows font if available
font = ImageFont.truetype("arial.ttf", font_size)
except IOError:
font = ImageFont.load_default()
# Measure text
tmp = Image.new("L", (16, 16), 255)
draw = ImageDraw.Draw(tmp)
bbox = draw.textbbox((0, 0), text, font=font)
tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
pad_x = random.randint(10, 20)
pad_y = random.randint(5, 15)
cw = max(32, tw + pad_x * 2)
ch = max(32, th + pad_y * 2)
image = Image.new("RGB", (cw, ch), (bg_color, bg_color, bg_color))
draw = ImageDraw.Draw(image)
x = pad_x
y = pad_y
draw.text((x, y), text, fill=(0, 0, 0), font=font)
# Slight rotation (beta silly distortion)
angle = random.uniform(-2, 2)
image = image.rotate(angle, resample=Image.Resampling.BICUBIC, expand=True, fillcolor=(bg_color,bg_color,bg_color))
return image
def generate_silly_training_set(source, count, output_dir="silly_train"):
"""
Generates images containing individual words extracted from 'source'.
'Beta' utility for quick training on custom datasets.
Returns the path to the generated labels.csv file.
"""
os.makedirs(output_dir, exist_ok=True)
text = _download_or_read_text(source)
words = _get_words_from_text(text)
if not words:
raise ValueError("Source has no valid words.")
labels_file = os.path.join(output_dir, "labels.csv")
with open(labels_file, "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
writer.writerow(["image_path", "label"])
for i in range(count):
word = random.choice(words)
img = _render_text(word)
img_name = f"train_{i:06d}.jpg"
img_path = os.path.join(output_dir, img_name)
img.save(img_path)
writer.writerow([img_path, word])
if i % 100 == 0:
print(f"Generated {i}/{count} training samples...", end="\r")
print(f"\nSaved {count} training samples to {labels_file}")
return labels_file
def generate_silly_testing_set(source, count, output_dir="silly_test"):
"""
Generates images containing sentences of 2-6 words extracted from 'source'.
'Beta' utility for testing inference on continuous text.
Returns the path to the generated labels.csv file.
"""
os.makedirs(output_dir, exist_ok=True)
text = _download_or_read_text(source)
words = _get_words_from_text(text)
if not words:
raise ValueError("Source has no valid words.")
labels_file = os.path.join(output_dir, "labels.csv")
with open(labels_file, "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
writer.writerow(["image_path", "label"])
for i in range(count):
sentence_len = random.randint(2, 6)
sentence_words = [random.choice(words) for _ in range(sentence_len)]
sentence = " ".join(sentence_words)
img = _render_text(sentence)
img_name = f"test_{i:06d}.jpg"
img_path = os.path.join(output_dir, img_name)
img.save(img_path)
writer.writerow([img_path, sentence])
if i % 100 == 0:
print(f"Generated {i}/{count} testing samples...", end="\r")
print(f"\nSaved {count} testing samples to {labels_file}")
return labels_file