DawnC commited on
Commit
3357fb4
·
verified ·
1 Parent(s): 93e593f

Upload statistics_processor.py

Browse files
Files changed (1) hide show
  1. statistics_processor.py +94 -217
statistics_processor.py CHANGED
@@ -4,111 +4,23 @@ from typing import Dict, List, Optional, Any
4
  class StatisticsProcessor:
5
  """
6
  統計分析處理器 - 負責複雜的物件統計分析和數據轉換
7
- 增加了決策穩健性機制來處理環境差異
 
 
8
  """
9
 
10
- def __init__(self, stability_config=None):
11
  """初始化統計分析處理器"""
12
  self.logger = logging.getLogger(self.__class__.__name__)
13
-
14
- # 穩定性配置參數
15
- self.stability_config = stability_config or {
16
- 'confidence_tolerance': 0.05, # 信心度容差範圍
17
- 'count_stability_threshold': 0.8, # 計數穩定性閾值
18
- 'decision_buffer_zone': 0.1, # 決策緩衝區
19
- 'prefer_specific_descriptions': True, # 優先使用具體描述
20
- 'multi_furniture_threshold': 2, # 多家具類型的最小閾值
21
- }
22
-
23
- self.logger.debug("StatisticsProcessor initialized with stability enhancements")
24
-
25
- def _stabilize_object_counts(self, object_statistics):
26
- """
27
- 穩定化物件計數,減少環境差異影響
28
-
29
- Args:
30
- object_statistics: 原始物件統計數據
31
-
32
- Returns:
33
- 穩定化後的物件統計數據
34
- """
35
- if not object_statistics:
36
- return object_statistics
37
-
38
- stabilized_stats = {}
39
-
40
- for obj_type, stats in object_statistics.items():
41
- stabilized_stats[obj_type] = stats.copy()
42
-
43
- # 穩定化信心度 - 將接近的值標準化到區間中點
44
- confidence = stats.get('confidence', 0.0)
45
- if confidence > 0:
46
- # 將信心度調整到標準化區間
47
- tolerance = self.stability_config['confidence_tolerance']
48
- stabilized_confidence = round(confidence / tolerance) * tolerance
49
- stabilized_stats[obj_type]['confidence'] = max(stabilized_confidence, confidence)
50
-
51
- return stabilized_stats
52
-
53
- def _should_use_specific_furniture_description(self, furniture_items, furniture_counts, object_statistics):
54
- """
55
- 決定是否使用具體的家具描述(如 "six chairs")還是通用描述(如 "furniture pieces")
56
- 增加了決策穩健性邏輯
57
-
58
- Args:
59
- furniture_items: 檢測到的家具類型列表
60
- furniture_counts: 對應的家具數量列表
61
- object_statistics: 完整的物件統計數據
62
-
63
- Returns:
64
- tuple: (是否使用具體描述, 主要家具類型, 主要家具數量)
65
- """
66
- # 如果沒有檢測到家具,返回通用描述
67
- if not furniture_items:
68
- return False, None, 0
69
-
70
- # 如果只有一種家具類型,優先使用具體描述
71
- if len(furniture_items) == 1:
72
- return True, furniture_items[0], furniture_counts[0]
73
-
74
- # 多種家具類型的決策邏輯
75
- total_furniture_count = sum(furniture_counts)
76
- main_furniture = furniture_items[0]
77
- main_count = furniture_counts[0]
78
-
79
- # 計算主要家具類型的比例
80
- main_furniture_ratio = main_count / total_furniture_count if total_furniture_count > 0 else 0
81
-
82
- # 決策緩衝區機制
83
- buffer_zone = self.stability_config['decision_buffer_zone']
84
- dominance_threshold = 0.7 + buffer_zone # 主導性閾值加上緩衝區
85
-
86
- # 椅子的特殊處理邏輯
87
- if main_furniture == "chair":
88
- chair_stats = object_statistics.get("chair", {})
89
- chair_confidence = chair_stats.get('confidence', 0.0)
90
-
91
- # 如果椅子檢測信心度很高且數量占主導地位,使用具體描述
92
- confidence_threshold = 0.8 - buffer_zone # 降低閾值增加穩定性
93
-
94
- if (chair_confidence >= confidence_threshold and
95
- main_furniture_ratio >= dominance_threshold):
96
- return True, main_furniture, main_count
97
-
98
- # 如果椅子數量適中且是唯一明確的家具類型,也使用具體描述
99
- if main_count <= 8 and main_furniture_ratio >= 0.6:
100
- return True, main_furniture, main_count
101
-
102
- # 其他情況使用通用描述
103
- return False, main_furniture, main_count
104
-
105
- def generate_statistics_replacements(self, object_statistics):
106
  """
107
  基於物體統計信息生成模板替換內容
108
-
109
  Args:
110
  object_statistics: 物體統計信息
111
-
112
  Returns:
113
  Dict[str, str]: 統計信息基礎的替換內容
114
  """
