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