Malaji71 commited on
Commit
c55ae1b
·
verified ·
1 Parent(s): d1eca5e

Update utils.py

Browse files
Files changed (1) hide show
  1. utils.py +92 -45
utils.py CHANGED
@@ -150,10 +150,10 @@ def apply_flux_rules(prompt: str, analysis_metadata: Optional[Dict[str, Any]] =
150
  # Extract description part only (remove CAMERA_SETUP section if present)
151
  description_part = _extract_description_only(cleaned_prompt)
152
 
153
- # NEW: Condense the description to remove redundancy
154
  if PROFESSIONAL_PHOTOGRAPHY_CONFIG.get("prompt_condensation", True):
155
- description_part = _condense_description(description_part)
156
- logger.info("Applied prompt condensation")
157
 
158
  # Check if BAGEL provided intelligent camera setup with cinematography context
159
  camera_config = ""
@@ -224,44 +224,89 @@ def _extract_description_only(prompt: str) -> str:
224
  return description.strip()
225
 
226
 
227
- def _condense_description(description: str) -> str:
228
- """Condense BAGEL's verbose description into concise prompt format"""
229
  try:
230
- condensed = description
231
-
232
- # Remove redundant phrases
233
- redundant_phrases = FLUX_RULES.get("condensation_patterns", {}).get("remove_redundant_phrases", [])
234
- for phrase in redundant_phrases:
235
- condensed = re.sub(phrase, '', condensed, flags=re.IGNORECASE)
236
-
237
- # Simplify lighting descriptions
238
- lighting_simplifications = FLUX_RULES.get("condensation_patterns", {}).get("simplify_lighting_descriptions", [])
239
- for pattern, replacement in lighting_simplifications:
240
- condensed = re.sub(pattern, replacement, condensed, flags=re.IGNORECASE)
241
-
242
- # Condense mood descriptions
243
- mood_condensations = FLUX_RULES.get("condensation_patterns", {}).get("condense_mood_descriptions", [])
244
- for pattern, replacement in mood_condensations:
245
- condensed = re.sub(pattern, replacement, condensed, flags=re.IGNORECASE)
246
-
247
- # Remove excessive adjectives and verbose explanations
248
- condensed = re.sub(r'\s*,\s*which\s+[^,]+,\s*', ', ', condensed)
249
- condensed = re.sub(r'\s*\.\s*The\s+', '. ', condensed)
250
- condensed = re.sub(r'\s+', ' ', condensed)
251
-
252
- # Split into sentences and keep only the most essential
253
- sentences = [s.strip() for s in condensed.split('.') if s.strip()]
254
-
255
- # Keep first 2-3 most descriptive sentences
256
- if len(sentences) > 3:
257
- essential_sentences = sentences[:3]
258
- condensed = '. '.join(essential_sentences)
259
-
260
- logger.info(f"Condensed description from {len(description)} to {len(condensed)} characters")
261
- return condensed.strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
 
263
  except Exception as e:
264
- logger.warning(f"Description condensation failed: {e}")
265
  return description
266
 
267
 
@@ -334,6 +379,8 @@ def _optimize_prompt_length(prompt: str) -> str:
334
  except Exception as e:
335
  logger.warning(f"Prompt length optimization failed: {e}")
336
  return prompt
 
 
337
  def _detect_scene_from_description(description_lower: str) -> str:
338
  """Enhanced scene detection from description with cinematography knowledge"""
339
  scene_keywords = PROFESSIONAL_PHOTOGRAPHY_CONFIG.get("scene_detection_keywords", {})
@@ -437,12 +484,12 @@ def _get_enhanced_camera_config(scene_type: str, description_lower: str) -> str:
437
  """Get enhanced camera configuration with cinematography knowledge"""
438
  # Enhanced camera configurations with cinema equipment
439
  enhanced_configs = {
440
- "cinematic": ", Shot on ARRI Alexa LF, 35mm anamorphic lens, cinematic photography",
441
- "portrait": ", Shot on Canon EOS R5, 85mm f/1.4 lens at f/2.8, professional portrait photography",
442
- "landscape": ", Shot on Phase One XT, 24-70mm f/4 lens at f/8, epic landscape photography",
443
- "street": ", Shot on Leica M11, 35mm f/1.4 lens at f/2.8, documentary street photography",
444
- "architectural": ", Shot on Canon EOS R5, 24-70mm f/2.8 lens at f/8, architectural photography",
445
- "commercial": ", Shot on Hasselblad X2D 100C, 90mm f/2.5 lens, commercial photography"
446
  }
447
 
448
  # Use enhanced config if available, otherwise fall back to FLUX_RULES
@@ -482,7 +529,7 @@ def _get_style_enhancement(scene_type: str, description_lower: str) -> str:
482
  if "film grain" not in description_lower:
483
  return ", " + style_enhancements.get("cinematic", "cinematic composition, film grain")
484
  elif scene_type in ["portrait", "commercial"]:
485
- return ", " + style_enhancements.get("photorealistic", "photorealistic, ultra-detailed")
486
  elif "editorial" in description_lower:
487
  return ", " + style_enhancements.get("editorial", "editorial photography style")
488
 
 
150
  # Extract description part only (remove CAMERA_SETUP section if present)
151
  description_part = _extract_description_only(cleaned_prompt)
152
 
153
+ # NEW: Convert from descriptive to generative language
154
  if PROFESSIONAL_PHOTOGRAPHY_CONFIG.get("prompt_condensation", True):
155
+ description_part = _convert_to_generative_language(description_part)
156
+ logger.info("Converted to generative language")
157
 
158
  # Check if BAGEL provided intelligent camera setup with cinematography context
159
  camera_config = ""
 
224
  return description.strip()
225
 
226
 
227
+ def _convert_to_generative_language(description: str) -> str:
228
+ """Convert descriptive analysis language to direct generative prompt language"""
229
  try:
230
+ generative = description
231
+
232
+ # Remove descriptive introduction phrases
233
+ descriptive_intros = [
234
+ r'This image (?:features|shows|depicts|presents|displays)',
235
+ r'The image (?:features|shows|depicts|presents|displays)',
236
+ r'This (?:photograph|picture|scene|composition) (?:features|shows|depicts)',
237
+ r'The (?:photograph|picture|scene|composition) (?:features|shows|depicts)',
238
+ r'This is (?:a|an) (?:image|photograph|picture) (?:of|showing)',
239
+ r'The setting (?:appears to be|is)',
240
+ r'The scene (?:appears to be|is|shows)',
241
+ r'(?:In the background|In the foreground), (?:there are|there is)',
242
+ r'(?:The background|The foreground) (?:features|shows|contains)',
243
+ r'(?:There are|There is) [^,]+ (?:in the background|in the foreground)',
244
+ r'The overall (?:setting|atmosphere|mood) (?:suggests|indicates)',
245
+ ]
246
+
247
+ for pattern in descriptive_intros:
248
+ generative = re.sub(pattern, '', generative, flags=re.IGNORECASE)
249
+
250
+ # Remove uncertainty phrases
251
+ uncertainty_phrases = [
252
+ r'possibly (?:a|an) ',
253
+ r'appears to be (?:a|an) ',
254
+ r'seems to be (?:a|an) ',
255
+ r'might be (?:a|an) ',
256
+ r'could be (?:a|an) ',
257
+ r'suggests (?:a|an) ',
258
+ r'indicating (?:a|an) ',
259
+ r'(?:possibly|apparently|seemingly|likely)',
260
+ ]
261
+
262
+ for pattern in uncertainty_phrases:
263
+ generative = re.sub(pattern, '', generative, flags=re.IGNORECASE)
264
+
265
+ # Convert descriptive structure to noun phrases
266
+ structural_conversions = [
267
+ # "close-up of a X" -> "close-up X"
268
+ (r'(?:close-up|medium shot|wide shot) of (?:a|an|the) ', r'close-up '),
269
+ # "blurred figures of people" -> "blurred people"
270
+ (r'(?:blurred )?(?:figures|silhouettes) of (\w+)', r'blurred \1'),
271
+ # "people walking on a sidewalk" -> "people walking on sidewalk"
272
+ (r'(?:a|an|the) (\w+)', r'\1'),
273
+ # Remove excessive connecting words
274
+ (r'(?:, and|, with|, featuring)', ','),
275
+ # Simplify location descriptions
276
+ (r'on (?:a|an|the) ', r'on '),
277
+ (r'in (?:a|an|the) ', r'in '),
278
+ ]
279
+
280
+ for pattern, replacement in structural_conversions:
281
+ generative = re.sub(pattern, replacement, generative, flags=re.IGNORECASE)
282
+
283
+ # Convert action descriptions to present participles
284
+ action_conversions = [
285
+ (r'(\w+) (?:are|is) walking', r'\1 walking'),
286
+ (r'(\w+) (?:are|is) standing', r'\1 standing'),
287
+ (r'(\w+) (?:are|is) sitting', r'\1 sitting'),
288
+ (r'people (?:are|is) out of focus', r'blurred people'),
289
+ ]
290
+
291
+ for pattern, replacement in action_conversions:
292
+ generative = re.sub(pattern, replacement, generative, flags=re.IGNORECASE)
293
+
294
+ # Clean up extra spaces and punctuation
295
+ generative = re.sub(r'\s+', ' ', generative)
296
+ generative = re.sub(r'^\s*,\s*', '', generative) # Remove leading commas
297
+ generative = re.sub(r'\s*,\s*,+', ',', generative) # Remove double commas
298
+ generative = re.sub(r'\.+', '.', generative) # Remove multiple periods
299
+
300
+ # Ensure it starts with a capital letter
301
+ generative = generative.strip()
302
+ if generative:
303
+ generative = generative[0].upper() + generative[1:] if len(generative) > 1 else generative.upper()
304
+
305
+ logger.info(f"Converted descriptive to generative: {len(description)} → {len(generative)} chars")
306
+ return generative
307
 
308
  except Exception as e:
309
+ logger.warning(f"Generative language conversion failed: {e}")
310
  return description
311
 
312
 
 
379
  except Exception as e:
380
  logger.warning(f"Prompt length optimization failed: {e}")
381
  return prompt
382
+
383
+
384
  def _detect_scene_from_description(description_lower: str) -> str:
385
  """Enhanced scene detection from description with cinematography knowledge"""
386
  scene_keywords = PROFESSIONAL_PHOTOGRAPHY_CONFIG.get("scene_detection_keywords", {})
 
484
  """Get enhanced camera configuration with cinematography knowledge"""
485
  # Enhanced camera configurations with cinema equipment
486
  enhanced_configs = {
487
+ "cinematic": ", Shot on ARRI Alexa LF, 35mm anamorphic lens at f/2.8, ISO 400, cinematic framing, film grain, dramatic composition",
488
+ "portrait": ", Shot on Canon EOS R5, 85mm f/1.4 lens at f/2.8, ISO 200, rule of thirds composition, professional portrait photography",
489
+ "landscape": ", Shot on Phase One XT, 24-70mm f/4 lens at f/8, ISO 100, hyperfocal distance, leading lines composition, epic landscape photography",
490
+ "street": ", Shot on Leica M11, 35mm f/1.4 lens at f/2.8, ISO 800, decisive moment, candid composition, documentary street photography",
491
+ "architectural": ", Shot on Canon EOS R5, 24-70mm f/2.8 lens at f/8, ISO 100, symmetrical composition, perspective correction, architectural photography",
492
+ "commercial": ", Shot on Hasselblad X2D 100C, 90mm f/2.5 lens at f/4, ISO 100, centered composition, product photography"
493
  }
494
 
495
  # Use enhanced config if available, otherwise fall back to FLUX_RULES
 
529
  if "film grain" not in description_lower:
530
  return ", " + style_enhancements.get("cinematic", "cinematic composition, film grain")
531
  elif scene_type in ["portrait", "commercial"]:
532
+ return ", " + style_enhancements.get("photorealistic", "photorealistic rendering, ultra-detailed")
533
  elif "editorial" in description_lower:
534
  return ", " + style_enhancements.get("editorial", "editorial photography style")
535