Spaces:
Running
on
Zero
Running
on
Zero
Update models.py
Browse files
models.py
CHANGED
|
@@ -90,234 +90,123 @@ class BagelAPIAnalyzer(BaseImageAnalyzer):
|
|
| 90 |
return False
|
| 91 |
|
| 92 |
def _create_professional_enhanced_prompt(self, analysis_type: str = "multimodal") -> str:
|
| 93 |
-
"""Create professionally enhanced prompt
|
| 94 |
|
| 95 |
-
# Import the complete professional knowledge
|
| 96 |
-
try:
|
| 97 |
-
from professional_photography import EXPERT_PHOTOGRAPHY_KNOWLEDGE
|
| 98 |
-
except ImportError:
|
| 99 |
-
logger.warning("Professional photography knowledge not available")
|
| 100 |
-
return self._create_fallback_prompt(analysis_type)
|
| 101 |
-
|
| 102 |
-
# Extract complete knowledge sections safely
|
| 103 |
-
knowledge_sections = {
|
| 104 |
-
'scene_types': EXPERT_PHOTOGRAPHY_KNOWLEDGE.get("scene_types", {}),
|
| 105 |
-
'lighting_principles': EXPERT_PHOTOGRAPHY_KNOWLEDGE.get("lighting_principles", {}),
|
| 106 |
-
'composition_rules': EXPERT_PHOTOGRAPHY_KNOWLEDGE.get("composition_rules", {}),
|
| 107 |
-
'camera_angles': EXPERT_PHOTOGRAPHY_KNOWLEDGE.get("camera_angles", {}),
|
| 108 |
-
'photographic_planes': EXPERT_PHOTOGRAPHY_KNOWLEDGE.get("photographic_planes", {}),
|
| 109 |
-
'focus_techniques': EXPERT_PHOTOGRAPHY_KNOWLEDGE.get("focus_techniques", {}),
|
| 110 |
-
'camera_modes': EXPERT_PHOTOGRAPHY_KNOWLEDGE.get("camera_modes", {}),
|
| 111 |
-
'iso_guidelines': EXPERT_PHOTOGRAPHY_KNOWLEDGE.get("iso_guidelines", {}),
|
| 112 |
-
'lighting_situations': EXPERT_PHOTOGRAPHY_KNOWLEDGE.get("lighting_situations", {}),
|
| 113 |
-
'movement_techniques': EXPERT_PHOTOGRAPHY_KNOWLEDGE.get("movement_techniques", {}),
|
| 114 |
-
'specialized_techniques': EXPERT_PHOTOGRAPHY_KNOWLEDGE.get("specialized_techniques", {})
|
| 115 |
-
}
|
| 116 |
-
|
| 117 |
-
# Build prompt based on analysis type
|
| 118 |
if analysis_type == "cinematic":
|
| 119 |
-
return
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
• Overcast: {lighting_principles.get("natural_light_types", {}).get("overcast", {}).get("characteristics", "soft, even, diffused light")} - advantage: {lighting_principles.get("natural_light_types", {}).get("overcast", {}).get("advantage", "no harsh shadows")}
|
| 164 |
-
|
| 165 |
-
2. CAMERA_SETUP: Recommend specific professional equipment based on scene analysis using these configurations:
|
| 166 |
-
|
| 167 |
-
SCENE TYPES - Match scene to appropriate setup:
|
| 168 |
-
Portrait Studio: Equipment: {scene_types.get("portrait_studio", {}).get("equipment", {}).get("camera", "Canon EOS R5")}, {scene_types.get("portrait_studio", {}).get("equipment", {}).get("lens", "85mm f/1.4")}, Settings: {scene_types.get("portrait_studio", {}).get("camera_settings", {}).get("mode", "AV/A")}, {scene_types.get("portrait_studio", {}).get("camera_settings", {}).get("aperture", "f/2.8")}, {scene_types.get("portrait_studio", {}).get("camera_settings", {}).get("iso", "100-400")}
|
| 169 |
-
|
| 170 |
-
Street Photography: Equipment: {scene_types.get("street_photography", {}).get("equipment", {}).get("camera", "Leica M11")}, {scene_types.get("street_photography", {}).get("equipment", {}).get("lens", "35mm f/1.4")}, Settings: {scene_types.get("street_photography", {}).get("camera_settings", {}).get("mode", "TV/S or Program")}, {scene_types.get("street_photography", {}).get("camera_settings", {}).get("aperture", "f/5.6-f/8")}, {scene_types.get("street_photography", {}).get("camera_settings", {}).get("iso", "400-1600")}
|
| 171 |
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
Architecture: Equipment: {scene_types.get("architecture", {}).get("equipment", {}).get("camera", "Canon EOS R5")}, {scene_types.get("architecture", {}).get("equipment", {}).get("lens", "24-70mm f/2.8")}, Settings: {scene_types.get("architecture", {}).get("camera_settings", {}).get("mode", "AV/A")}, {scene_types.get("architecture", {}).get("camera_settings", {}).get("aperture", "f/8-f/11")}, {scene_types.get("architecture", {}).get("camera_settings", {}).get("iso", "100-400")}
|
| 175 |
-
|
| 176 |
-
Action Sports: Equipment: {scene_types.get("action_sports", {}).get("equipment", {}).get("camera", "Sony A1")}, {scene_types.get("action_sports", {}).get("equipment", {}).get("lens", "70-200mm f/2.8")}, Settings: {scene_types.get("action_sports", {}).get("camera_settings", {}).get("mode", "TV/S")}, {scene_types.get("action_sports", {}).get("camera_settings", {}).get("aperture", "f/2.8-f/4")}, {scene_types.get("action_sports", {}).get("camera_settings", {}).get("iso", "800-3200")}
|
| 177 |
-
|
| 178 |
-
Apply complete professional cinematography knowledge to generate concise, technically accurate prompt for cinema-quality generation."""
|
| 179 |
-
|
| 180 |
-
return prompt
|
| 181 |
-
|
| 182 |
-
def _build_flux_prompt(self, knowledge: Dict[str, Any]) -> str:
|
| 183 |
-
"""Build FLUX-optimized prompt with complete professional knowledge"""
|
| 184 |
-
|
| 185 |
-
camera_angles = knowledge.get('camera_angles', {})
|
| 186 |
-
lighting_situations = knowledge.get('lighting_situations', {})
|
| 187 |
-
composition_rules = knowledge.get('composition_rules', {})
|
| 188 |
-
scene_types = knowledge.get('scene_types', {})
|
| 189 |
-
camera_modes = knowledge.get('camera_modes', {})
|
| 190 |
-
|
| 191 |
-
prompt = f"""Analyze this image for FLUX prompt generation using complete professional photography expertise. Apply the full knowledge base for photorealistic output. Provide exactly two sections:
|
| 192 |
-
|
| 193 |
-
1. DESCRIPTION: Professional technical analysis using complete photography framework:
|
| 194 |
-
|
| 195 |
-
CAMERA ANGLES - Identify specific angle and apply professional knowledge:
|
| 196 |
-
• Eye Level: {camera_angles.get("eye_level_normal", {}).get("description", "Eye level normal")} - {camera_angles.get("eye_level_normal", {}).get("effect", "neutral perspective")}, best for: {camera_angles.get("eye_level_normal", {}).get("best_for", "portraits, documentary")}
|
| 197 |
-
• Low Angle: {camera_angles.get("low_angle_worms_eye", {}).get("description", "Low angle worms eye")} - {camera_angles.get("low_angle_worms_eye", {}).get("effect", "subject appears larger")}, best for: {camera_angles.get("low_angle_worms_eye", {}).get("best_for", "architecture, powerful portraits")}
|
| 198 |
-
• High Angle: {camera_angles.get("high_angle_birds_eye", {}).get("description", "High angle birds eye")} - {camera_angles.get("high_angle_birds_eye", {}).get("effect", "subject appears smaller")}, best for: {camera_angles.get("high_angle_birds_eye", {}).get("best_for", "environmental context, patterns")}
|
| 199 |
-
|
| 200 |
-
LIGHTING SITUATIONS - Match to appropriate lighting condition:
|
| 201 |
-
• Bright Daylight: ISO {lighting_situations.get("bright_daylight", {}).get("iso", "100-200")} - challenge: {lighting_situations.get("bright_daylight", {}).get("challenge", "harsh shadows")}, solutions: use reflectors, find open shade
|
| 202 |
-
• Overcast Day: ISO {lighting_situations.get("overcast_day", {}).get("iso", "200-400")} - {lighting_situations.get("overcast_day", {}).get("characteristics", "soft, even light but dimmer")}, advantage: {lighting_situations.get("overcast_day", {}).get("advantage", "natural diffusion")}
|
| 203 |
-
• Indoor Natural: ISO {lighting_situations.get("indoor_natural_light", {}).get("iso", "800-1600")} - {lighting_situations.get("indoor_natural_light", {}).get("window_light", "excellent for portraits")}, technique: {lighting_situations.get("indoor_natural_light", {}).get("technique", "position subject relative to window")}
|
| 204 |
-
• Low Light: ISO {lighting_situations.get("low_light_available", {}).get("iso", "1600-6400")} - {lighting_situations.get("low_light_available", {}).get("stabilization", "essential for sharp images")}, technique: {lighting_situations.get("low_light_available", {}).get("technique", "wider apertures, slower movements")}
|
| 205 |
-
|
| 206 |
-
COMPOSITION APPLICATION - Apply these specific rules:
|
| 207 |
-
• Rule of Thirds: {composition_rules.get("rule_of_thirds", {}).get("principle", "Divide frame into 9 equal sections")} - {composition_rules.get("rule_of_thirds", {}).get("subject_placement", "eyes on upper third line for portraits")}, {composition_rules.get("rule_of_thirds", {}).get("horizon_placement", "upper or lower third for landscapes")}
|
| 208 |
-
• Leading Lines: {composition_rules.get("leading_lines", {}).get("purpose", "Guide viewer's eye through the image")} - technique: {composition_rules.get("leading_lines", {}).get("technique", "use lines to lead to main subject")}
|
| 209 |
-
• Depth Layers: {composition_rules.get("depth_layers", {}).get("technique", "Create separation between layers")} - {composition_rules.get("depth_layers", {}).get("foreground", "Nearest elements")}, {composition_rules.get("depth_layers", {}).get("middle_ground", "Main subject area")}, {composition_rules.get("depth_layers", {}).get("background", "Context and environment")}
|
| 210 |
-
|
| 211 |
-
2. CAMERA_SETUP: Apply complete professional equipment knowledge:
|
| 212 |
|
| 213 |
-
|
| 214 |
-
Portrait Studio: Equipment: {scene_types.get("portrait_studio", {}).get("equipment", {}).get("camera", "Canon EOS R5")}, {scene_types.get("portrait_studio", {}).get("equipment", {}).get("lens", "85mm f/1.4")}, Camera settings: {scene_types.get("portrait_studio", {}).get("camera_settings", {}).get("mode", "AV/A")}, {scene_types.get("portrait_studio", {}).get("camera_settings", {}).get("aperture", "f/2.8")}, {scene_types.get("portrait_studio", {}).get("camera_settings", {}).get("iso", "100-400")}, Focus: {scene_types.get("portrait_studio", {}).get("camera_settings", {}).get("focus", "single point AF on eyes")}
|
| 215 |
|
| 216 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 217 |
|
| 218 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
|
| 220 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 221 |
|
| 222 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
|
| 224 |
-
|
| 225 |
|
| 226 |
-
|
| 227 |
-
• Aperture Priority: {camera_modes.get("aperture_priority", {}).get("mode_designation", "AV (Canon) / A (Nikon)")} - photographer sets {camera_modes.get("aperture_priority", {}).get("photographer_sets", "aperture value")}, camera sets {camera_modes.get("aperture_priority", {}).get("camera_sets", "shutter speed")}, best for: {camera_modes.get("aperture_priority", {}).get("best_for", "controlling depth of field")}
|
| 228 |
-
• Shutter Priority: {camera_modes.get("shutter_priority", {}).get("mode_designation", "TV (Canon) / S (Nikon)")} - photographer sets {camera_modes.get("shutter_priority", {}).get("photographer_sets", "shutter speed")}, camera sets {camera_modes.get("shutter_priority", {}).get("camera_sets", "aperture")}, best for: {camera_modes.get("shutter_priority", {}).get("best_for", "controlling motion")}
|
| 229 |
-
• Manual Mode: {camera_modes.get("manual_mode", {}).get("photographer_sets", "Both aperture and shutter speed")} - when to use: consistent lighting, studio work, advantage: {camera_modes.get("manual_mode", {}).get("advantage", "complete creative control")}
|
| 230 |
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
|
|
|
|
|
|
| 234 |
|
| 235 |
-
|
| 236 |
-
"""Build multimodal analysis prompt with complete professional knowledge"""
|
| 237 |
-
|
| 238 |
-
prompt = """Analyze this image with professional cinematography expertise for multi-platform prompt generation. You are a master cinematographer with extensive technical and artistic knowledge from 30+ years in cinema. Provide exactly two sections:
|
| 239 |
-
|
| 240 |
-
1. DESCRIPTION: Expert visual analysis for prompt generation:
|
| 241 |
-
- Comprehensive scene description with photographic insight
|
| 242 |
-
- Subject matter, composition, and visual hierarchy
|
| 243 |
-
- Lighting analysis: quality, direction, mood, technical setup
|
| 244 |
-
- Color palette, contrast, and tonal relationships
|
| 245 |
-
- Artistic elements: style, mood, atmosphere, visual impact
|
| 246 |
-
- Technical photographic qualities and execution
|
| 247 |
-
|
| 248 |
-
2. CAMERA_SETUP: Professional equipment and technique recommendation:
|
| 249 |
-
- Camera system recommendation based on scene requirements
|
| 250 |
-
- Lens selection with specific focal length and aperture range
|
| 251 |
-
- Technical shooting parameters and considerations
|
| 252 |
-
- Lighting setup and methodology for scene recreation
|
| 253 |
-
- Professional approach: shooting style and technical execution
|
| 254 |
-
|
| 255 |
-
Apply master-level cinematography knowledge: advanced composition techniques, professional lighting principles, camera system expertise, lens characteristics, and technical excellence. Create content suitable for multiple generative engines (Flux, Midjourney, etc.) with emphasis on photorealistic quality."""
|
| 256 |
-
|
| 257 |
-
return prompt
|
| 258 |
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
if analysis_type == "cinematic":
|
| 263 |
-
return """Analyze this image as a professional cinematographer. Provide exactly two sections:
|
| 264 |
-
|
| 265 |
-
1. DESCRIPTION: Create a detailed, flowing paragraph describing the image for cinematic reproduction:
|
| 266 |
-
- Scene composition and visual storytelling elements
|
| 267 |
-
- Lighting quality, direction, and dramatic mood
|
| 268 |
-
- Color palette, tonal relationships, and atmospheric elements
|
| 269 |
-
- Subject positioning, environmental context, and framing
|
| 270 |
-
- Cinematic qualities: film grain, depth of field, visual style
|
| 271 |
-
- Technical photographic elements that enhance realism
|
| 272 |
-
|
| 273 |
-
2. CAMERA_SETUP: Recommend professional cinema/photography equipment based on scene analysis:
|
| 274 |
-
- Camera body: Choose from Canon EOS R5/R6, Sony A7R/A1, Leica M11, ARRI Alexa, RED cameras
|
| 275 |
-
- Lens: Specific focal length and aperture (e.g., "85mm f/1.4", "35mm anamorphic f/2.8")
|
| 276 |
-
- Technical settings: Aperture consideration for depth of field and story mood
|
| 277 |
-
- Lighting setup: Professional lighting rationale (key, fill, rim, practical lights)
|
| 278 |
-
- Shooting style: Documentary, portrait, landscape, architectural, or cinematic approach
|
| 279 |
|
| 280 |
-
|
| 281 |
|
| 282 |
-
|
| 283 |
-
return """Analyze this image for FLUX prompt generation with professional cinematography expertise. Provide exactly two sections:
|
| 284 |
|
| 285 |
-
|
| 286 |
-
- Scene elements and composition with precise technical language
|
| 287 |
-
- Lighting setup and quality with specific technical terms
|
| 288 |
-
- Camera angle and perspective with professional terminology
|
| 289 |
-
- Color grading and tonal balance for photorealistic output
|
| 290 |
-
- Depth of field and focus characteristics
|
| 291 |
-
- Professional photographic style and execution
|
| 292 |
|
| 293 |
-
|
| 294 |
-
- Professional camera body with model specifications
|
| 295 |
-
- Lens specifications with focal length and aperture
|
| 296 |
-
- ISO settings and technical parameters
|
| 297 |
-
- Professional lighting setup and rationale
|
| 298 |
-
- Shooting technique and professional approach
|
| 299 |
|
| 300 |
-
|
| 301 |
|
| 302 |
-
|
| 303 |
-
return """Analyze this image with professional cinematography expertise for multi-platform prompt generation. Provide exactly two sections:
|
| 304 |
|
| 305 |
-
|
| 306 |
-
- Comprehensive scene description with photographic insight
|
| 307 |
-
- Subject matter, composition, and visual hierarchy
|
| 308 |
-
- Lighting analysis: quality, direction, mood, technical setup
|
| 309 |
-
- Color palette, contrast, and tonal relationships
|
| 310 |
-
- Artistic elements: style, mood, atmosphere, visual impact
|
| 311 |
-
- Technical photographic qualities and execution
|
| 312 |
|
| 313 |
-
|
| 314 |
-
-
|
| 315 |
-
-
|
| 316 |
-
-
|
| 317 |
-
-
|
| 318 |
-
-
|
| 319 |
|
| 320 |
-
|
| 321 |
|
| 322 |
def _extract_professional_camera_setup(self, description: str) -> Optional[str]:
|
| 323 |
"""Extract and enhance camera setup with professional photography knowledge"""
|
|
@@ -329,138 +218,54 @@ Apply master-level cinematography knowledge: advanced composition techniques, pr
|
|
| 329 |
parts = description.split("CAMERA_SETUP:")
|
| 330 |
if len(parts) > 1:
|
| 331 |
camera_section = parts[1].strip()
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 335 |
|
| 336 |
elif "2. CAMERA_SETUP" in description:
|
| 337 |
parts = description.split("2. CAMERA_SETUP")
|
| 338 |
if len(parts) > 1:
|
| 339 |
camera_section = parts[1].strip()
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
|
| 346 |
-
camera_setup = self._find_professional_camera_recommendation(description)
|
| 347 |
-
|
| 348 |
-
return camera_setup
|
| 349 |
-
|
| 350 |
-
except Exception as e:
|
| 351 |
-
logger.warning(f"Failed to extract professional camera setup: {e}")
|
| 352 |
-
return None
|
| 353 |
-
|
| 354 |
-
def _parse_professional_camera_recommendation(self, camera_text: str) -> Optional[str]:
|
| 355 |
-
"""Parse camera recommendation with professional photography enhancement"""
|
| 356 |
-
try:
|
| 357 |
-
# Clean and extract with professional patterns
|
| 358 |
-
camera_text = re.sub(r'^(Based on.*?recommend|I would recommend|For this.*?recommend)\s*', '', camera_text, flags=re.IGNORECASE)
|
| 359 |
-
|
| 360 |
-
# Professional camera patterns (more comprehensive)
|
| 361 |
-
camera_patterns = [
|
| 362 |
-
r'(Canon EOS R[^\s,]*(?:\s+[^\s,]*)?)',
|
| 363 |
-
r'(Sony A[^\s,]*(?:\s+[^\s,]*)?)',
|
| 364 |
-
r'(Leica [^\s,]+)',
|
| 365 |
-
r'(Hasselblad [^\s,]+)',
|
| 366 |
-
r'(Phase One [^\s,]+)',
|
| 367 |
-
r'(Fujifilm [^\s,]+)',
|
| 368 |
-
r'(ARRI [^\s,]+)',
|
| 369 |
-
r'(RED [^\s,]+)',
|
| 370 |
-
r'(Nikon [^\s,]+)'
|
| 371 |
-
]
|
| 372 |
|
| 373 |
-
|
| 374 |
-
|
| 375 |
-
|
| 376 |
-
if match:
|
| 377 |
-
camera_model = match.group(1).strip()
|
| 378 |
-
break
|
| 379 |
-
|
| 380 |
-
# Professional lens patterns (enhanced)
|
| 381 |
-
lens_patterns = [
|
| 382 |
-
r'(\d+mm\s*f/[\d.]+(?:\s*(?:lens|anamorphic|telephoto|wide))?)',
|
| 383 |
-
r'(\d+-\d+mm\s*f/[\d.]+(?:\s*lens)?)',
|
| 384 |
-
r'(with\s+(?:a\s+)?(\d+mm[^,.]*))',
|
| 385 |
-
r'(paired with.*?(\d+mm[^,.]*))',
|
| 386 |
-
r'(\d+mm[^,]*anamorphic[^,]*)',
|
| 387 |
-
r'(\d+mm[^,]*telephoto[^,]*)'
|
| 388 |
-
]
|
| 389 |
-
|
| 390 |
-
lens_info = None
|
| 391 |
-
for pattern in lens_patterns:
|
| 392 |
-
match = re.search(pattern, camera_text, re.IGNORECASE)
|
| 393 |
-
if match:
|
| 394 |
-
lens_info = match.group(1).strip()
|
| 395 |
-
lens_info = re.sub(r'^(with\s+(?:a\s+)?|paired with\s+)', '', lens_info, flags=re.IGNORECASE)
|
| 396 |
-
break
|
| 397 |
-
|
| 398 |
-
# Build professional recommendation
|
| 399 |
-
parts = []
|
| 400 |
-
if camera_model:
|
| 401 |
-
parts.append(camera_model)
|
| 402 |
-
if lens_info:
|
| 403 |
-
parts.append(lens_info)
|
| 404 |
-
|
| 405 |
-
if parts:
|
| 406 |
-
result = ', '.join(parts)
|
| 407 |
-
logger.info(f"Professional camera setup extracted: {result}")
|
| 408 |
-
return result
|
| 409 |
-
|
| 410 |
-
return None
|
| 411 |
-
|
| 412 |
-
except Exception as e:
|
| 413 |
-
logger.warning(f"Failed to parse professional camera recommendation: {e}")
|
| 414 |
-
return None
|
| 415 |
-
|
| 416 |
-
def _find_professional_camera_recommendation(self, text: str) -> Optional[str]:
|
| 417 |
-
"""Find professional camera recommendations with enhanced detection"""
|
| 418 |
-
try:
|
| 419 |
-
sentences = re.split(r'[.!?]', text)
|
| 420 |
-
|
| 421 |
-
for sentence in sentences:
|
| 422 |
-
# Professional camera brands and technical terms
|
| 423 |
-
if any(brand in sentence.lower() for brand in ['canon', 'sony', 'leica', 'hasselblad', 'phase one', 'fujifilm', 'arri', 'red']):
|
| 424 |
-
if any(term in sentence.lower() for term in ['recommend', 'suggest', 'would use', 'camera', 'lens', 'shot on']):
|
| 425 |
-
parsed = self._parse_professional_camera_recommendation(sentence.strip())
|
| 426 |
-
if parsed:
|
| 427 |
-
return parsed
|
| 428 |
|
| 429 |
return None
|
| 430 |
|
| 431 |
except Exception as e:
|
| 432 |
-
logger.warning(f"Failed to
|
| 433 |
return None
|
| 434 |
|
| 435 |
-
def
|
| 436 |
-
"""
|
| 437 |
try:
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
|
| 441 |
-
# Get professional cinematography context without being invasive
|
| 442 |
-
enhanced_context = self.professional_analyzer.generate_enhanced_context(description)
|
| 443 |
|
| 444 |
-
#
|
| 445 |
-
|
| 446 |
-
technical_context = enhanced_context.get("technical_context", "")
|
| 447 |
-
professional_insight = enhanced_context.get("professional_insight", "")
|
| 448 |
|
| 449 |
-
#
|
| 450 |
-
|
|
|
|
| 451 |
|
| 452 |
-
|
| 453 |
-
if technical_context and len(technical_context) > 20:
|
| 454 |
-
# Only add if it doesn't duplicate existing information
|
| 455 |
-
if not any(term in description.lower() for term in ["shot on", "professional", "camera"]):
|
| 456 |
-
enhanced_description += f"\n\nProfessional Context: {technical_context}"
|
| 457 |
-
|
| 458 |
-
logger.info(f"Enhanced description with cinematography context for {scene_type} scene")
|
| 459 |
-
return enhanced_description
|
| 460 |
|
| 461 |
except Exception as e:
|
| 462 |
-
logger.warning(f"
|
| 463 |
-
return
|
| 464 |
|
| 465 |
def _save_temp_image(self, image: Image.Image) -> str:
|
| 466 |
"""Save image to temporary file for API call"""
|
|
@@ -517,7 +322,7 @@ Apply master-level cinematography knowledge: advanced composition techniques, pr
|
|
| 517 |
if not temp_path:
|
| 518 |
return "Image processing failed", {"error": "Could not save image"}
|
| 519 |
|
| 520 |
-
logger.info("Calling BAGEL API with professional cinematography
|
| 521 |
|
| 522 |
# Call BAGEL API with enhanced prompt
|
| 523 |
result = self.client.predict(
|
|
@@ -547,15 +352,13 @@ Apply master-level cinematography knowledge: advanced composition techniques, pr
|
|
| 547 |
logger.info(f"Professional camera setup extracted: {camera_setup}")
|
| 548 |
else:
|
| 549 |
metadata["has_camera_suggestion"] = False
|
| 550 |
-
logger.info("No camera setup found
|
| 551 |
|
| 552 |
-
#
|
| 553 |
-
|
| 554 |
-
description = self._enhance_description_with_professional_context(description, image)
|
| 555 |
-
metadata["cinematography_context_applied"] = True
|
| 556 |
|
| 557 |
else:
|
| 558 |
-
description = "Professional
|
| 559 |
metadata["has_camera_suggestion"] = False
|
| 560 |
|
| 561 |
# Update metadata
|
|
@@ -620,32 +423,25 @@ class FallbackAnalyzer(BaseImageAnalyzer):
|
|
| 620 |
mode = image.mode
|
| 621 |
aspect_ratio = width / height
|
| 622 |
|
| 623 |
-
# Enhanced scene detection
|
| 624 |
if aspect_ratio > 1.5:
|
| 625 |
orientation = "landscape"
|
| 626 |
scene_type = "landscape"
|
| 627 |
-
|
|
|
|
| 628 |
elif aspect_ratio < 0.75:
|
| 629 |
orientation = "portrait"
|
| 630 |
scene_type = "portrait_studio"
|
| 631 |
-
|
|
|
|
| 632 |
else:
|
| 633 |
orientation = "square"
|
| 634 |
scene_type = "general"
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
# Generate professional description
|
| 638 |
-
description = f"A {orientation} format professional photograph with balanced composition and technical excellence. The image demonstrates clear visual hierarchy and professional execution, suitable for high-quality reproduction across multiple generative platforms. Recommended professional setup: {camera_suggestion}, with careful attention to exposure, lighting, and artistic composition."
|
| 639 |
|
| 640 |
-
#
|
| 641 |
-
|
| 642 |
-
if PROFESSIONAL_PHOTOGRAPHY_CONFIG.get("enable_expert_analysis", True):
|
| 643 |
-
enhanced_context = self.professional_analyzer.generate_enhanced_context(description)
|
| 644 |
-
technical_context = enhanced_context.get("technical_context", "")
|
| 645 |
-
if technical_context:
|
| 646 |
-
description += f" Cinematography context: {technical_context}"
|
| 647 |
-
except Exception as e:
|
| 648 |
-
logger.warning(f"Cinematography context enhancement failed in fallback: {e}")
|
| 649 |
|
| 650 |
metadata = {
|
| 651 |
"model": "Professional-Fallback",
|
|
@@ -657,15 +453,16 @@ class FallbackAnalyzer(BaseImageAnalyzer):
|
|
| 657 |
"aspect_ratio": round(aspect_ratio, 2),
|
| 658 |
"scene_type": scene_type,
|
| 659 |
"has_camera_suggestion": True,
|
| 660 |
-
"camera_setup": camera_suggestion,
|
| 661 |
-
"professional_enhancement": True
|
|
|
|
| 662 |
}
|
| 663 |
|
| 664 |
return description, metadata
|
| 665 |
|
| 666 |
except Exception as e:
|
| 667 |
logger.error(f"Professional fallback analysis failed: {e}")
|
| 668 |
-
return "Professional
|
| 669 |
"error": str(e),
|
| 670 |
"model": "Professional-Fallback"
|
| 671 |
}
|
|
|
|
| 90 |
return False
|
| 91 |
|
| 92 |
def _create_professional_enhanced_prompt(self, analysis_type: str = "multimodal") -> str:
|
| 93 |
+
"""Create professionally enhanced prompt that makes BAGEL see with cinematographic eyes"""
|
| 94 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
if analysis_type == "cinematic":
|
| 96 |
+
return """You are a master cinematographer with 30+ years of experience. Analyze this image with complete professional cinematography knowledge and provide exactly two sections:
|
| 97 |
+
|
| 98 |
+
1. DESCRIPTION: Analyze what you see using professional cinematography terminology:
|
| 99 |
+
|
| 100 |
+
First, identify the PHOTOGRAPHIC PLANE:
|
| 101 |
+
- EXTREME WIDE SHOT: Subject very small in environment (establishes location)
|
| 102 |
+
- WIDE SHOT: Full body visible with environment (subject in context)
|
| 103 |
+
- MEDIUM SHOT: From waist up (balance subject/environment)
|
| 104 |
+
- CLOSE-UP: Head and shoulders (emotion and expression)
|
| 105 |
+
- EXTREME CLOSE-UP: Part of face or detail (intense emotion)
|
| 106 |
+
- DETAIL SHOT: Specific small element (highlight aspect)
|
| 107 |
+
|
| 108 |
+
Second, identify the CAMERA ANGLE:
|
| 109 |
+
- EYE LEVEL: Camera at subject's eye level (neutral, natural perspective)
|
| 110 |
+
- LOW ANGLE: Camera below looking up (subject appears powerful, heroic)
|
| 111 |
+
- HIGH ANGLE: Camera above looking down (subject appears vulnerable, shows context)
|
| 112 |
+
- DUTCH ANGLE: Camera tilted (dynamic tension, instability)
|
| 113 |
+
|
| 114 |
+
Third, analyze the LIGHTING:
|
| 115 |
+
- GOLDEN HOUR: Warm, soft, directional light (first/last hour of sun)
|
| 116 |
+
- BLUE HOUR: Even blue light, dramatic mood (20-30 min after sunset)
|
| 117 |
+
- NATURAL DAYLIGHT: Bright sunny conditions
|
| 118 |
+
- SOFT NATURAL: Overcast, diffused, even light
|
| 119 |
+
- DRAMATIC: High contrast, moody shadows
|
| 120 |
+
- STUDIO: Controlled professional lighting
|
| 121 |
+
|
| 122 |
+
Fourth, identify COMPOSITION:
|
| 123 |
+
- RULE OF THIRDS: Key elements on intersection points
|
| 124 |
+
- LEADING LINES: Lines guide viewer's eye to subject
|
| 125 |
+
- SYMMETRICAL: Mirror-like balance
|
| 126 |
+
- CENTERED: Subject in middle for impact
|
| 127 |
+
- DEPTH LAYERS: Foreground, middle ground, background separation
|
| 128 |
+
|
| 129 |
+
Now describe the scene combining all these professional elements in flowing descriptive language.
|
| 130 |
+
|
| 131 |
+
2. CAMERA_SETUP: Recommend specific professional equipment based on your analysis:
|
| 132 |
+
|
| 133 |
+
For PORTRAIT scenes: Canon EOS R5, 85mm f/1.4 lens, f/2.8, ISO 200, single point AF on eyes
|
| 134 |
+
For LANDSCAPE scenes: Phase One XT, 24-70mm f/4 lens, f/8-f/11, ISO 100, hyperfocal distance
|
| 135 |
+
For STREET scenes: Leica M11, 35mm f/1.4 lens, f/5.6-f/8, ISO 400-1600, zone focusing
|
| 136 |
+
For ARCHITECTURE: Canon EOS R5, 24-70mm f/2.8 lens, f/8-f/11, ISO 100, tilt-shift correction
|
| 137 |
+
For ACTION: Sony A1, 70-200mm f/2.8 lens, f/2.8-f/4, ISO 800-3200, continuous AF tracking
|
| 138 |
+
|
| 139 |
+
Apply your complete professional cinematography knowledge to see this image as a master would."""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
|
| 141 |
+
elif analysis_type == "flux_optimized":
|
| 142 |
+
return """You are a professional cinematographer analyzing this image for photorealistic prompt generation. Use complete technical knowledge and provide exactly two sections:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
|
| 144 |
+
1. DESCRIPTION: Technical cinematographic analysis:
|
|
|
|
| 145 |
|
| 146 |
+
PHOTOGRAPHIC PLANE (choose one):
|
| 147 |
+
- Wide shot: Full subject visible with environment
|
| 148 |
+
- Medium shot: Waist up, balanced composition
|
| 149 |
+
- Close-up: Head and shoulders, tight framing
|
| 150 |
+
- Extreme close-up: Facial details or specific elements
|
| 151 |
+
- Detail shot: Small specific elements highlighted
|
| 152 |
|
| 153 |
+
CAMERA ANGLE (identify):
|
| 154 |
+
- Eye level: Natural, relatable perspective
|
| 155 |
+
- Low angle: Looking up, subject appears powerful
|
| 156 |
+
- High angle: Looking down, shows vulnerability/context
|
| 157 |
+
- Dutch angle: Tilted, creates dynamic tension
|
| 158 |
|
| 159 |
+
LIGHTING TYPE (analyze):
|
| 160 |
+
- Golden hour: Warm, soft directional light
|
| 161 |
+
- Natural daylight: Bright outdoor conditions
|
| 162 |
+
- Soft natural: Overcast, even diffusion
|
| 163 |
+
- Dramatic: High contrast, moody shadows
|
| 164 |
+
- Blue hour: Even twilight, dramatic mood
|
| 165 |
|
| 166 |
+
COMPOSITION TECHNIQUE (apply):
|
| 167 |
+
- Rule of thirds: Subject on intersection points
|
| 168 |
+
- Leading lines: Elements guide eye to subject
|
| 169 |
+
- Symmetrical: Balanced mirror composition
|
| 170 |
+
- Centered: Subject middle for impact
|
| 171 |
+
- Dynamic: Diagonal elements, movement
|
| 172 |
|
| 173 |
+
Describe the scene using these professional cinematography elements in precise technical language.
|
| 174 |
|
| 175 |
+
2. CAMERA_SETUP: Professional equipment recommendation:
|
|
|
|
|
|
|
|
|
|
| 176 |
|
| 177 |
+
PORTRAIT SETUP: Canon EOS R5 with 85mm f/1.4 lens at f/2.8, ISO 200, rule of thirds composition
|
| 178 |
+
LANDSCAPE SETUP: Phase One XT with 24-70mm f/4 lens at f/8, ISO 100, hyperfocal distance focus
|
| 179 |
+
STREET SETUP: Leica M11 with 35mm f/1.4 lens at f/5.6, ISO 800, zone focusing technique
|
| 180 |
+
ARCHITECTURE SETUP: Canon EOS R5 with 24-70mm f/2.8 lens at f/11, ISO 100, perspective correction
|
| 181 |
+
ACTION SETUP: Sony A1 with 70-200mm f/2.8 lens at f/4, ISO 1600, continuous AF tracking
|
| 182 |
|
| 183 |
+
Choose the setup that matches your scene analysis and provide complete technical specifications."""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
|
| 185 |
+
else: # multimodal analysis
|
| 186 |
+
return """You are a master cinematographer with decades of professional experience. Analyze this image using complete cinematography knowledge and provide exactly two sections:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
|
| 188 |
+
1. DESCRIPTION: Professional cinematographic analysis combining:
|
| 189 |
|
| 190 |
+
PHOTOGRAPHIC PLANES: Identify if this is a wide shot (full subject with environment), medium shot (waist up), close-up (head/shoulders), extreme close-up (facial details), or detail shot (specific elements).
|
|
|
|
| 191 |
|
| 192 |
+
CAMERA ANGLES: Determine if shot from eye level (natural perspective), low angle (looking up, powerful), high angle (looking down, vulnerable), or dutch angle (tilted, dynamic).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
|
| 194 |
+
LIGHTING ANALYSIS: Analyze if this is golden hour (warm directional), natural daylight (bright outdoor), soft natural (overcast even), dramatic (high contrast), blue hour (twilight mood), or studio (controlled).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
|
| 196 |
+
COMPOSITION: Identify rule of thirds (key elements on intersections), leading lines (guiding elements), symmetrical (balanced), centered (middle impact), or dynamic (diagonal movement).
|
| 197 |
|
| 198 |
+
Describe the complete scene using professional cinematography terminology in flowing descriptive language that captures all visual and technical elements.
|
|
|
|
| 199 |
|
| 200 |
+
2. CAMERA_SETUP: Professional equipment recommendation based on scene analysis:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
|
| 202 |
+
Choose from these professional setups:
|
| 203 |
+
- PORTRAIT: Canon EOS R5, 85mm f/1.4 lens, f/2.8, ISO 200
|
| 204 |
+
- LANDSCAPE: Phase One XT, 24-70mm f/4 lens, f/8, ISO 100
|
| 205 |
+
- STREET: Leica M11, 35mm f/1.4 lens, f/5.6, ISO 800
|
| 206 |
+
- ARCHITECTURE: Canon EOS R5, 24-70mm f/2.8 lens, f/11, ISO 100
|
| 207 |
+
- ACTION: Sony A1, 70-200mm f/2.8 lens, f/4, ISO 1600
|
| 208 |
|
| 209 |
+
Provide complete technical specifications matching your cinematographic analysis."""
|
| 210 |
|
| 211 |
def _extract_professional_camera_setup(self, description: str) -> Optional[str]:
|
| 212 |
"""Extract and enhance camera setup with professional photography knowledge"""
|
|
|
|
| 218 |
parts = description.split("CAMERA_SETUP:")
|
| 219 |
if len(parts) > 1:
|
| 220 |
camera_section = parts[1].strip()
|
| 221 |
+
# Take the first substantial line
|
| 222 |
+
lines = camera_section.split('\n')
|
| 223 |
+
for line in lines:
|
| 224 |
+
clean_line = line.strip()
|
| 225 |
+
if len(clean_line) > 20 and not clean_line.startswith('2.'):
|
| 226 |
+
camera_setup = clean_line
|
| 227 |
+
break
|
| 228 |
|
| 229 |
elif "2. CAMERA_SETUP" in description:
|
| 230 |
parts = description.split("2. CAMERA_SETUP")
|
| 231 |
if len(parts) > 1:
|
| 232 |
camera_section = parts[1].strip()
|
| 233 |
+
lines = camera_section.split('\n')
|
| 234 |
+
for line in lines:
|
| 235 |
+
clean_line = line.strip()
|
| 236 |
+
if len(clean_line) > 20:
|
| 237 |
+
camera_setup = clean_line
|
| 238 |
+
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 239 |
|
| 240 |
+
# Clean and format camera setup
|
| 241 |
+
if camera_setup:
|
| 242 |
+
return self._clean_camera_setup(camera_setup)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 243 |
|
| 244 |
return None
|
| 245 |
|
| 246 |
except Exception as e:
|
| 247 |
+
logger.warning(f"Failed to extract professional camera setup: {e}")
|
| 248 |
return None
|
| 249 |
|
| 250 |
+
def _clean_camera_setup(self, raw_setup: str) -> str:
|
| 251 |
+
"""Clean and format camera setup"""
|
| 252 |
try:
|
| 253 |
+
# Remove common prefixes
|
| 254 |
+
setup = re.sub(r'^(Based on.*?recommend|I would recommend|For this.*?setup)\s*:?\s*', '', raw_setup, flags=re.IGNORECASE)
|
| 255 |
+
setup = re.sub(r'^(CAMERA_SETUP:|2\.\s*CAMERA_SETUP:?)\s*', '', setup, flags=re.IGNORECASE)
|
|
|
|
|
|
|
| 256 |
|
| 257 |
+
# Clean up formatting
|
| 258 |
+
setup = re.sub(r'\s+', ' ', setup).strip()
|
|
|
|
|
|
|
| 259 |
|
| 260 |
+
# Ensure proper format
|
| 261 |
+
if setup and not setup.lower().startswith('shot on'):
|
| 262 |
+
setup = f"shot on {setup}"
|
| 263 |
|
| 264 |
+
return setup
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 265 |
|
| 266 |
except Exception as e:
|
| 267 |
+
logger.warning(f"Camera setup cleaning failed: {e}")
|
| 268 |
+
return raw_setup
|
| 269 |
|
| 270 |
def _save_temp_image(self, image: Image.Image) -> str:
|
| 271 |
"""Save image to temporary file for API call"""
|
|
|
|
| 322 |
if not temp_path:
|
| 323 |
return "Image processing failed", {"error": "Could not save image"}
|
| 324 |
|
| 325 |
+
logger.info("Calling BAGEL API with professional cinematography prompt...")
|
| 326 |
|
| 327 |
# Call BAGEL API with enhanced prompt
|
| 328 |
result = self.client.predict(
|
|
|
|
| 352 |
logger.info(f"Professional camera setup extracted: {camera_setup}")
|
| 353 |
else:
|
| 354 |
metadata["has_camera_suggestion"] = False
|
| 355 |
+
logger.info("No camera setup found in BAGEL response")
|
| 356 |
|
| 357 |
+
# Mark as cinematography enhanced
|
| 358 |
+
metadata["cinematography_context_applied"] = True
|
|
|
|
|
|
|
| 359 |
|
| 360 |
else:
|
| 361 |
+
description = "Professional cinematographic analysis completed"
|
| 362 |
metadata["has_camera_suggestion"] = False
|
| 363 |
|
| 364 |
# Update metadata
|
|
|
|
| 423 |
mode = image.mode
|
| 424 |
aspect_ratio = width / height
|
| 425 |
|
| 426 |
+
# Enhanced scene detection with cinematographic analysis
|
| 427 |
if aspect_ratio > 1.5:
|
| 428 |
orientation = "landscape"
|
| 429 |
scene_type = "landscape"
|
| 430 |
+
plane = "Wide shot"
|
| 431 |
+
camera_suggestion = "Phase One XT with 24-70mm f/4 lens, f/8, ISO 100"
|
| 432 |
elif aspect_ratio < 0.75:
|
| 433 |
orientation = "portrait"
|
| 434 |
scene_type = "portrait_studio"
|
| 435 |
+
plane = "Close-up"
|
| 436 |
+
camera_suggestion = "Canon EOS R5 with 85mm f/1.4 lens, f/2.8, ISO 200"
|
| 437 |
else:
|
| 438 |
orientation = "square"
|
| 439 |
scene_type = "general"
|
| 440 |
+
plane = "Medium shot"
|
| 441 |
+
camera_suggestion = "Canon EOS R6 with 50mm f/1.8 lens, f/4, ISO 400"
|
|
|
|
|
|
|
| 442 |
|
| 443 |
+
# Generate professional cinematographic description
|
| 444 |
+
description = f"{plane} composition with balanced framing and professional execution, natural lighting with good contrast, rule of thirds composition, suitable for high-quality reproduction across multiple generative platforms"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 445 |
|
| 446 |
metadata = {
|
| 447 |
"model": "Professional-Fallback",
|
|
|
|
| 453 |
"aspect_ratio": round(aspect_ratio, 2),
|
| 454 |
"scene_type": scene_type,
|
| 455 |
"has_camera_suggestion": True,
|
| 456 |
+
"camera_setup": f"shot on {camera_suggestion}",
|
| 457 |
+
"professional_enhancement": True,
|
| 458 |
+
"cinematography_context_applied": True
|
| 459 |
}
|
| 460 |
|
| 461 |
return description, metadata
|
| 462 |
|
| 463 |
except Exception as e:
|
| 464 |
logger.error(f"Professional fallback analysis failed: {e}")
|
| 465 |
+
return "Professional cinematographic analysis with technical excellence", {
|
| 466 |
"error": str(e),
|
| 467 |
"model": "Professional-Fallback"
|
| 468 |
}
|