Spaces:
Running
Running
| """ | |
| Standard Grid Processor (Final / Perfect). | |
| Uses Spectral Separation + Correct Polarity (Black Ink). | |
| """ | |
| import cv2 | |
| import numpy as np | |
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parent / 'src')) | |
| from vectorizer import CharacterVectorizer | |
| from font_generator import generate_font | |
| def get_page_transform(img): | |
| # Simplified alignment - Find page if possible, else full image | |
| h, w = img.shape[:2] | |
| return np.array([[0,0], [2480,0], [2480,3508], [0,3508]], dtype="float32") # Fallback to full A4 | |
| def process_grid_final(image_path, output_font="outputs/PerfectAIFont.ttf", font_family_name="PerfectAIFont"): | |
| print(f"Processing: {image_path}") | |
| img = cv2.imread(image_path) | |
| if img is None: | |
| raise ValueError("Cannot open image") | |
| # Resize to A4 | |
| img = cv2.resize(img, (2480, 3508)) | |
| # 1. AI Extraction (Blue Ink -> White Mask) | |
| hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) | |
| s = hsv[:, :, 1] | |
| _, mask = cv2.threshold(s, 50, 255, cv2.THRESH_BINARY) | |
| # 2. Polarity Fix (White Mask -> Black Ink on White BG) | |
| # This matches "Option B" which was confirmed correct | |
| final_mask = cv2.bitwise_not(mask) | |
| # Clean noise | |
| kernel = np.ones((3,3), np.uint8) | |
| final_mask = cv2.morphologyEx(final_mask, cv2.MORPH_OPEN, kernel) # Remove small noise | |
| # 3. Grid Extraction | |
| margin_x, margin_y = 100, 300 | |
| cols = 8 | |
| cell_w = (2480 - 2 * margin_x) // cols | |
| cell_h = int(cell_w * 1.2) | |
| chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?.,:;" | |
| current_x, current_y = margin_x, margin_y | |
| vectorizer = CharacterVectorizer() | |
| char_paths = {} | |
| print("Vectorizing...") | |
| for i, char in enumerate(chars): | |
| x1, y1 = int(current_x), int(current_y) | |
| x2, y2 = int(x1 + cell_w), int(y1 + cell_h) | |
| pad = 20 | |
| roi = final_mask[y1+pad:y2-pad, x1+pad:x2-pad] | |
| # Check original mask for content (White ink) | |
| roi_check = mask[y1+pad:y2-pad, x1+pad:x2-pad] | |
| if cv2.countNonZero(roi_check) > 50: | |
| path, _ = vectorizer.vectorize(roi) | |
| if path: | |
| char_paths[char] = path | |
| print(f" {char}: Found") | |
| current_x += cell_w | |
| if (i + 1) % cols == 0: | |
| current_x = margin_x | |
| current_y += cell_h | |
| generate_font(char_paths, output_font, font_family_name) | |
| print(f"Success! Saved to {output_font}") | |
| if __name__ == "__main__": | |
| import argparse | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("image", help="Input image") | |
| parser.add_argument("-o", "--output", default="outputs/PerfectAIFont.ttf") | |
| args = parser.parse_args() | |
| process_grid_final(args.image, args.output) | |