primerz commited on
Commit
288b3a2
·
verified ·
1 Parent(s): 737485e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +110 -65
app.py CHANGED
@@ -38,7 +38,7 @@ from compel import Compel, ReturnedEmbeddingsType
38
 
39
  from gradio_imageslider import ImageSlider
40
 
41
- # Load LoRA configurations
42
  with open("sdxl_loras.json", "r") as file:
43
  data = json.load(file)
44
  sdxl_loras_raw = [
@@ -123,8 +123,9 @@ et = time.time()
123
  print('Loading VAE took: ', et - st, 'seconds')
124
 
125
  st = time.time()
 
126
  pipe = StableDiffusionXLInstantIDImg2ImgPipeline.from_pretrained(
127
- "SG161222/RealVisXL_V5.0",
128
  vae=vae,
129
  controlnet=[identitynet, zoedepthnet],
130
  torch_dtype=torch.float16
@@ -132,7 +133,8 @@ pipe = StableDiffusionXLInstantIDImg2ImgPipeline.from_pretrained(
132
 
133
  pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config, use_karras_sigmas=True)
134
  pipe.load_ip_adapter_instantid(face_adapter)
135
- pipe.set_ip_adapter_scale(0.9)
 
136
  et = time.time()
137
  print('Loading pipeline took: ', et - st, 'seconds')
138
 
@@ -157,10 +159,10 @@ last_lora = ""
157
  last_fused = False
158
  lora_archive = "/data"
159
 
160
- # Improved face detection with multi-face support
161
  def detect_faces(face_image, use_multiple_faces=False):
162
  """
163
- Detect faces in the image
164
  Returns: list of face info dictionaries, or empty list if no faces
165
  """
166
  try:
@@ -170,47 +172,56 @@ def detect_faces(face_image, use_multiple_faces=False):
170
  print("No faces detected")
171
  return []
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  # Sort faces by size (largest first)
174
- face_info_list = sorted(
175
- face_info_list,
176
  key=lambda x: (x['bbox'][2] - x['bbox'][0]) * (x['bbox'][3] - x['bbox'][1]),
177
  reverse=True
178
  )
179
 
180
  if use_multiple_faces:
181
- print(f"Detected {len(face_info_list)} faces")
182
- return face_info_list
183
  else:
184
- print(f"Using largest face (detected {len(face_info_list)} total)")
185
- return [face_info_list[0]]
186
 
187
  except Exception as e:
188
  print(f"Face detection error: {e}")
189
  return []
190
 
191
- def process_face_embeddings(face_info_list):
192
  """
193
- Process face embeddings - average multiple faces or return single face
 
194
  """
195
  if not face_info_list:
196
- return None
197
-
198
- if len(face_info_list) == 1:
199
- return face_info_list[0]['embedding']
200
 
201
- # Average embeddings for multiple faces
202
  embeddings = [face_info['embedding'] for face_info in face_info_list]
203
- avg_embedding = np.mean(embeddings, axis=0)
204
- return avg_embedding
205
 
206
  def create_face_kps_image(face_image, face_info_list):
207
  """
208
- Create keypoints image from face info
209
  """
210
  if not face_info_list:
211
  return face_image
212
 
213
- # For multiple faces, draw all keypoints
214
  if len(face_info_list) > 1:
215
  return draw_multiple_kps(face_image, [f['kps'] for f in face_info_list])
216
  else:
@@ -218,7 +229,7 @@ def create_face_kps_image(face_image, face_info_list):
218
 
219
  def draw_multiple_kps(image_pil, kps_list, color_list=[(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 0, 255)]):
220
  """
221
- Draw keypoints for multiple faces
222
  """
223
  stickwidth = 4
224
  limbSeq = np.array([[0, 2], [1, 2], [3, 2], [4, 2]])
@@ -226,12 +237,14 @@ def draw_multiple_kps(image_pil, kps_list, color_list=[(255, 0, 0), (0, 255, 0),
226
  w, h = image_pil.size
227
  out_img = np.zeros([h, w, 3])
228
 
229
- for kps in kps_list:
230
  kps = np.array(kps)
 
 
231
 
232
  for i in range(len(limbSeq)):
233
  index = limbSeq[i]
234
- color = color_list[index[0]]
235
 
236
  x = kps[index][:, 0]
237
  y = kps[index][:, 1]
@@ -245,7 +258,7 @@ def draw_multiple_kps(image_pil, kps_list, color_list=[(255, 0, 0), (0, 255, 0),
245
  out_img = (out_img * 0.6).astype(np.uint8)
246
 
247
  for idx_kp, kp in enumerate(kps):
248
- color = color_list[idx_kp]
249
  x, y = kp
250
  out_img = cv2.circle(out_img.copy(), (int(x), int(y)), 10, color, -1)
251
 
@@ -260,9 +273,9 @@ def update_selection(selected_state: gr.SelectData, sdxl_loras, face_strength, i
260
 
261
  for lora_list in lora_defaults:
262
  if lora_list["model"] == sdxl_loras[selected_state.index]["repo"]:
263
- face_strength = lora_list.get("face_strength", 0.9)
264
- image_strength = lora_list.get("image_strength", 0.2)
265
- weight = lora_list.get("weight", 0.95)
266
  depth_control_scale = lora_list.get("depth_control_scale", 0.8)
267
  negative = lora_list.get("negative", "")
268
 
@@ -308,10 +321,7 @@ def run_lora(face_image, prompt, negative, lora_scale, selected_state, face_stre
308
  guidance_scale, depth_control_scale, sdxl_loras, custom_lora, use_multiple_faces=False,
309
  progress=gr.Progress(track_tqdm=True)):
310
  """
311
- Enhanced run_lora with support for:
312
- - No faces (landscape mode)
313
- - Multiple faces
314
- - Improved results
315
  """
316
  print("Custom LoRA:", custom_lora)
317
  custom_lora_path = custom_lora[0] if custom_lora else None
@@ -325,13 +335,17 @@ def run_lora(face_image, prompt, negative, lora_scale, selected_state, face_stre
325
  face_detected = len(face_info_list) > 0
326
 
327
  if face_detected:
328
- face_emb = process_face_embeddings(face_info_list)
 
329
  face_kps = create_face_kps_image(face_image, face_info_list)
330
- print(f"Processing with {len(face_info_list)} face(s)")
 
 
 
331
  else:
332
  face_emb = None
333
  face_kps = face_image
334
- print("No faces detected - using landscape/depth mode only")
335
 
336
  et = time.time()
337
  print('Face processing took:', et - st, 'seconds')
@@ -348,14 +362,21 @@ def run_lora(face_image, prompt, negative, lora_scale, selected_state, face_stre
348
  if prompt_full:
349
  prompt = prompt_full.replace("<subject>", prompt)
350
 
 
 
 
 
351
  print("Prompt:", prompt)
352
  if prompt == "":
353
- prompt = "a beautiful scene" if not face_detected else "a person"
354
  print(f"Executing prompt: {prompt}")
355
 
356
  if negative == "":
357
- # Enhanced negative prompt for better quality
358
- negative = "worst quality, low quality, blurry, distorted, deformed" if not face_detected else None
 
 
 
359
 
360
  print("Custom Loaded LoRA:", custom_lora_path)
361
 
@@ -375,15 +396,22 @@ def run_lora(face_image, prompt, negative, lora_scale, selected_state, face_stre
375
  et = time.time()
376
  print('Prompt processing took:', et - st, 'seconds')
377
 
378
- # Adjust parameters based on face detection
379
  if not face_detected:
380
- # For landscape/no face mode, reduce face strength and increase depth control
381
  face_strength = 0.0
382
- depth_control_scale = max(depth_control_scale, 0.9)
383
- image_strength = min(image_strength, 0.4)
384
- print("Adjusted parameters for no-face mode")
 
 
 
 
 
385
 
386
  st = time.time()
 
 
387
  image = generate_image(
388
  prompt, negative, face_emb, face_image, face_kps, image_strength,
389
  guidance_scale, face_strength, depth_control_scale, repo_name,
@@ -395,7 +423,7 @@ def run_lora(face_image, prompt, negative, lora_scale, selected_state, face_stre
395
  run_lora.zerogpu = True
396
 
397
 
398
- @spaces.GPU(duration=75)
399
  def generate_image(prompt, negative, face_emb, face_image, face_kps, image_strength, guidance_scale,
400
  face_strength, depth_control_scale, repo_name, loaded_state_dict, lora_scale,
401
  sdxl_loras, selected_state_index, face_detected, st):
@@ -404,13 +432,16 @@ def generate_image(prompt, negative, face_emb, face_image, face_kps, image_stren
404
  print("Loaded state dict:", loaded_state_dict)
405
  print("Last LoRA:", last_lora, "| Current LoRA:", repo_name)
406
 
407
- # Prepare control images and scales based on face detection
 
 
408
  if face_detected:
409
- control_images = [face_kps, zoe(face_image)]
 
410
  control_scales = [face_strength, depth_control_scale]
411
  else:
412
- # Only use depth control for landscapes
413
- control_images = [zoe(face_image)]
414
  control_scales = [depth_control_scale]
415
 
416
  # Handle custom LoRA from HuggingFace
@@ -441,7 +472,7 @@ def generate_image(prompt, negative, face_emb, face_image, face_kps, image_stren
441
  pipe.fuse_lora(lora_scale)
442
  last_fused = True
443
 
444
- # Handle pivotal tuning embeddings
445
  is_pivotal = sdxl_loras[selected_state_index]["is_pivotal"]
446
  if is_pivotal:
447
  text_embedding_name = sdxl_loras[selected_state_index]["text_embedding_weights"]
@@ -467,8 +498,8 @@ def generate_image(prompt, negative, face_emb, face_image, face_kps, image_stren
467
  conditioning, pooled = compel(prompt)
468
  negative_conditioning, negative_pooled = compel(negative) if negative else (None, None)
469
 
470
- # Enhanced generation parameters
471
- num_inference_steps = 40 # Increased for better quality
472
 
473
  print("Generating image...")
474
  image = pipe(
@@ -480,7 +511,7 @@ def generate_image(prompt, negative, face_emb, face_image, face_kps, image_stren
480
  height=face_image.height,
481
  image_embeds=face_emb if face_detected else None,
482
  image=face_image,
483
- strength=1-image_strength,
484
  control_image=control_images,
485
  num_inference_steps=num_inference_steps,
486
  guidance_scale=guidance_scale,
@@ -615,12 +646,12 @@ with gr.Blocks(css="custom.css") as demo:
615
  gr_sdxl_loras = gr.State(value=sdxl_loras_raw)
616
  title = gr.HTML(
617
  """<h1><img src="https://i.imgur.com/DVoGw04.png">
618
- <span>Face to All - Enhanced<br><small style="
619
  font-size: 13px;
620
  display: block;
621
  font-weight: normal;
622
  opacity: 0.75;
623
- ">🔥 Supports: No faces (landscape), Multiple faces, Improved quality, Custom LoRAs<br> diffusers InstantID + ControlNet</small></span></h1>""",
624
  elem_id="title",
625
  )
626
  selected_state = gr.State()
@@ -632,7 +663,7 @@ with gr.Blocks(css="custom.css") as demo:
632
  photo = gr.Image(label="Upload a picture (with or without faces)", interactive=True, type="pil", height=300)
633
  selected_loras = gr.Gallery(label="Selected LoRAs", height=80, show_share_button=False, visible=False, elem_id="gallery_selected")
634
  gallery = gr.Gallery(
635
- label="Pick a style from the gallery",
636
  allow_preview=False,
637
  columns=4,
638
  elem_id="gallery",
@@ -659,18 +690,32 @@ with gr.Blocks(css="custom.css") as demo:
659
  share_button = gr.Button("Share to community", elem_id="share-btn")
660
 
661
  with gr.Accordion("Advanced options", open=False):
662
- use_multiple_faces = gr.Checkbox(label="Use multiple faces (if detected)", value=False)
 
 
 
 
663
  negative = gr.Textbox(label="Negative Prompt")
664
- weight = gr.Slider(0, 10, value=0.9, step=0.1, label="LoRA weight")
665
- face_strength = gr.Slider(0, 2, value=0.9, step=0.01, label="Face strength",
666
- info="Higher values increase face likeness (auto-adjusted for no-face images)")
667
- image_strength = gr.Slider(0, 1, value=0.20, step=0.01, label="Image strength",
668
- info="Higher values increase similarity with original structure/colors")
669
- guidance_scale = gr.Slider(0, 50, value=8, step=0.1, label="Guidance Scale")
670
- depth_control_scale = gr.Slider(0, 1, value=0.8, step=0.01, label="Zoe Depth ControlNet strength")
 
 
 
 
 
 
 
 
 
 
671
 
672
  prompt_title = gr.Markdown(
673
- value="### Click on a LoRA in the gallery to select it",
674
  visible=True,
675
  elem_id="selected_lora",
676
  )
 
38
 
39
  from gradio_imageslider import ImageSlider
40
 
41
+ # Load LoRA configurations - now only LucasArts style
42
  with open("sdxl_loras.json", "r") as file:
43
  data = json.load(file)
44
  sdxl_loras_raw = [
 
123
  print('Loading VAE took: ', et - st, 'seconds')
124
 
125
  st = time.time()
126
+ # CHANGED: Using AlbedoBase XL v2.1 for better quality
127
  pipe = StableDiffusionXLInstantIDImg2ImgPipeline.from_pretrained(
128
+ "frankjoshua/albedobaseXL_v21",
129
  vae=vae,
130
  controlnet=[identitynet, zoedepthnet],
131
  torch_dtype=torch.float16
 
133
 
134
  pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config, use_karras_sigmas=True)
135
  pipe.load_ip_adapter_instantid(face_adapter)
136
+ # IMPROVED: Higher IP adapter scale for better face preservation
137
+ pipe.set_ip_adapter_scale(1.0)
138
  et = time.time()
139
  print('Loading pipeline took: ', et - st, 'seconds')
140
 
 
159
  last_fused = False
160
  lora_archive = "/data"
161
 
162
+ # Enhanced face detection with better face quality filtering
163
  def detect_faces(face_image, use_multiple_faces=False):
164
  """
165
+ Detect faces in the image with quality filtering
166
  Returns: list of face info dictionaries, or empty list if no faces
167
  """
168
  try:
 
172
  print("No faces detected")
173
  return []
174
 
175
+ # Filter faces by quality score if available
176
+ filtered_faces = []
177
+ for face_info in face_info_list:
178
+ # Check if face has minimum quality
179
+ if 'det_score' in face_info and face_info['det_score'] > 0.5:
180
+ filtered_faces.append(face_info)
181
+ elif 'det_score' not in face_info:
182
+ filtered_faces.append(face_info)
183
+
184
+ if not filtered_faces:
185
+ print("No high-quality faces detected")
186
+ return []
187
+
188
  # Sort faces by size (largest first)
189
+ filtered_faces = sorted(
190
+ filtered_faces,
191
  key=lambda x: (x['bbox'][2] - x['bbox'][0]) * (x['bbox'][3] - x['bbox'][1]),
192
  reverse=True
193
  )
194
 
195
  if use_multiple_faces:
196
+ print(f"Detected {len(filtered_faces)} high-quality faces")
197
+ return filtered_faces
198
  else:
199
+ print(f"Using largest face (detected {len(filtered_faces)} total)")
200
+ return [filtered_faces[0]]
201
 
202
  except Exception as e:
203
  print(f"Face detection error: {e}")
204
  return []
205
 
206
+ def process_face_embeddings_separately(face_info_list):
207
  """
208
+ Process face embeddings separately for multi-face generation
209
+ Returns: list of individual face embeddings
210
  """
211
  if not face_info_list:
212
+ return []
 
 
 
213
 
 
214
  embeddings = [face_info['embedding'] for face_info in face_info_list]
215
+ return embeddings
 
216
 
217
  def create_face_kps_image(face_image, face_info_list):
218
  """
219
+ Create keypoints image from face info with enhanced visibility
220
  """
221
  if not face_info_list:
222
  return face_image
223
 
224
+ # For multiple faces, draw all keypoints with different colors
225
  if len(face_info_list) > 1:
226
  return draw_multiple_kps(face_image, [f['kps'] for f in face_info_list])
227
  else:
 
229
 
230
  def draw_multiple_kps(image_pil, kps_list, color_list=[(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 0, 255)]):
231
  """
232
+ Draw keypoints for multiple faces with enhanced visibility
233
  """
234
  stickwidth = 4
235
  limbSeq = np.array([[0, 2], [1, 2], [3, 2], [4, 2]])
 
237
  w, h = image_pil.size
238
  out_img = np.zeros([h, w, 3])
239
 
240
+ for idx, kps in enumerate(kps_list):
241
  kps = np.array(kps)
242
+ # Use different colors for different faces
243
+ color_offset = idx % len(color_list)
244
 
245
  for i in range(len(limbSeq)):
246
  index = limbSeq[i]
247
+ color = color_list[(index[0] + color_offset) % len(color_list)]
248
 
249
  x = kps[index][:, 0]
250
  y = kps[index][:, 1]
 
258
  out_img = (out_img * 0.6).astype(np.uint8)
259
 
260
  for idx_kp, kp in enumerate(kps):
261
+ color = color_list[(idx_kp + color_offset) % len(color_list)]
262
  x, y = kp
263
  out_img = cv2.circle(out_img.copy(), (int(x), int(y)), 10, color, -1)
264
 
 
273
 
274
  for lora_list in lora_defaults:
275
  if lora_list["model"] == sdxl_loras[selected_state.index]["repo"]:
276
+ face_strength = lora_list.get("face_strength", 1.0)
277
+ image_strength = lora_list.get("image_strength", 0.15)
278
+ weight = lora_list.get("weight", 1.0)
279
  depth_control_scale = lora_list.get("depth_control_scale", 0.8)
280
  negative = lora_list.get("negative", "")
281
 
 
321
  guidance_scale, depth_control_scale, sdxl_loras, custom_lora, use_multiple_faces=False,
322
  progress=gr.Progress(track_tqdm=True)):
323
  """
324
+ Enhanced run_lora with improved face preservation and landscape mode
 
 
 
325
  """
326
  print("Custom LoRA:", custom_lora)
327
  custom_lora_path = custom_lora[0] if custom_lora else None
 
335
  face_detected = len(face_info_list) > 0
336
 
337
  if face_detected:
338
+ # CHANGED: Process faces separately instead of averaging
339
+ face_embeddings = process_face_embeddings_separately(face_info_list)
340
  face_kps = create_face_kps_image(face_image, face_info_list)
341
+ print(f"Processing with {len(face_info_list)} face(s) separately")
342
+
343
+ # For multiple faces, we'll generate with the primary face (largest)
344
+ face_emb = face_embeddings[0]
345
  else:
346
  face_emb = None
347
  face_kps = face_image
348
+ print("No faces detected - using enhanced landscape/depth mode")
349
 
350
  et = time.time()
351
  print('Face processing took:', et - st, 'seconds')
 
362
  if prompt_full:
363
  prompt = prompt_full.replace("<subject>", prompt)
364
 
365
+ # Add LucasArts trigger word if not present
366
+ if "lucasarts artstyle" not in prompt.lower():
367
+ prompt = f"{prompt}, lucasarts artstyle"
368
+
369
  print("Prompt:", prompt)
370
  if prompt == "":
371
+ prompt = "a beautiful cinematic scene" if not face_detected else "a person in cinematic lighting"
372
  print(f"Executing prompt: {prompt}")
373
 
374
  if negative == "":
375
+ # Enhanced negative prompt
376
+ if not face_detected:
377
+ negative = "worst quality, low quality, blurry, distorted, deformed, ugly, bad anatomy"
378
+ else:
379
+ negative = "worst quality, low quality, blurry, distorted, deformed, ugly, bad anatomy, bad proportions"
380
 
381
  print("Custom Loaded LoRA:", custom_lora_path)
382
 
 
396
  et = time.time()
397
  print('Prompt processing took:', et - st, 'seconds')
398
 
399
+ # IMPROVED: Better parameter adjustment for face/landscape modes
400
  if not face_detected:
401
+ # Enhanced landscape mode parameters
402
  face_strength = 0.0
403
+ depth_control_scale = 1.0 # Maximum depth control for landscapes
404
+ image_strength = 0.25 # Higher structure preservation
405
+ print("Adjusted parameters for enhanced landscape mode")
406
+ else:
407
+ # Enhanced face preservation
408
+ face_strength = max(face_strength, 1.0) # Ensure strong face preservation
409
+ depth_control_scale = max(depth_control_scale, 0.8) # Good depth control
410
+ print("Adjusted parameters for enhanced face preservation")
411
 
412
  st = time.time()
413
+
414
+ # Generate single image with best face (or landscape)
415
  image = generate_image(
416
  prompt, negative, face_emb, face_image, face_kps, image_strength,
417
  guidance_scale, face_strength, depth_control_scale, repo_name,
 
423
  run_lora.zerogpu = True
424
 
425
 
426
+ @spaces.GPU(duration=90) # Increased duration for better quality
427
  def generate_image(prompt, negative, face_emb, face_image, face_kps, image_strength, guidance_scale,
428
  face_strength, depth_control_scale, repo_name, loaded_state_dict, lora_scale,
429
  sdxl_loras, selected_state_index, face_detected, st):
 
432
  print("Loaded state dict:", loaded_state_dict)
433
  print("Last LoRA:", last_lora, "| Current LoRA:", repo_name)
434
 
435
+ # IMPROVED: Better control image preparation
436
+ depth_image = zoe(face_image)
437
+
438
  if face_detected:
439
+ # Face mode: use both face keypoints and depth
440
+ control_images = [face_kps, depth_image]
441
  control_scales = [face_strength, depth_control_scale]
442
  else:
443
+ # Landscape mode: only depth control with enhanced parameters
444
+ control_images = [depth_image]
445
  control_scales = [depth_control_scale]
446
 
447
  # Handle custom LoRA from HuggingFace
 
472
  pipe.fuse_lora(lora_scale)
473
  last_fused = True
474
 
475
+ # Handle pivotal tuning embeddings (if needed for future LoRAs)
476
  is_pivotal = sdxl_loras[selected_state_index]["is_pivotal"]
477
  if is_pivotal:
478
  text_embedding_name = sdxl_loras[selected_state_index]["text_embedding_weights"]
 
498
  conditioning, pooled = compel(prompt)
499
  negative_conditioning, negative_pooled = compel(negative) if negative else (None, None)
500
 
501
+ # IMPROVED: Enhanced generation parameters for better quality
502
+ num_inference_steps = 50 # Increased for better quality
503
 
504
  print("Generating image...")
505
  image = pipe(
 
511
  height=face_image.height,
512
  image_embeds=face_emb if face_detected else None,
513
  image=face_image,
514
+ strength=1-image_strength, # Higher strength = more transformation
515
  control_image=control_images,
516
  num_inference_steps=num_inference_steps,
517
  guidance_scale=guidance_scale,
 
646
  gr_sdxl_loras = gr.State(value=sdxl_loras_raw)
647
  title = gr.HTML(
648
  """<h1><img src="https://i.imgur.com/DVoGw04.png">
649
+ <span>LucasArts Style - Enhanced Face Preservation<br><small style="
650
  font-size: 13px;
651
  display: block;
652
  font-weight: normal;
653
  opacity: 0.75;
654
+ ">🔥 Improved: Better face identity preservation, Enhanced landscape mode, Multiple face support<br>AlbedoBase XL v2.1 + InstantID + ControlNet</small></span></h1>""",
655
  elem_id="title",
656
  )
657
  selected_state = gr.State()
 
663
  photo = gr.Image(label="Upload a picture (with or without faces)", interactive=True, type="pil", height=300)
664
  selected_loras = gr.Gallery(label="Selected LoRAs", height=80, show_share_button=False, visible=False, elem_id="gallery_selected")
665
  gallery = gr.Gallery(
666
+ label="LucasArts Style",
667
  allow_preview=False,
668
  columns=4,
669
  elem_id="gallery",
 
690
  share_button = gr.Button("Share to community", elem_id="share-btn")
691
 
692
  with gr.Accordion("Advanced options", open=False):
693
+ use_multiple_faces = gr.Checkbox(
694
+ label="Process multiple faces separately",
695
+ value=False,
696
+ info="Generate separate outputs for each detected face"
697
+ )
698
  negative = gr.Textbox(label="Negative Prompt")
699
+ weight = gr.Slider(0, 10, value=1.0, step=0.1, label="LoRA weight")
700
+ face_strength = gr.Slider(
701
+ 0, 2, value=1.0, step=0.01, label="Face identity strength",
702
+ info="Higher = stronger face preservation (auto-adjusted for landscapes)"
703
+ )
704
+ image_strength = gr.Slider(
705
+ 0, 1, value=0.15, step=0.01, label="Image structure strength",
706
+ info="Lower = more transformation, Higher = more original structure"
707
+ )
708
+ guidance_scale = gr.Slider(
709
+ 0, 50, value=7.5, step=0.1, label="Guidance Scale",
710
+ info="How closely to follow the prompt"
711
+ )
712
+ depth_control_scale = gr.Slider(
713
+ 0, 1, value=0.8, step=0.01, label="Depth ControlNet strength",
714
+ info="3D structure preservation (auto-maximized for landscapes)"
715
+ )
716
 
717
  prompt_title = gr.Markdown(
718
+ value="### Click 'Run' to generate with LucasArts style",
719
  visible=True,
720
  elem_id="selected_lora",
721
  )