from typing import Dict, List from prompt_library_manager import PromptLibraryManager class SceneCompatibilityManager: """Check brand-scene compatibility to reduce false positives""" def __init__(self, prompt_library: PromptLibraryManager = None): """ Args: prompt_library: PromptLibraryManager instance for brand metadata """ if prompt_library is None: prompt_library = PromptLibraryManager() self.prompt_library = prompt_library # Scene classification keywords self.scene_keywords = { 'food_closeup': ['food', 'meal', 'dish', 'plate', 'restaurant', 'dining', 'cuisine'], 'nature_landscape': ['mountain', 'forest', 'beach', 'ocean', 'lake', 'sky', 'sunset', 'outdoor'], 'industrial': ['factory', 'warehouse', 'industrial', 'machinery', 'construction'], 'sports': ['gym', 'fitness', 'running', 'sports', 'athletic', 'exercise'], 'fashion': ['fashion', 'outfit', 'style', 'wearing', 'model'], 'luxury_retail': ['store', 'boutique', 'shop', 'retail', 'display'], 'office': ['office', 'desk', 'computer', 'workspace', 'business'], 'home': ['home', 'room', 'interior', 'living', 'bedroom'], 'lifestyle': ['lifestyle', 'casual', 'everyday', 'daily'], 'tech_review': ['unboxing', 'review', 'tech', 'device', 'gadget'], 'formal_event': ['event', 'party', 'formal', 'ceremony', 'celebration'], 'outdoor': ['outdoor', 'park', 'street', 'outside'], 'travel': ['travel', 'trip', 'luggage', 'airport', 'vacation'], 'street': ['street', 'road', 'urban', 'city'], 'parking': ['parking', 'car park', 'garage'], 'showroom': ['showroom', 'exhibition', 'display'], 'closeup': ['closeup', 'detail', 'macro', 'close-up'] } print("✓ Scene Compatibility Manager initialized") def classify_scene(self, scene_analysis: Dict) -> str: """ Classify scene type from OpenCLIP scene analysis Args: scene_analysis: Scene analysis results from OpenCLIPSemanticManager Returns: Scene type string (e.g., 'food_closeup', 'fashion', 'tech_review') """ # Extract top scene categories scene_scores = {} # Check different scene analysis keys for key in ['urban', 'lighting', 'mood', 'composition']: if key in scene_analysis and 'top' in scene_analysis[key]: top_label = scene_analysis[key]['top'].lower() # Match with scene keywords for scene_type, keywords in self.scene_keywords.items(): for keyword in keywords: if keyword in top_label: scene_scores[scene_type] = scene_scores.get(scene_type, 0) + 1 # Return most matched scene type if scene_scores: return max(scene_scores.items(), key=lambda x: x[1])[0] return 'general' def check_compatibility(self, brand_name: str, scene_type: str) -> float: """ Check if brand is compatible with scene Args: brand_name: Name of the brand scene_type: Scene type (e.g., 'food_closeup', 'fashion') Returns: Compatibility score (0.3 to 1.0) - 1.0: fully compatible - 0.7: neutral (no strong match or mismatch) - 0.3: incompatible (reduce confidence) """ brand_info = self.prompt_library.get_brand_prompts(brand_name) if not brand_info: return 0.7 # Neutral if brand not found # Check if scene is typical for this brand typical_scenes = brand_info.get('typical_scenes', []) if scene_type in typical_scenes: return 1.0 # Fully compatible # Check if scene is incompatible incompatible_scenes = brand_info.get('incompatible_scenes', []) if scene_type in incompatible_scenes: return 0.3 # Reduce confidence significantly # Neutral case - no strong evidence either way return 0.7 def batch_check_compatibility(self, detected_brands: List[tuple], scene_analysis: Dict) -> List[tuple]: """ Check compatibility for multiple brands Args: detected_brands: List of (brand_name, confidence, bbox) tuples scene_analysis: Scene analysis results Returns: List of (brand_name, adjusted_confidence, bbox) tuples """ scene_type = self.classify_scene(scene_analysis) adjusted_brands = [] for brand_name, confidence, bbox in detected_brands: compatibility_score = self.check_compatibility(brand_name, scene_type) # Adjust confidence based on compatibility adjusted_confidence = confidence * compatibility_score # Only keep if adjusted confidence is still reasonable if adjusted_confidence > 0.25: adjusted_brands.append((brand_name, adjusted_confidence, bbox)) # Re-sort by adjusted confidence adjusted_brands.sort(key=lambda x: x[1], reverse=True) return adjusted_brands print("✓ SceneCompatibilityManager defined")