@@ -118,12 +30,9 @@ class StatisticsProcessor:
118
  return replacements
119
 
120
  try:
121
- # 首先穩定化物件統計數據
122
- stabilized_stats = self._stabilize_object_counts(object_statistics)
123
-
124
  # 處理植物元素
125
- if "potted plant" in stabilized_stats:
126
- count = stabilized_stats["potted plant"]["count"]
127
  if count == 1:
128
  replacements["plant_elements"] = "a potted plant"
129
  elif count <= 3:
@@ -131,12 +40,59 @@ class StatisticsProcessor:
131
  else:
132
  replacements["plant_elements"] = f"multiple potted plants ({count} total)"
133
 
134
- # 椅子和家具的穩健處理邏輯
135
- self._process_furniture_with_stability(stabilized_stats, replacements)
136
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  # 處理人員
138
- if "person" in stabilized_stats:
139
- count = stabilized_stats["person"]["count"]
140
  if count == 1:
141
  replacements["people_and_vehicles"] = "a person"
142
  replacements["pedestrian_flow"] = "an individual walking"
@@ -147,9 +103,9 @@ class StatisticsProcessor:
147
  replacements["people_and_vehicles"] = f"many people ({count} individuals)"
148
  replacements["pedestrian_flow"] = f"a crowd of {count} people"
149
 
150
- # 處理桌子設置(保持原有邏輯)
151
- if "dining table" in stabilized_stats:
152
- count = stabilized_stats["dining table"]["count"]
153
  if count == 1:
154
  replacements["table_setup"] = "a dining table"
155
  replacements["table_description"] = "a dining surface"
@@ -157,133 +113,54 @@ class StatisticsProcessor:
157
  replacements["table_setup"] = f"{count} dining tables"
158
  replacements["table_description"] = f"{count} dining surfaces"
159
 
160
- self.logger.debug(f"Generated {len(replacements)} stability-enhanced replacements")
161
 
162
  except Exception as e:
163
  self.logger.warning(f"Error generating statistics replacements: {str(e)}")
164
 
165
  return replacements
166
 
167
- def _process_furniture_with_stability(self, object_statistics, replacements):
168
  """
169
- 使用穩健性邏輯處理家具描述, 解決測試與部署時的浮點數計算結果差異
170
-
171
-
172
  Args:
173
- object_statistics: 穩定化後的物件統計數據
174
- replacements: 要更新的替換字典
175
- """
176
- # 數字轉換字典
177
- number_words = {
178
- 1: "one", 2: "two", 3: "three", 4: "four",
179
- 5: "five", 6: "six", 7: "seven", 8: "eight",
180
- 9: "nine", 10: "ten", 11: "eleven", 12: "twelve"
181
- }
182
-
183
- # 收集所有家具類型的統計
184
- furniture_items = []
185
- furniture_counts = []
186
-
187
- furniture_types = ["chair", "dining table", "couch", "bed"]
188
- for furniture_type in furniture_types:
189
- if furniture_type in object_statistics:
190
- count = object_statistics[furniture_type]["count"]
191
- if count > 0:
192
- furniture_items.append(furniture_type)
193
- furniture_counts.append(count)
194
-
195
- # 使用穩健性決策邏輯
196
- use_specific, main_furniture, main_count = self._should_use_specific_furniture_description(
197
- furniture_items, furniture_counts, object_statistics
198
- )
199
-
200
- # 椅子的特殊處理
201
- if "chair" in object_statistics:
202
- chair_count = object_statistics["chair"]["count"]
203
-
204
- if use_specific and main_furniture == "chair":
205
- # 使用具體的椅子描述
206
- if chair_count == 1:
207
- replacements["seating"] = "a chair"
208
- replacements["furniture"] = "a chair"
209
- elif chair_count in number_words:
210
- word_count = number_words[chair_count]
211
- replacements["seating"] = f"{word_count} chairs"
212
- replacements["furniture"] = f"{word_count} chairs"
213
- elif chair_count <= 20:
214
- replacements["seating"] = "several chairs"
215
- replacements["furniture"] = "several chairs"
216
- else:
217
- replacements["seating"] = f"numerous chairs ({chair_count} total)"
218
- replacements["furniture"] = "numerous chairs"
219
-
220
- self.logger.debug(f"Using specific chair description: {replacements.get('furniture', 'N/A')}")
221
-
222
- else:
223
- # 使用通用家具描述
224
- total_furniture = sum(furniture_counts)
225
- if total_furniture == 1:
226
- replacements["furniture"] = "a furniture piece"
227
- elif total_furniture in number_words:
228
- word_count = number_words[total_furniture]
229
- replacements["furniture"] = f"{word_count} furniture pieces"
230
- else:
231
- replacements["furniture"] = f"several furniture pieces"
232
-
233
- # 但椅子的 seating 描述保持具體
234
- if chair_count in number_words:
235
- word_count = number_words[chair_count]
236
- replacements["seating"] = f"{word_count} chairs"
237
- else:
238
- replacements["seating"] = "several chairs"
239
-
240
- self.logger.debug(f"Using generic furniture description: {replacements.get('furniture', 'N/A')}")
241
-
242
- # 處理混合家具情況的額外邏輯
243
- if len(furniture_items) > 1 and "furniture" not in replacements:
244
- # 當有多種家具但沒有主導類型時的後備邏輯
245
- total_count = sum(furniture_counts)
246
- if total_count in number_words:
247
- word_count = number_words[total_count]
248
- replacements["furniture"] = f"{word_count} furniture pieces"
249
- else:
250
- replacements["furniture"] = "multiple furniture pieces"
251
 
