SpacelyJohn commited on
Commit
7d0d69e
·
verified ·
1 Parent(s): 579b7d0

Upload 6 files

Browse files
Files changed (2) hide show
  1. app_gradio.py +72 -4
  2. 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 full mask to eliminate boundaries
301
- mask_image = create_full_mask(resized_image)
 
 
 
 
 
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