File size: 5,390 Bytes
6a3bd1f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
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")
|