252
- def generate_places365_replacements(self, places365_info):
253
- """
254
- 基於Places365信息生成模板替換內容
255
  """
256
  replacements = {}
257
 
258
  if not places365_info or places365_info.get('confidence', 0) <= 0.35:
259
  replacements["places365_context"] = ""
 
260
  return replacements
261
 
262
  try:
263
- scene_class = places365_info.get('scene_class', '').lower()
264
- confidence = places365_info.get('confidence', 0.0)
265
-
266
- # 基於場景類別添加上下文信息
267
- if 'kitchen' in scene_class:
268
- replacements["places365_context"] = "kitchen environment"
269
- replacements["area_description"] = "culinary space"
270
- elif 'bedroom' in scene_class:
271
- replacements["places365_context"] = "sleeping area"
272
- replacements["area_description"] = "rest space"
273
- elif 'living' in scene_class or 'room' in scene_class:
274
- replacements["places365_context"] = "living area"
275
- replacements["area_description"] = "comfortable space"
276
- elif 'office' in scene_class:
277
- replacements["places365_context"] = "work environment"
278
- replacements["area_description"] = "professional workspace"
279
- elif 'street' in scene_class or 'road' in scene_class:
280
- replacements["places365_context"] = "urban street"
281
- replacements["area_description"] = "city thoroughfare"
282
-
283
- self.logger.debug(f"Generated Places365 context: {replacements.get('places365_context', 'none')}")
284
 
285
  except Exception as e:
286
  self.logger.warning(f"Error generating Places365 replacements: {str(e)}")
 
 
287
 
288
  return replacements
289
 
 
4
  class StatisticsProcessor:
5
  """
6
  統計分析處理器 - 負責複雜的物件統計分析和數據轉換
7
+
8
+ 此類別專門處理物件統計信息的深度分析、Places365信息處理,
9
+ 以及基於統計數據生成替換內容的複雜邏輯。
10
  """
11
 
12
+ def __init__(self):
13
  """初始化統計分析處理器"""
14
  self.logger = logging.getLogger(self.__class__.__name__)
15
+ self.logger.debug("StatisticsProcessor initialized successfully")
16
+
17
+ def generate_statistics_replacements(self, object_statistics: Optional[Dict]) -> Dict[str, str]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  """
19
  基於物體統計信息生成模板替換內容
20
+
21
  Args:
22
  object_statistics: 物體統計信息
23
+
24
  Returns:
25
  Dict[str, str]: 統計信息基礎的替換內容
26
  """
 
30
  return replacements
31
 
32
  try:
 
 
 
33
  # 處理植物元素
34
+ if "potted plant" in object_statistics:
35
+ count = object_statistics["potted plant"]["count"]
36
  if count == 1:
37
  replacements["plant_elements"] = "a potted plant"
38
  elif count <= 3:
 
40
  else:
41
  replacements["plant_elements"] = f"multiple potted plants ({count} total)"
42
 
