Spaces:
Running
on
Zero
Running
on
Zero
Update utils.py
Browse files
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:
|
| 154 |
if PROFESSIONAL_PHOTOGRAPHY_CONFIG.get("prompt_condensation", True):
|
| 155 |
-
description_part =
|
| 156 |
-
logger.info("
|
| 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
|
| 228 |
-
"""
|
| 229 |
try:
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
# Remove
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
|
| 263 |
except Exception as e:
|
| 264 |
-
logger.warning(f"
|
| 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
|
| 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,
|
| 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 |
|