Spaces:
Running
Running
| import gradio as gr | |
| from PIL import Image, ImageEnhance, ImageDraw | |
| import cv2 | |
| import numpy as np | |
| # Map keywords in text prompt to colors | |
| COLOR_MAP = { | |
| "orange": (255, 150, 0, 180), | |
| "purple": (150, 0, 255, 180), | |
| "blue": (0, 150, 255, 180), | |
| "red": (255, 0, 0, 180), | |
| "green": (0, 255, 0, 180), | |
| "yellow": (255, 255, 0, 180) | |
| } | |
| def parse_colors(text): | |
| colors = [] | |
| text = text.lower() | |
| for key, value in COLOR_MAP.items(): | |
| if key in text: | |
| colors.append(value) | |
| if not colors: | |
| colors = [(255, 150, 0, 180)] # default orange | |
| return colors | |
| def detect_building_mask(pil_image): | |
| img = np.array(pil_image) | |
| gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) | |
| # Detect edges | |
| edges = cv2.Canny(gray, 50, 150) | |
| # Dilate edges to cover full building area | |
| mask = cv2.dilate(edges, np.ones((15,15),np.uint8), iterations=3) | |
| return mask # mask = 255 where building edges/windows exist | |
| def draw_lights_on_mask(pil_image, mask, colors): | |
| draw = ImageDraw.Draw(pil_image) | |
| width, height = pil_image.size | |
| mask_img = Image.fromarray(mask) | |
| mask_pixels = mask_img.load() | |
| # Step size smaller → lights cover full building | |
| step_x = max(width // 40, 5) | |
| step_y = max(height // 40, 5) | |
| for x in range(0, width, step_x): | |
| for y in range(0, height, step_y): | |
| if mask_pixels[x, y] > 0: | |
| color = colors[(x//step_x + y//step_y) % len(colors)] | |
| draw.rectangle([x, y, x+step_x, y+step_y], fill=color) | |
| return pil_image | |
| def facade_lighting(image, prompt): | |
| if not isinstance(image, Image.Image): | |
| image = Image.fromarray(image) | |
| # Darken building first | |
| dark_image = ImageEnhance.Brightness(image).enhance(0.3) | |
| # Parse colors from text | |
| colors = parse_colors(prompt) | |
| # Detect building structure | |
| mask = detect_building_mask(dark_image) | |
| # Draw facade lights on dark building | |
| output_image = draw_lights_on_mask(dark_image, mask, colors) | |
| return output_image | |
| def process(image, prompt): | |
| return facade_lighting(image, prompt) | |
| demo = gr.Interface( | |
| process, | |
| ["image", "text"], | |
| "image", | |
| examples=[["building.jpg", "orange and purple lights"]] | |
| ) | |
| demo.launch() | |