43
+ # 處理座位(椅子)相關
44
+ if "chair" in object_statistics:
45
+ count = object_statistics["chair"]["count"]
46
+
47
+ # 使用統一的數字轉換邏輯
48
+ number_words = {
49
+ 1: "one", 2: "two", 3: "three", 4: "four",
50
+ 5: "five", 6: "six", 7: "seven", 8: "eight",
51
+ 9: "nine", 10: "ten", 11: "eleven", 12: "twelve"
52
+ }
53
+
54
+ if count == 1:
55
+ replacements["seating"] = "a chair"
56
+ replacements["furniture"] = "a chair"
57
+ elif count in number_words:
58
+ word_count = number_words[count]
59
+ replacements["seating"] = f"{word_count} chairs"
60
+ replacements["furniture"] = f"{word_count} chairs"
61
+ elif count <= 20:
62
+ replacements["seating"] = f"several chairs"
63
+ replacements["furniture"] = f"several chairs"
64
+ else:
65
+ replacements["seating"] = f"numerous chairs ({count} total)"
66
+ replacements["furniture"] = f"numerous chairs"
67
+
68
+ # 處理混合家具情況(當存在多種家具類型時)
69
+ furniture_items = []
70
+ furniture_counts = []
71
+
72
+ # 收集所有家具類型的統計
73
+ for furniture_type in ["chair", "dining table", "couch", "bed"]:
74
+ if furniture_type in object_statistics:
75
+ count = object_statistics[furniture_type]["count"]
76
+ if count > 0:
77
+ furniture_items.append(furniture_type)
78
+ furniture_counts.append(count)
79
+
80
+ # 如果只有椅子,那就用上面的方式
81
+ # 如果有多種家具類型,生成組合描述
82
+ if len(furniture_items) > 1 and "furniture" not in replacements:
83
+ main_furniture = furniture_items[0] # 數量最多的家具類型
84
+ main_count = furniture_counts[0]
85
+
86
+ if main_furniture == "chair":
87
+ number_words = ["", "one", "two", "three", "four", "five", "six"]
88
+ if main_count <= 6:
89
+ replacements["furniture"] = f"{number_words[main_count]} chairs and other furniture"
90
+ else:
91
+ replacements["furniture"] = "multiple chairs and other furniture"
92
+
93
  # 處理人員
94
+ if "person" in object_statistics:
95
+ count = object_statistics["person"]["count"]
96
  if count == 1:
97
  replacements["people_and_vehicles"] = "a person"
98
  replacements["pedestrian_flow"] = "an individual walking"
 
103
  replacements["people_and_vehicles"] = f"many people ({count} individuals)"
104
  replacements["pedestrian_flow"] = f"a crowd of {count} people"
105
 
106
+ # 處理桌子設置
107
+ if "dining table" in object_statistics:
108
+ count = object_statistics["dining table"]["count"]
109
  if count == 1:
110
  replacements["table_setup"] = "a dining table"
111
  replacements["table_description"] = "a dining surface"
 
113
  replacements["table_setup"] = f"{count} dining tables"
114
  replacements["table_description"] = f"{count} dining surfaces"
115
 
116
+ self.logger.debug(f"Generated {len(replacements)} statistics-based replacements")
117
 
118
  except Exception as e:
119
  self.logger.warning(f"Error generating statistics replacements: {str(e)}")
120
 
121
  return replacements
122
 
123
+ def generate_places365_replacements(self, places365_info: Optional[Dict]) -> Dict[str, str]:
124
  """
125
+ 基於Places365信息生成模板替換內容
126
+
 
127
  Args:
128
+ places365_info: Places365場景分類信息
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
+ Returns:
131
+ Dict[str, str]: Places365基礎的替換內容
 
132
  """
133
  replacements = {}
134
 
135
  if not places365_info or places365_info.get('confidence', 0) <= 0.35:
136
  replacements["places365_context"] = ""
137
+ replacements["places365_atmosphere"] = ""
138
  return replacements
139
 
140
  try:
141
+ scene_label = places365_info.get('scene_label', '').replace('_', ' ')
142
+ attributes = places365_info.get('attributes', [])
143
+
144
+ # 生成場景上下文
145
+ if scene_label:
146
+ replacements["places365_context"] = f"characteristic of a {scene_label}"
147
+ else:
148
+ replacements["places365_context"] = ""
149
+
150
+ # 生成氛圍描述
151
+ if 'natural_lighting' in attributes:
152
+ replacements["places365_atmosphere"] = "with natural illumination"
153
+ elif 'artificial_lighting' in attributes:
154
+ replacements["places365_atmosphere"] = "under artificial lighting"
155
+ else:
156
+ replacements["places365_atmosphere"] = ""
157
+
158
+ self.logger.debug("Generated Places365-based replacements")
 
 
 
159
 
160
  except Exception as e:
161
  self.logger.warning(f"Error generating Places365 replacements: {str(e)}")
162
+ replacements["places365_context"] = ""
163
+ replacements["places365_atmosphere"] = ""
164
 
165
  return replacements
166