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