Spaces:
Running
on
Zero
Running
on
Zero
""" | |
Professional Photography Knowledge Base | |
Advanced camera settings, lighting, and composition rules from expert photography practice | |
Extracted from 30+ years of professional photography experience | |
""" | |
import re | |
from typing import Dict, List, Optional, Tuple, Any | |
# ===================================================== | |
# PARTE 1: CONFIGURACIONES BASE Y TIPOS DE ESCENA | |
# ===================================================== | |
EXPERT_PHOTOGRAPHY_KNOWLEDGE = { | |
# TIPOS DE ESCENA Y CONFIGURACIONES PROFESIONALES | |
"scene_types": { | |
"portrait_studio": { | |
"description": "Professional studio portrait photography", | |
"camera_settings": { | |
"mode": "AV/A", | |
"aperture": "f/2.8", | |
"iso": "100-400", | |
"focus": "single point AF on eyes", | |
"metering": "spot or center-weighted" | |
}, | |
"equipment": { | |
"camera": "Canon EOS R5", | |
"lens": "85mm f/1.4", | |
"alternative_lens": "105mm f/2.8" | |
}, | |
"lighting": { | |
"primary": "3-point studio lighting setup", | |
"key_light": "large softbox at 45 degrees", | |
"fill_light": "reflector or secondary softbox", | |
"rim_light": "subtle rim light for separation" | |
}, | |
"composition": [ | |
"rule of thirds for eye placement", | |
"shallow depth of field to isolate subject", | |
"focus on nearest eye for sharpness", | |
"leave breathing room in frame direction" | |
] | |
}, | |
"portrait_exterior": { | |
"description": "Natural light outdoor portrait photography", | |
"camera_settings": { | |
"mode": "AV/A", | |
"aperture": "f/2.8-f/4", | |
"iso": "100-800", | |
"focus": "continuous AF for moving subjects", | |
"exposure_compensation": "+0.3 to +0.7 for faces" | |
}, | |
"equipment": { | |
"camera": "Canon EOS R6", | |
"lens": "85mm f/1.4", | |
"alternative_lens": "70-200mm f/2.8" | |
}, | |
"lighting": { | |
"preferred": "soft natural light", | |
"golden_hour": "best for warm, flattering light", | |
"overcast": "natural diffusion, even lighting", | |
"open_shade": "avoid harsh direct sunlight", | |
"reflector": "use to fill shadows when needed" | |
}, | |
"composition": [ | |
"environmental context for storytelling", | |
"rule of thirds with subject placement", | |
"watch background for distractions", | |
"use natural leading lines" | |
] | |
}, | |
"street_photography": { | |
"description": "Spontaneous urban and documentary photography", | |
"camera_settings": { | |
"mode": "TV/S or Program", | |
"shutter_speed": "1/125s minimum for sharp subjects", | |
"aperture": "f/5.6-f/8 for sufficient depth of field", | |
"iso": "400-1600 adaptive to lighting", | |
"focus": "zone focusing or continuous AF" | |
}, | |
"equipment": { | |
"camera": "Leica M11", | |
"lens": "35mm f/1.4", | |
"alternative_lens": "50mm f/2.8" | |
}, | |
"lighting": { | |
"available_light": "work with existing conditions", | |
"dramatic_contrast": "use shadows and highlights", | |
"window_light": "exploit urban light sources", | |
"golden_hour": "warm street lighting mix" | |
}, | |
"composition": [ | |
"anticipation of decisive moments", | |
"rule of Z for visual flow", | |
"layered composition with depth", | |
"leading lines from urban architecture", | |
"respect distance and privacy" | |
] | |
}, | |
"landscape": { | |
"description": "Natural landscape and scenic photography", | |
"camera_settings": { | |
"mode": "AV/A or Manual", | |
"aperture": "f/8-f/11 for maximum sharpness", | |
"iso": "100-400 for lowest noise", | |
"focus": "hyperfocal distance or infinity", | |
"exposure": "often requires bracketing" | |
}, | |
"equipment": { | |
"camera": "Phase One XT", | |
"lens": "24-70mm f/4", | |
"wide_alternative": "16-35mm f/2.8", | |
"telephoto_alternative": "70-200mm f/4" | |
}, | |
"lighting": { | |
"golden_hour": "optimal warm light", | |
"blue_hour": "dramatic twilight colors", | |
"overcast": "even light for forests/waterfalls", | |
"side_lighting": "enhance texture and depth" | |
}, | |
"composition": [ | |
"rule of thirds for horizon placement", | |
"foreground, middle ground, background layers", | |
"leading lines from natural features", | |
"point of interest as focal anchor", | |
"patience for optimal light conditions" | |
] | |
}, | |
"architecture": { | |
"description": "Building and structural photography", | |
"camera_settings": { | |
"mode": "AV/A", | |
"aperture": "f/8-f/11 for sharp details", | |
"iso": "100-400", | |
"focus": "single point AF on key details", | |
"perspective_correction": "use tilt-shift when available" | |
}, | |
"equipment": { | |
"camera": "Canon EOS R5", | |
"lens": "24-70mm f/2.8", | |
"wide_lens": "16-35mm f/2.8", | |
"tilt_shift": "24mm f/3.5 TS-E for correction" | |
}, | |
"lighting": { | |
"side_lighting": "reveal texture and form", | |
"golden_hour": "warm light on facades", | |
"blue_hour": "interior lights vs exterior", | |
"overcast": "even light for details" | |
}, | |
"composition": [ | |
"strong geometric lines and patterns", | |
"symmetry and balance", | |
"leading lines and vanishing points", | |
"watch for converging verticals", | |
"isolate key architectural elements" | |
] | |
}, | |
"action_sports": { | |
"description": "High-speed movement and sports photography", | |
"camera_settings": { | |
"mode": "TV/S", | |
"shutter_speed": "1/500s+ to freeze motion", | |
"aperture": "f/2.8-f/4 for subject isolation", | |
"iso": "800-3200 adaptive", | |
"focus": "continuous AF with tracking", | |
"burst_mode": "high speed continuous" | |
}, | |
"equipment": { | |
"camera": "Sony A1", | |
"lens": "70-200mm f/2.8", | |
"longer_lens": "300mm f/2.8", | |
"wide_lens": "24-70mm f/2.8 for close action" | |
}, | |
"lighting": { | |
"fast_shutter": "freeze motion priority", | |
"available_light": "work with venue lighting", | |
"iso_performance": "accept higher ISO for speed" | |
}, | |
"composition": [ | |
"anticipate action and peak moments", | |
"leave space in direction of movement", | |
"fill frame with subject", | |
"capture emotion and intensity", | |
"continuous focus tracking" | |
] | |
} | |
}, | |
# PRINCIPIOS DE ILUMINACIÓN PROFESIONAL | |
"lighting_principles": { | |
"natural_light_types": { | |
"golden_hour": { | |
"timing": "first hour after sunrise, last hour before sunset", | |
"characteristics": "warm, soft, directional", | |
"best_for": "portraits, landscapes, architecture", | |
"camera_settings": "lower ISO, wider aperture possible" | |
}, | |
"blue_hour": { | |
"timing": "20-30 minutes after sunset", | |
"characteristics": "even blue light, dramatic mood", | |
"best_for": "cityscapes, architecture with lights", | |
"camera_settings": "tripod required, longer exposures" | |
}, | |
"overcast": { | |
"characteristics": "soft, even, diffused light", | |
"best_for": "portraits, forests, waterfalls", | |
"advantage": "no harsh shadows", | |
"camera_settings": "watch for flat contrast" | |
}, | |
"open_shade": { | |
"characteristics": "soft directional light", | |
"best_for": "outdoor portraits", | |
"advantage": "avoids harsh sun", | |
"camera_settings": "may need exposure compensation" | |
} | |
}, | |
"artificial_light_setups": { | |
"three_point_lighting": { | |
"key_light": "primary light source at 45 degrees", | |
"fill_light": "softer light to reduce shadows", | |
"rim_light": "separation from background", | |
"ratio": "3:1 or 2:1 key to fill for drama" | |
}, | |
"window_lighting": { | |
"side_lighting": "place subject 90 degrees to window", | |
"frontal": "face window directly for even light", | |
"reflector_use": "bounce light back to fill shadows" | |
} | |
}, | |
"lighting_directions": { | |
"frontal": { | |
"effect": "even illumination, minimal shadows", | |
"mood": "clean, professional, safe", | |
"best_for": "corporate portraits, documentation" | |
}, | |
"side_lateral": { | |
"effect": "dramatic shadows, depth and texture", | |
"mood": "artistic, mysterious, powerful", | |
"best_for": "creative portraits, artistic work" | |
}, | |
"backlighting": { | |
"effect": "rim lighting, silhouettes", | |
"mood": "dreamy, romantic, dramatic", | |
"technical": "watch for exposure compensation" | |
}, | |
"top_lighting": { | |
"effect": "dramatic shadows under eyes", | |
"mood": "harsh, dramatic, theatrical", | |
"use_carefully": "can be unflattering for portraits" | |
} | |
} | |
}, | |
# ===================================================== | |
# PARTE 2: REGLAS DE COMPOSICIÓN Y TÉCNICAS AVANZADAS | |
# ===================================================== | |
# REGLAS DE COMPOSICIÓN PROFESIONAL | |
"composition_rules": { | |
"rule_of_thirds": { | |
"principle": "divide frame into 9 equal sections", | |
"application": "place key elements on intersection points", | |
"subject_placement": "eyes on upper third line for portraits", | |
"horizon_placement": "upper or lower third for landscapes", | |
"when_to_break": "center composition for symmetry or impact" | |
}, | |
"rule_of_z": { | |
"principle": "visual examination technique following Z pattern", | |
"purpose": "eliminate distracting elements systematically", | |
"application": "scan image from top-left to bottom-right", | |
"focus_check": "ensure sharp focus where intended", | |
"composition_check": "verify all elements contribute to story" | |
}, | |
"leading_lines": { | |
"purpose": "guide viewer's eye through the image", | |
"types": ["diagonal lines", "curved lines", "converging lines"], | |
"sources": ["roads", "rivers", "architecture", "shadows"], | |
"technique": "use lines to lead to main subject" | |
}, | |
"vanishing_points": { | |
"single_point": "all lines converge to one point", | |
"two_point": "vertical lines stay vertical, horizontals converge", | |
"application": "create depth and draw attention", | |
"photography_use": "architecture, streets, interiors" | |
}, | |
"fibonacci_spiral": { | |
"mathematical_basis": "golden ratio spiral", | |
"composition_tool": "place subject at spiral intersection", | |
"relationship_to_thirds": "refined version of rule of thirds", | |
"application": "when precise composition balance needed" | |
}, | |
"symmetry_and_patterns": { | |
"perfect_symmetry": "exact mirror image composition", | |
"near_symmetry": "almost symmetrical with subtle variation", | |
"pattern_breaking": "disruption in regular pattern creates focus", | |
"application": "architecture, reflections, nature patterns" | |
}, | |
"depth_layers": { | |
"foreground": "nearest elements to camera", | |
"middle_ground": "main subject area typically here", | |
"background": "context and environment", | |
"technique": "create separation between layers", | |
"depth_cues": "overlapping, size variation, atmospheric perspective" | |
} | |
}, | |
# ÁNGULOS Y PERSPECTIVAS | |
"camera_angles": { | |
"eye_level_normal": { | |
"description": "camera at subject's eye level", | |
"effect": "neutral, natural perspective", | |
"psychological_impact": "equality, relatability", | |
"best_for": "portraits, documentary, street photography" | |
}, | |
"low_angle_worms_eye": { | |
"description": "camera below subject looking up", | |
"effect": "subject appears larger, more powerful", | |
"psychological_impact": "dominance, strength, heroic", | |
"technical": "watch for distortion with wide lenses", | |
"best_for": "architecture, powerful portraits, dramatic scenes" | |
}, | |
"high_angle_birds_eye": { | |
"description": "camera above subject looking down", | |
"effect": "subject appears smaller, vulnerable", | |
"psychological_impact": "submission, overview, context", | |
"aerial_version": "complete overhead view", | |
"best_for": "environmental context, patterns, vulnerability" | |
}, | |
"dutch_angle": { | |
"description": "camera tilted off horizontal", | |
"effect": "dynamic tension, unease", | |
"psychological_impact": "instability, energy, confusion", | |
"use_sparingly": "can become gimmicky if overused", | |
"best_for": "creative portraits, dynamic scenes" | |
} | |
}, | |
# PLANOS FOTOGRÁFICOS | |
"photographic_planes": { | |
"extreme_wide_shot": { | |
"framing": "subject very small in environment", | |
"purpose": "establish location and context", | |
"best_for": "landscapes, establishing shots", | |
"composition_focus": "environment tells the story" | |
}, | |
"wide_shot": { | |
"framing": "full body visible with environment", | |
"purpose": "show subject in context", | |
"best_for": "environmental portraits, action", | |
"composition_balance": "subject and environment both important" | |
}, | |
"medium_shot": { | |
"framing": "from waist up approximately", | |
"purpose": "balance between subject and environment", | |
"best_for": "conversation, interaction, casual portraits", | |
"composition_focus": "subject is primary, environment secondary" | |
}, | |
"close_up": { | |
"framing": "head and shoulders, tight on face", | |
"purpose": "show emotion and expression clearly", | |
"best_for": "emotional portraits, interviews", | |
"technical_focus": "eyes must be perfectly sharp" | |
}, | |
"extreme_close_up": { | |
"framing": "part of face or specific detail", | |
"purpose": "intense emotion or specific detail", | |
"best_for": "artistic portraits, product details", | |
"technical_challenge": "depth of field very shallow" | |
}, | |
"detail_shot": { | |
"framing": "specific small element", | |
"purpose": "highlight particular aspect", | |
"best_for": "hands, jewelry, textures, products", | |
"technical_requirements": "macro capabilities often needed" | |
} | |
}, | |
# TÉCNICAS DE ENFOQUE Y PROFUNDIDAD DE CAMPO | |
"focus_techniques": { | |
"shallow_depth_of_field": { | |
"aperture_range": "f/1.4 - f/2.8", | |
"effect": "subject sharp, background blurred", | |
"best_for": "portraits, product photography, subject isolation", | |
"technical_consideration": "precise focus critical", | |
"creative_use": "bokeh quality becomes important" | |
}, | |
"deep_depth_of_field": { | |
"aperture_range": "f/8 - f/16", | |
"effect": "everything sharp from front to back", | |
"best_for": "landscapes, architecture, group photos", | |
"technical_consideration": "diffraction at very small apertures", | |
"hyperfocal_distance": "maximize sharp zone" | |
}, | |
"selective_focus": { | |
"technique": "choose specific focal plane", | |
"creative_control": "direct viewer attention", | |
"applications": ["isolate subject", "hide distractions", "create mood"], | |
"lens_choice": "longer focal lengths enhance effect" | |
}, | |
"focus_stacking": { | |
"technique": "multiple shots at different focus points", | |
"purpose": "extend depth of field beyond single shot", | |
"best_for": "macro photography, product shots", | |
"post_processing": "requires blending software" | |
} | |
}, | |
# MODO DE CÁMARA Y CONFIGURACIONES | |
"camera_modes": { | |
"program_mode": { | |
"description": "camera selects aperture and shutter speed", | |
"when_to_use": "quick shooting, changing conditions", | |
"photographer_control": "ISO, exposure compensation, focus", | |
"advantage": "fast response to opportunities", | |
"limitation": "less creative control over depth of field" | |
}, | |
"aperture_priority": { | |
"mode_designation": "AV (Canon) / A (Nikon)", | |
"photographer_sets": "aperture value", | |
"camera_sets": "shutter speed for correct exposure", | |
"best_for": "controlling depth of field", | |
"applications": ["portraits", "landscapes", "creative control"], | |
"watch_for": "shutter speed dropping too low" | |
}, | |
"shutter_priority": { | |
"mode_designation": "TV (Canon) / S (Nikon)", | |
"photographer_sets": "shutter speed", | |
"camera_sets": "aperture for correct exposure", | |
"best_for": "controlling motion", | |
"applications": ["sports", "action", "panning techniques"], | |
"watch_for": "aperture limits at extreme speeds" | |
}, | |
"manual_mode": { | |
"photographer_sets": "both aperture and shutter speed", | |
"when_to_use": ["consistent lighting", "studio work", "long exposures"], | |
"requires": "good understanding of exposure triangle", | |
"advantage": "complete creative control", | |
"tools": "light meter, histogram, experience" | |
} | |
}, | |
# TÉCNICAS DE MOVIMIENTO Y ACCIÓN | |
"movement_techniques": { | |
"freeze_motion": { | |
"shutter_speed": "1/250s or faster", | |
"applications": ["sports", "action", "sharp movement"], | |
"considerations": ["adequate light needed", "higher ISO may be required"], | |
"focus_mode": "continuous AF with tracking" | |
}, | |
"motion_blur_panning": { | |
"shutter_speed": "1/15s - 1/60s typically", | |
"technique": "follow subject smoothly while shooting", | |
"effect": "sharp subject with blurred background", | |
"creates": "sense of speed and movement", | |
"requires": "practice and smooth camera movement" | |
}, | |
"intentional_camera_movement": { | |
"technique": "deliberate camera shake during exposure", | |
"creative_effect": "abstract, artistic blur patterns", | |
"shutter_speed": "1/4s - 2s typically", | |
"applications": ["creative landscapes", "abstract art", "impressionistic effects"] | |
} | |
}, | |
# ===================================================== | |
# PARTE 3: CONFIGURACIONES ISO Y CONDICIONES DE LUZ | |
# ===================================================== | |
# CONFIGURACIONES ISO PROFESIONALES | |
"iso_guidelines": { | |
"base_iso": { | |
"range": "100-200", | |
"quality": "maximum image quality, lowest noise", | |
"lighting_needed": "bright daylight, studio lighting", | |
"best_for": "landscapes, studio portraits, product photography" | |
}, | |
"low_iso": { | |
"range": "400-800", | |
"quality": "excellent quality, minimal noise", | |
"lighting_needed": "good available light", | |
"best_for": "outdoor portraits, street photography, indoor with windows" | |
}, | |
"medium_iso": { | |
"range": "1600-3200", | |
"quality": "good quality, manageable noise", | |
"lighting_needed": "indoor available light, overcast outdoor", | |
"best_for": "event photography, indoor sports, available light portraits" | |
}, | |
"high_iso": { | |
"range": "6400-12800", | |
"quality": "acceptable quality, visible noise", | |
"lighting_needed": "low light situations", | |
"best_for": "concerts, nighttime events, astrophotography", | |
"post_processing": "noise reduction recommended" | |
} | |
}, | |
# SITUACIONES DE LUZ ESPECÍFICAS | |
"lighting_situations": { | |
"bright_daylight": { | |
"iso": "100-200", | |
"aperture_considerations": "can use smaller apertures for sharpness", | |
"challenge": "harsh shadows", | |
"solutions": ["use reflectors", "find open shade", "use fill flash"] | |
}, | |
"overcast_day": { | |
"iso": "200-400", | |
"characteristics": "soft, even light but dimmer", | |
"advantage": "natural diffusion", | |
"watch_for": "flat contrast, may need post-processing boost" | |
}, | |
"indoor_natural_light": { | |
"iso": "800-1600", | |
"window_light": "excellent for portraits", | |
"technique": "position subject relative to window", | |
"tools": "reflectors to control shadow fill" | |
}, | |
"low_light_available": { | |
"iso": "1600-6400", | |
"stabilization": "essential for sharp images", | |
"technique": "wider apertures, slower movements", | |
"creative_opportunities": "dramatic lighting, mood" | |
}, | |
"night_photography": { | |
"iso": "3200-12800", | |
"equipment": "tripod usually required", | |
"techniques": ["long exposures", "image stacking", "noise reduction"], | |
"subjects": ["cityscapes", "astrophotography", "light trails"] | |
} | |
}, | |
# TÉCNICAS ESPECIALIZADAS | |
"specialized_techniques": { | |
"macro_photography": { | |
"equipment": "macro lens or extension tubes", | |
"camera_settings": { | |
"aperture": "f/8-f/16 for adequate depth of field", | |
"iso": "200-800", | |
"focus": "manual focus recommended", | |
"stabilization": "tripod essential" | |
}, | |
"lighting": "ring flash or diffused lighting", | |
"challenges": ["shallow depth of field", "camera shake", "subject movement"] | |
}, | |
"long_exposure": { | |
"equipment": "tripod, neutral density filters", | |
"camera_settings": { | |
"mode": "Manual or Bulb", | |
"aperture": "f/8-f/16", | |
"iso": "100-200", | |
"shutter_speed": "30s to several minutes" | |
}, | |
"subjects": ["waterfalls", "clouds", "star trails", "traffic"], | |
"technique": "use timer or remote to avoid camera shake" | |
}, | |
"high_key_photography": { | |
"lighting": "bright, even, minimal shadows", | |
"exposure": "intentionally overexposed by 1-2 stops", | |
"post_processing": "maintain detail in highlights", | |
"mood": "clean, optimistic, airy", | |
"subjects": ["fashion", "beauty", "products"] | |
}, | |
"low_key_photography": { | |
"lighting": "dramatic, contrasty, deep shadows", | |
"exposure": "underexposed to maintain shadow detail", | |
"technique": "single light source often", | |
"mood": "mysterious, dramatic, moody", | |
"subjects": ["portraits", "still life", "artistic work"] | |
} | |
} | |
} | |
# ===================================================== | |
# PARTE 4: CLASES DE ANÁLISIS PROFESIONAL | |
# ===================================================== | |
class ProfessionalPhotoAnalyzer: | |
"""Expert photography context provider for intelligent prompt enhancement""" | |
def __init__(self): | |
self.knowledge = EXPERT_PHOTOGRAPHY_KNOWLEDGE | |
def detect_scene_type(self, description: str) -> str: | |
"""Detect primary scene type from image description""" | |
description_lower = description.lower() | |
# Scene type detection patterns | |
scene_patterns = { | |
"portrait_studio": ["studio", "portrait", "professional lighting", "controlled lighting"], | |
"portrait_exterior": ["portrait", "person", "outdoor", "natural light", "exterior"], | |
"street_photography": ["street", "urban", "candid", "documentary", "city"], | |
"landscape": ["landscape", "nature", "mountain", "horizon", "scenic", "outdoor scene"], | |
"architecture": ["building", "architecture", "structure", "geometric", "facade"], | |
"action_sports": ["action", "sport", "movement", "running", "dynamic", "motion"] | |
} | |
# Score each scene type based on keyword matches | |
scene_scores = {} | |
for scene_type, keywords in scene_patterns.items(): | |
score = sum(1 for keyword in keywords if keyword in description_lower) | |
if score > 0: | |
scene_scores[scene_type] = score | |
# Return highest scoring scene type, default to general if none match | |
if scene_scores: | |
return max(scene_scores.items(), key=lambda x: x[1])[0] | |
else: | |
return "general" | |
def analyze_lighting_conditions(self, description: str) -> Dict[str, Any]: | |
"""Analyze lighting conditions from description""" | |
description_lower = description.lower() | |
lighting_analysis = { | |
"type": "unknown", | |
"quality": "unknown", | |
"direction": "unknown", | |
"recommendations": [] | |
} | |
# Detect lighting type | |
if any(term in description_lower for term in ["studio", "controlled", "professional lighting"]): | |
lighting_analysis["type"] = "studio" | |
lighting_analysis["recommendations"].append("3-point lighting setup") | |
elif any(term in description_lower for term in ["natural", "daylight", "outdoor", "sun"]): | |
lighting_analysis["type"] = "natural" | |
lighting_analysis["recommendations"].append("consider time of day for optimal light") | |
elif any(term in description_lower for term in ["low light", "dark", "night", "dim"]): | |
lighting_analysis["type"] = "low_light" | |
lighting_analysis["recommendations"].append("higher ISO and stabilization needed") | |
# Detect lighting quality | |
if any(term in description_lower for term in ["soft", "diffused", "even"]): | |
lighting_analysis["quality"] = "soft" | |
elif any(term in description_lower for term in ["harsh", "dramatic", "contrasty"]): | |
lighting_analysis["quality"] = "hard" | |
# Detect lighting direction | |
if any(term in description_lower for term in ["side lit", "lateral", "from side"]): | |
lighting_analysis["direction"] = "side" | |
elif any(term in description_lower for term in ["backlit", "rim light", "silhouette"]): | |
lighting_analysis["direction"] = "back" | |
elif any(term in description_lower for term in ["front lit", "frontal"]): | |
lighting_analysis["direction"] = "front" | |
return lighting_analysis | |
def get_camera_recommendations(self, scene_type: str, lighting_conditions: Dict[str, Any]) -> Dict[str, Any]: | |
"""Get professional camera setup recommendations""" | |
if scene_type not in self.knowledge["scene_types"]: | |
scene_type = "portrait_exterior" # Default fallback | |
scene_config = self.knowledge["scene_types"][scene_type] | |
recommendations = { | |
"camera_body": scene_config["equipment"]["camera"], | |
"primary_lens": scene_config["equipment"]["lens"], | |
"camera_settings": scene_config["camera_settings"].copy(), | |
"lighting_setup": scene_config["lighting"], | |
"composition_tips": scene_config["composition"] | |
} | |
# Adjust ISO based on lighting conditions | |
if lighting_conditions["type"] == "low_light": | |
recommendations["camera_settings"]["iso"] = "1600-6400" | |
elif lighting_conditions["type"] == "studio": | |
recommendations["camera_settings"]["iso"] = "100-200" | |
elif lighting_conditions["type"] == "natural": | |
recommendations["camera_settings"]["iso"] = "200-800" | |
return recommendations | |
def get_composition_guidance(self, scene_type: str, description: str) -> List[str]: | |
"""Get composition recommendations based on scene type and content""" | |
guidance = [] | |
description_lower = description.lower() | |
# Base composition rules | |
guidance.append("apply rule of thirds for key element placement") | |
# Scene-specific composition | |
if scene_type == "portrait_studio" or scene_type == "portrait_exterior": | |
guidance.extend([ | |
"focus on nearest eye for maximum sharpness", | |
"use shallow depth of field to isolate subject", | |
"leave appropriate headroom and breathing space" | |
]) | |
elif scene_type == "landscape": | |
guidance.extend([ | |
"place horizon on upper or lower third line", | |
"create depth with foreground, middle ground, background", | |
"use leading lines to guide viewer's eye" | |
]) | |
elif scene_type == "street_photography": | |
guidance.extend([ | |
"apply rule of Z for comprehensive composition check", | |
"anticipate decisive moments", | |
"maintain respectful distance while capturing authenticity" | |
]) | |
elif scene_type == "architecture": | |
guidance.extend([ | |
"watch for converging verticals", | |
"use strong geometric lines and patterns", | |
"consider symmetry and balance" | |
]) | |
# Motion-specific guidance | |
if any(term in description_lower for term in ["movement", "motion", "running", "action"]): | |
guidance.extend([ | |
"leave space in direction of movement", | |
"consider panning technique for motion blur", | |
"use continuous autofocus for tracking" | |
]) | |
return guidance | |
def get_technical_context(self, scene_type: str, lighting_conditions: Dict[str, Any]) -> str: | |
"""Generate technical context string for prompt enhancement""" | |
recommendations = self.get_camera_recommendations(scene_type, lighting_conditions) | |
context_parts = [] | |
# Camera and lens | |
context_parts.append(f"Professional setup: {recommendations['camera_body']}") | |
context_parts.append(f"with {recommendations['primary_lens']}") | |
# Key settings | |
settings = recommendations['camera_settings'] | |
if 'mode' in settings: | |
context_parts.append(f"shot in {settings['mode']} mode") | |
if 'aperture' in settings: | |
context_parts.append(f"at {settings['aperture']}") | |
if 'iso' in settings: | |
context_parts.append(f"ISO {settings['iso']}") | |
# Lighting insight | |
if lighting_conditions["type"] != "unknown": | |
if lighting_conditions["type"] == "studio": | |
context_parts.append("professional studio lighting") | |
elif lighting_conditions["type"] == "natural": | |
context_parts.append("natural lighting conditions") | |
elif lighting_conditions["type"] == "low_light": | |
context_parts.append("available light photography") | |
return ", ".join(context_parts) | |
def _generate_professional_insight(self, scene_type: str, lighting_conditions: Dict[str, Any]) -> str: | |
"""Generate professional photography insight based on scene and lighting""" | |
insights = [] | |
# Scene-specific professional insights | |
if scene_type == "portrait_studio": | |
insights.append("Professional studio portraiture requires precise lighting control") | |
insights.append("3-point lighting setup ensures dimensional modeling of facial features") | |
elif scene_type == "portrait_exterior": | |
insights.append("Natural light portraiture benefits from soft, directional lighting") | |
insights.append("Golden hour provides optimal warmth and flattering illumination") | |
elif scene_type == "street_photography": | |
insights.append("Street photography requires anticipation and quick technical adaptation") | |
insights.append("Available light mastery is essential for authentic documentary capture") | |
elif scene_type == "landscape": | |
insights.append("Landscape photography demands patience for optimal natural lighting") | |
insights.append("Hyperfocal distance technique maximizes front-to-back sharpness") | |
elif scene_type == "architecture": | |
insights.append("Architectural photography emphasizes form, texture, and geometric precision") | |
insights.append("Side lighting reveals dimensional qualities and surface textures") | |
# Lighting-specific insights | |
if lighting_conditions["type"] == "studio": | |
insights.append("Controlled studio environment allows precise mood and contrast control") | |
elif lighting_conditions["type"] == "natural": | |
insights.append("Natural lighting varies continuously, requiring adaptive technical approach") | |
elif lighting_conditions["type"] == "low_light": | |
insights.append("Low light conditions demand technical precision and creative interpretation") | |
return ". ".join(insights) | |
def generate_enhanced_context(self, bagel_description: str) -> Dict[str, Any]: | |
""" | |
Main method: Generate professional photography context for BAGEL enhancement | |
NON-INVASIVE: Provides guidance without overriding BAGEL's creativity | |
""" | |
# Analyze the image description from BAGEL | |
scene_type = self.detect_scene_type(bagel_description) | |
lighting_conditions = self.analyze_lighting_conditions(bagel_description) | |
composition_guidance = self.get_composition_guidance(scene_type, bagel_description) | |
technical_context = self.get_technical_context(scene_type, lighting_conditions) | |
enhanced_context = { | |
"scene_type": scene_type, | |
"lighting_analysis": lighting_conditions, | |
"technical_context": technical_context, | |
"composition_guidance": composition_guidance, | |
"professional_insight": self._generate_professional_insight(scene_type, lighting_conditions), | |
"equipment_recommendation": self.get_camera_recommendations(scene_type, lighting_conditions) | |
} | |
return enhanced_context | |
def format_bagel_enhancement_prompt(self, base_prompt: str, enhanced_context: Dict[str, Any]) -> str: | |
""" | |
Format enhanced prompt for BAGEL while preserving its creative freedom | |
""" | |
context_guidance = f""" | |
PROFESSIONAL PHOTOGRAPHY CONTEXT: | |
Scene Type: {enhanced_context['scene_type'].replace('_', ' ').title()} | |
Technical Setup: {enhanced_context['technical_context']} | |
COMPOSITION CONSIDERATIONS: | |
{' • '.join(enhanced_context['composition_guidance'])} | |
PROFESSIONAL INSIGHT: | |
{enhanced_context['professional_insight']} | |
Apply these principles flexibly to enhance your creative analysis. | |
""" | |
return base_prompt + context_guidance | |
# ===================================================== | |
# PARTE 5: FUNCIONES DE INTEGRACIÓN Y UTILIDADES | |
# ===================================================== | |
class ProfessionalScoring: | |
"""Enhanced scoring system incorporating professional photography principles""" | |
def __init__(self): | |
self.analyzer = ProfessionalPhotoAnalyzer() | |
def calculate_professional_score(self, prompt: str, analysis_data: Optional[Dict[str, Any]] = None) -> Tuple[int, Dict[str, int]]: | |
""" | |
Calculate enhanced quality score incorporating professional photography principles | |
""" | |
breakdown = {} | |
# 1. TECHNICAL EXCELLENCE (0-30 points) | |
technical_score = 0 | |
# Professional camera bodies | |
professional_cameras = [ | |
'canon eos r5', 'canon eos r6', 'sony a1', 'sony a7r', | |
'leica m11', 'phase one', 'hasselblad', 'fujifilm gfx' | |
] | |
if any(camera in prompt.lower() for camera in professional_cameras): | |
technical_score += 10 | |
# Professional lens specifications | |
lens_pattern = r'\d+mm.*f/[\d.]+' | |
if re.search(lens_pattern, prompt.lower()): | |
technical_score += 8 | |
# Specific aperture settings | |
aperture_pattern = r'f/[\d.]+' | |
if re.search(aperture_pattern, prompt.lower()): | |
technical_score += 6 | |
# ISO considerations | |
iso_pattern = r'iso\s*\d+' | |
if re.search(iso_pattern, prompt.lower()): | |
technical_score += 6 | |
breakdown["technical_excellence"] = min(30, technical_score) | |
# 2. LIGHTING MASTERY (0-25 points) | |
lighting_score = 0 | |
# Professional lighting terms | |
lighting_terms = [ | |
'studio lighting', 'natural lighting', 'golden hour', 'blue hour', | |
'side lighting', 'rim lighting', 'dramatic lighting', 'soft lighting', | |
'3-point lighting', 'key light', 'fill light', 'diffused light' | |
] | |
lighting_matches = sum(1 for term in lighting_terms if term in prompt.lower()) | |
lighting_score += min(15, lighting_matches * 3) | |
# Advanced lighting concepts | |
advanced_lighting = [ | |
'lighting ratio', 'hard light', 'soft light', 'directional light', | |
'ambient light', 'available light', 'controlled lighting' | |
] | |
advanced_matches = sum(1 for term in advanced_lighting if term in prompt.lower()) | |
lighting_score += min(10, advanced_matches * 2) | |
breakdown["lighting_mastery"] = min(25, lighting_score) | |
# 3. COMPOSITION EXPERTISE (0-25 points) | |
composition_score = 0 | |
# Classic composition rules | |
composition_rules = [ | |
'rule of thirds', 'leading lines', 'depth of field', 'shallow depth', | |
'bokeh', 'symmetry', 'balance', 'framing', 'perspective' | |
] | |
rule_matches = sum(1 for rule in composition_rules if rule in prompt.lower()) | |
composition_score += min(15, rule_matches * 2) | |
# Advanced composition concepts | |
advanced_composition = [ | |
'vanishing point', 'fibonacci', 'golden ratio', 'dynamic composition', | |
'layered composition', 'negative space', 'visual flow' | |
] | |
advanced_comp_matches = sum(1 for concept in advanced_composition if concept in prompt.lower()) | |
composition_score += min(10, advanced_comp_matches * 2) | |
breakdown["composition_expertise"] = min(25, composition_score) | |
# 4. PROFESSIONAL TERMINOLOGY (0-20 points) | |
terminology_score = 0 | |
# Professional photography terms | |
pro_terms = [ | |
'professional photography', 'commercial photography', 'editorial', | |
'documentary style', 'photojournalism', 'fine art photography', | |
'architectural photography', 'landscape photography', 'portraiture' | |
] | |
term_matches = sum(1 for term in pro_terms if term in prompt.lower()) | |
terminology_score += min(12, term_matches * 2) | |
# Technical photography terms | |
technical_terms = [ | |
'hyperfocal distance', 'exposure triangle', 'metering', 'focus stacking', | |
'bracketing', 'tilt-shift', 'macro photography', 'telephoto compression' | |
] | |
tech_matches = sum(1 for term in technical_terms if term in prompt.lower()) | |
terminology_score += min(8, tech_matches * 2) | |
breakdown["professional_terminology"] = min(20, terminology_score) | |
# Calculate total score | |
total_score = sum(breakdown.values()) | |
return total_score, breakdown | |
def get_professional_camera_setup(scene_description: str) -> Dict[str, str]: | |
""" | |
Quick function to get camera setup recommendation based on scene description | |
""" | |
analyzer = ProfessionalPhotoAnalyzer() | |
scene_type = analyzer.detect_scene_type(scene_description) | |
lighting_conditions = analyzer.analyze_lighting_conditions(scene_description) | |
recommendations = analyzer.get_camera_recommendations(scene_type, lighting_conditions) | |
# Format as simple dictionary for easy use | |
return { | |
"camera": recommendations["camera_body"], | |
"lens": recommendations["primary_lens"], | |
"aperture": recommendations["camera_settings"].get("aperture", "f/4"), | |
"mode": recommendations["camera_settings"].get("mode", "AV"), | |
"iso": recommendations["camera_settings"].get("iso", "400"), | |
"scene_type": scene_type | |
} | |
def enhance_flux_prompt_with_professional_knowledge(original_prompt: str, image_analysis: str = "") -> str: | |
""" | |
Main integration function: Enhance FLUX prompts with professional photography knowledge | |
PRESERVES CREATIVITY while adding technical expertise | |
""" | |
analyzer = ProfessionalPhotoAnalyzer() | |
# Use image analysis if provided, otherwise use the prompt itself | |
analysis_text = image_analysis if image_analysis else original_prompt | |
# Get professional context | |
enhanced_context = analyzer.generate_enhanced_context(analysis_text) | |
# Build enhancement that supplements rather than replaces | |
enhancement_parts = [] | |
# Add technical context naturally | |
technical_context = enhanced_context["technical_context"] | |
if technical_context: | |
enhancement_parts.append(f"Shot on {technical_context}") | |
# Add composition guidance as suggestion | |
composition_tips = enhanced_context["composition_guidance"] | |
if composition_tips: | |
# Pick most relevant composition tip | |
primary_tip = composition_tips[0] if composition_tips else "" | |
if "rule of thirds" in primary_tip: | |
enhancement_parts.append("composed using rule of thirds") | |
elif "shallow depth" in primary_tip: | |
enhancement_parts.append("with shallow depth of field") | |
# Add lighting enhancement | |
lighting_analysis = enhanced_context["lighting_analysis"] | |
if lighting_analysis["type"] == "studio": | |
enhancement_parts.append("professional studio lighting") | |
elif lighting_analysis["type"] == "natural": | |
enhancement_parts.append("natural lighting") | |
elif lighting_analysis["type"] == "low_light": | |
enhancement_parts.append("available light photography") | |
# Combine original prompt with enhancements | |
if enhancement_parts: | |
enhanced_prompt = f"{original_prompt}, {', '.join(enhancement_parts)}" | |
else: | |
enhanced_prompt = f"{original_prompt}, professional photography" | |
return enhanced_prompt | |
def get_scene_specific_camera_config(scene_keywords: List[str]) -> Dict[str, Any]: | |
""" | |
Get camera configuration based on scene keywords | |
Useful for quick scene-based recommendations | |
""" | |
scene_mappings = { | |
"portrait": "portrait_studio", | |
"person": "portrait_exterior", | |
"street": "street_photography", | |
"urban": "street_photography", | |
"landscape": "landscape", | |
"nature": "landscape", | |
"building": "architecture", | |
"architecture": "architecture", | |
"action": "action_sports", | |
"sport": "action_sports", | |
"movement": "action_sports" | |
} | |
# Find matching scene type | |
scene_type = "portrait_exterior" # default | |
for keyword in scene_keywords: | |
if keyword.lower() in scene_mappings: | |
scene_type = scene_mappings[keyword.lower()] | |
break | |
# Get configuration from knowledge base | |
if scene_type in EXPERT_PHOTOGRAPHY_KNOWLEDGE["scene_types"]: | |
config = EXPERT_PHOTOGRAPHY_KNOWLEDGE["scene_types"][scene_type] | |
return { | |
"scene_type": scene_type, | |
"equipment": config["equipment"], | |
"settings": config["camera_settings"], | |
"lighting": config["lighting"], | |
"composition": config["composition"] | |
} | |
return {} | |
# ===================================================== | |
# UTILIDADES DE EXPORTACIÓN | |
# ===================================================== | |
def export_professional_prompt_enhancement(bagel_output: str, bagel_metadata: Dict[str, Any] = None) -> Dict[str, Any]: | |
""" | |
Complete integration function for use in your existing pipeline | |
Returns enhanced prompt and metadata for seamless integration | |
""" | |
analyzer = ProfessionalPhotoAnalyzer() | |
scorer = ProfessionalScoring() | |
# Generate professional context | |
enhanced_context = analyzer.generate_enhanced_context(bagel_output) | |
# Create enhanced prompt | |
enhanced_prompt = enhance_flux_prompt_with_professional_knowledge(bagel_output) | |
# Calculate professional score | |
score, score_breakdown = scorer.calculate_professional_score(enhanced_prompt, bagel_metadata) | |
# Prepare metadata | |
enhanced_metadata = bagel_metadata.copy() if bagel_metadata else {} | |
enhanced_metadata.update({ | |
"professional_enhancement": True, | |
"scene_type": enhanced_context["scene_type"], | |
"professional_score": score, | |
"score_breakdown": score_breakdown, | |
"technical_context": enhanced_context["technical_context"], | |
"professional_insights": enhanced_context["professional_insight"] | |
}) | |
return { | |
"enhanced_prompt": enhanced_prompt, | |
"metadata": enhanced_metadata, | |
"original_prompt": bagel_output, | |
"enhancement_context": enhanced_context | |
} | |
# Global analyzer instance for easy access | |
professional_analyzer = ProfessionalPhotoAnalyzer() | |
professional_scorer = ProfessionalScoring() | |
# Export main functions for integration | |
__all__ = [ | |
"ProfessionalPhotoAnalyzer", | |
"ProfessionalScoring", | |
"enhance_flux_prompt_with_professional_knowledge", | |
"get_professional_camera_setup", | |
"export_professional_prompt_enhancement", | |
"professional_analyzer", | |
"professional_scorer", | |
"EXPERT_PHOTOGRAPHY_KNOWLEDGE" | |
] | |