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 |
|