Spaces:
Running
Running
Upload 6 files
Browse files- app_gradio.py +72 -4
- requirements_gradio.txt +2 -1
app_gradio.py
CHANGED
@@ -218,6 +218,60 @@ def create_full_mask(image):
|
|
218 |
|
219 |
return Image.fromarray(mask).convert("RGB")
|
220 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
def post_process_blend(original, generated):
|
222 |
"""Post-process to reduce seam artifacts between original and generated areas"""
|
223 |
from PIL import ImageFilter
|
@@ -253,7 +307,7 @@ def post_process_blend(original, generated):
|
|
253 |
return Image.fromarray(final_array)
|
254 |
|
255 |
@spaces.GPU
|
256 |
-
def design_space(input_image, room_type, design_style, num_steps, guidance_scale, strength):
|
257 |
"""Generate space design using ZeroGPU"""
|
258 |
|
259 |
global pipe, seg_processor, seg_model, mlsd_processor
|
@@ -297,8 +351,13 @@ def design_space(input_image, room_type, design_style, num_steps, guidance_scale
|
|
297 |
else:
|
298 |
mlsd_image = resized_image.copy()
|
299 |
|
300 |
-
# Create
|
301 |
-
|
|
|
|
|
|
|
|
|
|
|
302 |
|
303 |
# Generate image with original project settings
|
304 |
result = pipe(
|
@@ -357,6 +416,15 @@ def create_interface():
|
|
357 |
label="Select Design Style"
|
358 |
)
|
359 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
360 |
|
361 |
with gr.Accordion("⚙️ Advanced Settings", open=False):
|
362 |
num_steps = gr.Slider(
|
@@ -389,7 +457,7 @@ def create_interface():
|
|
389 |
# Event handler
|
390 |
generate_btn.click(
|
391 |
fn=design_space,
|
392 |
-
inputs=[input_image, room_type, design_style, num_steps, guidance_scale, strength],
|
393 |
outputs=[output_image, result_message]
|
394 |
)
|
395 |
|
|
|
218 |
|
219 |
return Image.fromarray(mask).convert("RGB")
|
220 |
|
221 |
+
def create_smart_mask(image):
|
222 |
+
"""Create smart mask that preserves walls/windows but allows furniture placement in empty areas"""
|
223 |
+
import cv2
|
224 |
+
|
225 |
+
# Convert PIL to numpy
|
226 |
+
img_array = np.array(image)
|
227 |
+
|
228 |
+
# Convert to HSV for better color analysis
|
229 |
+
hsv = cv2.cvtColor(img_array, cv2.COLOR_RGB2HSV)
|
230 |
+
|
231 |
+
# Create mask for empty floor areas (typically lighter, less saturated)
|
232 |
+
# This targets floors, empty spaces where furniture can be placed
|
233 |
+
|
234 |
+
# Method 1: Detect floor areas (usually uniform, lighter colors)
|
235 |
+
gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
|
236 |
+
|
237 |
+
# Create base mask
|
238 |
+
mask = np.zeros(gray.shape, dtype=np.uint8)
|
239 |
+
|
240 |
+
# Find relatively uniform areas (potential floor/empty spaces)
|
241 |
+
# Use adaptive threshold to find uniform regions
|
242 |
+
blur = cv2.GaussianBlur(gray, (15, 15), 0)
|
243 |
+
|
244 |
+
# Create mask for areas that are not walls/windows (middle brightness range)
|
245 |
+
# Avoid very dark (shadows) and very bright (windows) areas
|
246 |
+
floor_mask = cv2.inRange(gray, 50, 200)
|
247 |
+
|
248 |
+
# Remove small noise
|
249 |
+
kernel = np.ones((5,5), np.uint8)
|
250 |
+
floor_mask = cv2.morphologyEx(floor_mask, cv2.MORPH_OPEN, kernel)
|
251 |
+
floor_mask = cv2.morphologyEx(floor_mask, cv2.MORPH_CLOSE, kernel)
|
252 |
+
|
253 |
+
# Create gradient mask - stronger in center, weaker at edges to preserve walls
|
254 |
+
h, w = floor_mask.shape
|
255 |
+
center_x, center_y = w//2, h//2
|
256 |
+
|
257 |
+
# Create distance-based gradient
|
258 |
+
Y, X = np.ogrid[:h, :w]
|
259 |
+
dist_from_center = np.sqrt((X - center_x)**2 + (Y - center_y)**2)
|
260 |
+
max_dist = np.sqrt(center_x**2 + center_y**2)
|
261 |
+
|
262 |
+
# Central areas get higher weight (more likely to be inpainted)
|
263 |
+
gradient = 1 - (dist_from_center / max_dist) * 0.7 # Keep some mask even at edges
|
264 |
+
gradient = np.clip(gradient, 0.2, 1.0) # Minimum 20% mask everywhere
|
265 |
+
|
266 |
+
# Combine floor detection with gradient
|
267 |
+
final_mask = (floor_mask.astype(np.float32) / 255.0) * gradient * 255
|
268 |
+
final_mask = final_mask.astype(np.uint8)
|
269 |
+
|
270 |
+
# Apply some blur for smoother transitions
|
271 |
+
final_mask = cv2.GaussianBlur(final_mask, (11, 11), 0)
|
272 |
+
|
273 |
+
return Image.fromarray(final_mask).convert("RGB")
|
274 |
+
|
275 |
def post_process_blend(original, generated):
|
276 |
"""Post-process to reduce seam artifacts between original and generated areas"""
|
277 |
from PIL import ImageFilter
|
|
|
307 |
return Image.fromarray(final_array)
|
308 |
|
309 |
@spaces.GPU
|
310 |
+
def design_space(input_image, room_type, design_style, inpainting_mode, num_steps, guidance_scale, strength):
|
311 |
"""Generate space design using ZeroGPU"""
|
312 |
|
313 |
global pipe, seg_processor, seg_model, mlsd_processor
|
|
|
351 |
else:
|
352 |
mlsd_image = resized_image.copy()
|
353 |
|
354 |
+
# Create mask based on selected mode
|
355 |
+
if inpainting_mode == "smart":
|
356 |
+
mask_image = create_smart_mask(resized_image)
|
357 |
+
# Adjust prompt for furniture placement
|
358 |
+
prompt = f"photorealistic interior design, add {detailed_prompt.split(',')[0]} furniture and decor, preserve existing walls and windows, natural lighting, ultra-realistic, high resolution, sharp focus, interior design magazine quality, realistic textures, realistic materials"
|
359 |
+
else:
|
360 |
+
mask_image = create_full_mask(resized_image)
|
361 |
|
362 |
# Generate image with original project settings
|
363 |
result = pipe(
|
|
|
416 |
label="Select Design Style"
|
417 |
)
|
418 |
|
419 |
+
inpainting_mode = gr.Radio(
|
420 |
+
choices=[
|
421 |
+
("Complete Room Redesign", "full"),
|
422 |
+
("Add Furniture Only (Preserve Walls)", "smart")
|
423 |
+
],
|
424 |
+
value="smart",
|
425 |
+
label="🎨 Design Mode",
|
426 |
+
info="Choose how to modify your image"
|
427 |
+
)
|
428 |
|
429 |
with gr.Accordion("⚙️ Advanced Settings", open=False):
|
430 |
num_steps = gr.Slider(
|
|
|
457 |
# Event handler
|
458 |
generate_btn.click(
|
459 |
fn=design_space,
|
460 |
+
inputs=[input_image, room_type, design_style, inpainting_mode, num_steps, guidance_scale, strength],
|
461 |
outputs=[output_image, result_message]
|
462 |
)
|
463 |
|
requirements_gradio.txt
CHANGED
@@ -9,4 +9,5 @@ gradio
|
|
9 |
spaces
|
10 |
pillow
|
11 |
numpy
|
12 |
-
scipy
|
|
|
|
9 |
spaces
|
10 |
pillow
|
11 |
numpy
|
12 |
+
scipy
|
13 |
+
opencv-python
|