Spaces:
Sleeping
Sleeping
| import os | |
| import glob | |
| import time | |
| import json | |
| import random | |
| import numpy as np | |
| import gradio as gr | |
| from matplotlib import pyplot as plt | |
| from PIL import Image, ImageDraw, ImageFilter | |
| def get_template(path): | |
| # RGB to HSV | |
| img = Image.open(path).convert('HSV') | |
| copy = img.convert('L').copy() | |
| # where is white | |
| copy = np.where(np.array(copy) == 255, 255, 0).astype(np.uint8) | |
| # convert numpy array to image | |
| copy = Image.fromarray(copy, "L") | |
| # pick the H channel | |
| img = img.split()[0] | |
| # divide by 16 | |
| img = np.array(img) + 8 | |
| img = Image.fromarray(img // 16) | |
| return img, copy | |
| # resize via height, keep the aspect ratio | |
| def resize_height(img, height, nearest=False): | |
| width, old_height = img.size | |
| new_width = int(width * height / old_height) | |
| return img.resize((new_width, height), Image.NEAREST if nearest else Image.BICUBIC), new_width | |
| # load config json file | |
| def load_config(path): | |
| with open(path, "r") as f: | |
| config = json.load(f) | |
| return config | |
| def parse_config(config): | |
| def random_choice(char): | |
| if char == "#": | |
| return random.choice(config["plateNums"] + config["plateChars"]) | |
| elif char == "A": | |
| return random.choice(config["plateChars"]) | |
| elif char == "0": | |
| return random.choice(config["plateNums"]) | |
| elif char == "@": | |
| return random.choice(config["plateCities"]) | |
| return char | |
| plate_patch = [(random_choice(char) for char in plate) for plate in config["plateFormat"]] | |
| return config["name"], plate_patch | |
| def get_background(name): | |
| bgs = os.path.join("config", name, "background") | |
| bg_path = random.choice(glob.glob(f"{bgs}/*.*")) | |
| bg = Image.open(bg_path).convert("RGB") | |
| return bg | |
| # get mask and paste the file from folder to generate the mask | |
| def get_mask(cfg): | |
| name, plates = parse_config(cfg) | |
| root_dir = os.path.join("config", name) | |
| # if none key, return default value | |
| plateTextColor = cfg.get("plateTextColor", "#000000").lstrip("#") | |
| img, dot = get_template(os.path.join(root_dir, "template.png")) | |
| mask = Image.new("L", img.size, 0) | |
| ord_ = Image.new("L", img.size, 0) | |
| count = 0 | |
| plateText = "" | |
| for idx, plate in enumerate(plates): | |
| for char in plate: | |
| count += 1 | |
| plateText += char | |
| m_char_path = random.choice(glob.glob(f"{root_dir}/{idx}/{char}_*.png")) | |
| mask_rect = np.where(np.array(img) == count) | |
| h_min, w_min = np.min(mask_rect, axis=1) | |
| h_max, w_max = np.max(mask_rect, axis=1) | |
| m_char = Image.open(m_char_path).convert("RGBA").split()[-1] | |
| m_char, new_width = resize_height(m_char, h_max - h_min) | |
| x = (w_min + w_max - new_width) // 2 | |
| mask.paste(m_char, (x, h_min), m_char) | |
| m_char = np.array(np.array(m_char) > 128, dtype=np.uint8) * 255 | |
| m_char = Image.fromarray(m_char) | |
| ord_.paste(count*16, (x, h_min), m_char) | |
| # add the dot img on the mask | |
| mask = Image.composite(dot, mask, dot) | |
| mask, _ = resize_height(mask, 512) | |
| mask_wo_border = mask.copy() | |
| mask_wo_border = mask_wo_border.filter(ImageFilter.MaxFilter(3)) | |
| mask = mask.filter(ImageFilter.MaxFilter(5)).filter(ImageFilter.GaussianBlur(1.5)) | |
| ord_, _ = resize_height(ord_, 512, nearest=True) | |
| plate_bg = get_background(name) | |
| mask_wo_border = mask_wo_border.resize(plate_bg.size) | |
| # make the mask as alpha channel | |
| bg = Image.new("RGBA", plate_bg.size, (0, 0, 0, 0)) | |
| bg.paste(plate_bg, (0, 0)) | |
| # hex to rgb | |
| plateTextColor = tuple(int(plateTextColor[i:i + 2], 16) for i in (0, 2, 4)) | |
| bg.paste(plateTextColor, (0, 0), mask_wo_border) | |
| return plateText, bg, mask, ord_ | |
| # get all folders in the config folder | |
| config_path = os.path.join(os.path.dirname(__file__), "config") | |
| plates = [f for f in os.listdir(config_path) if os.path.isdir(os.path.join(config_path, f))] | |
| def generate(name): | |
| cfg = load_config(os.path.join(config_path, name, "config.json")) | |
| return get_mask(cfg) # text, bg, mask, ord_ | |
| demo = gr.Interface( | |
| generate, | |
| [ | |
| gr.Dropdown(plates, value="cn_truck", label="Plate Style"), | |
| ], | |
| [ | |
| gr.Text(label="Plate Text"), | |
| gr.Image(label="Background", show_label=False, format="png"), | |
| gr.Image(label="Mask", show_label=False, format="png"), | |
| gr.Image(label="Ord", show_label=False, format="png"), | |
| ], | |
| allow_flagging=False, | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch(debug=True) | |