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