9OCR / legacy /b3.py
ansarzeinulla's picture
Initial commit
20d7fde
Raw History Blame
3.31 kB
import os
import random
import glob
import numpy as np
from PIL import Image, ImageFilter
import cv2
INGREDIENTS_PATH = "ingredients"
OUTPUT_PATH = "train_data2"
BOX_HEIGHT = 40
BOX_WIDTH = 80
SAMPLES_PER_CLASS = 300
move_classes = [f"{s}{e}" for s in range(1, 10) for e in range(1, 10)] + \
[f"{s}{e}x" for s in range(1, 10) for e in range(1, 10)]
classes = move_classes + ['empty']
os.makedirs(OUTPUT_PATH, exist_ok=True)
def crop_and_center_ink(cv2_gray_img, target_w=80, target_h=40, margin=4):
ink_mask = cv2.bitwise_not(cv2_gray_img)
coords = cv2.findNonZero(ink_mask)
if coords is not None:
x, y, w, h = cv2.boundingRect(coords)
crop = cv2_gray_img[y:y+h, x:x+w]
scale = min((target_w - 2*margin) / w, (target_h - 2*margin) / h)
new_w, new_h = max(1, int(w * scale)), max(1, int(h * scale))
resized_crop = cv2.resize(crop, (new_w, new_h), interpolation=cv2.INTER_AREA)
canvas = np.full((target_h, target_w), 255, dtype=np.uint8)
start_x, start_y = (target_w - new_w) // 2, (target_h - new_h) // 2
canvas[start_y:start_y+new_h, start_x:start_x+new_w] = resized_crop
return canvas
return np.full((target_h, target_w), 255, dtype=np.uint8)
def create_move_image(class_name):
if class_name == 'empty':
return Image.new('L', (BOX_WIDTH, BOX_HEIGHT), color=255)
# Start with a clean canvas
img = Image.new('L', (200, 200), color=255)
current_x = 40
for char in class_name:
files = glob.glob(os.path.join(INGREDIENTS_PATH, char, "*.png"))
char_img = Image.open(random.choice(files))
size = random.randint(22, 28) if char == 'x' else random.randint(32, 42)
char_img = char_img.resize((size, size), Image.Resampling.LANCZOS)
char_img = char_img.rotate(random.randint(-12, 12), expand=True, fillcolor=0)
bbox = char_img.getbbox()
if bbox: char_img = char_img.crop(bbox)
ink_layer = Image.new('L', char_img.size, color=0)
paste_y = 100 - (char_img.height // 2) + random.randint(-5, 5)
img.paste(ink_layer, (current_x, paste_y), mask=char_img)
current_x += char_img.width + random.randint(-1, 4)
# --- THE CRITICAL FIX: Center FIRST, then Dilate ---
temp_arr = np.array(img)
centered = crop_and_center_ink(temp_arr, BOX_WIDTH, BOX_HEIGHT)
# Randomly vary thickness (Some thin, some thick)
ink_is_white = cv2.bitwise_not(centered)
thickness = random.choice([1, 2, 2]) # Weight it towards thicker lines
kernel = np.ones((thickness, thickness), np.uint8)
thick_ink = cv2.dilate(ink_is_white, kernel, iterations=1)
# Add a tiny bit of blur/noise to simulate real camera focus
final_img = cv2.bitwise_not(thick_ink)
pil_final = Image.fromarray(final_img)
if random.random() > 0.5:
pil_final = pil_final.filter(ImageFilter.GaussianBlur(radius=0.3))
return pil_final
# ... Execution loop remains same as previous ...
print("Generating centered data with variable thickness...")
for cls in classes:
class_dir = os.path.join(OUTPUT_PATH, cls)
os.makedirs(class_dir, exist_ok=True)
for i in range(SAMPLES_PER_CLASS):
create_move_image(cls).save(os.path.join(class_dir, f"{cls}_{i}.png"))