Spaces:
Running
on
Zero
Running
on
Zero
File size: 10,293 Bytes
e6a18b7 |
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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
import logging
import traceback
from typing import Dict, Any, Optional
class ConfidenceManager:
"""
專門管理信心度相關邏輯,包括動態閾值調整、信心度乘數管理和地標類型特定的閾值處理
"""
def __init__(self):
"""
初始化置信度管理器
"""
self.logger = logging.getLogger(__name__)
# 初始化批處理參數
self.batch_size = 16 # 默認批處理大小
# 置信度閾值乘數配置
self.confidence_threshold_multipliers = {
"close_up": 0.9, # 近景標準閾值
"partial": 0.6, # 部分可見降低閾值要求
"distant": 0.5, # 遠景更低閾值要求
"full_image": 0.7 # 整張圖像需要更高閾值
}
# 地標類型閾值配置
self.landmark_type_thresholds = {
"tower": 0.5, # 塔型建築需要更高閾值
"skyscraper": 0.4, # 摩天大樓使用較低閾值
"building": 0.55, # 一般的建築物閾值略微降低
"monument": 0.5, # 紀念碑閾值
"natural": 0.6 # 自然景觀可以使用較低閾值
}
def set_batch_size(self, batch_size: int):
"""
設置批處理大小
Args:
batch_size: 新的批處理大小
"""
self.batch_size = max(1, batch_size)
self.logger.info(f"Batch size set to {self.batch_size}")
def adjust_confidence_threshold(self, detection_type: str, multiplier: float):
"""
調整特定檢測類型的信心度的threshold
Args:
detection_type: 檢測類型 ('close_up', 'partial', 'distant', 'full_image')
multiplier: 置信度閾值乘數
"""
if detection_type in self.confidence_threshold_multipliers:
self.confidence_threshold_multipliers[detection_type] = max(0.1, min(1.5, multiplier))
self.logger.info(f"Adjusted confidence threshold multiplier for {detection_type} to {multiplier}")
else:
self.logger.warning(f"Unknown detection type: {detection_type}")
def get_detection_type_multiplier(self, detection_type: str) -> float:
"""
獲取檢測類型的置信度乘數
Args:
detection_type: 檢測類型
Returns:
float: 置信度乘數
"""
return self.confidence_threshold_multipliers.get(detection_type, 1.0)
def get_landmark_type_threshold(self, landmark_type: str) -> float:
"""
獲取地標類型的閾值
Args:
landmark_type: 地標類型
Returns:
float: 地標類型閾值
"""
return self.landmark_type_thresholds.get(landmark_type, 0.5)
def calculate_adjusted_threshold(self, base_threshold: float, detection_type: str) -> float:
"""
根據檢測類型計算調整後的閾值
Args:
base_threshold: 基礎閾值
detection_type: 檢測type
Returns:
float: 調整後的閾值
"""
try:
base_multiplier = self.get_detection_type_multiplier(detection_type)
adjusted_threshold = base_threshold * base_multiplier
return adjusted_threshold
except Exception as e:
self.logger.error(f"Error calculating adjusted threshold: {e}")
self.logger.error(traceback.format_exc())
return base_threshold
def calculate_final_threshold(self, base_threshold: float, detection_type: str,
landmark_type: str) -> float:
"""
計算最終閾值,結合檢測類型和地標類型
Args:
base_threshold: 基礎閾值
detection_type: 檢測type
landmark_type: 地標type
Returns:
float: 最終閾值
"""
try:
# 根據檢測類型調整
adjusted_threshold = self.calculate_adjusted_threshold(base_threshold, detection_type)
# 根據地標類型進一步調整
if landmark_type == "distinctive":
# 特殊建築的閾值降低25%
type_multiplier = 0.75
else:
# 使用已有的類型閾值
type_multiplier = self.get_landmark_type_threshold(landmark_type) / 0.5
final_threshold = adjusted_threshold * type_multiplier
return final_threshold
except Exception as e:
self.logger.error(f"Error calculating final threshold: {e}")
self.logger.error(traceback.format_exc())
return base_threshold
def evaluate_confidence(self, confidence: float, threshold: float) -> bool:
"""
評估置信度是否達到閾值
Args:
confidence: 信心度score
threshold: 閾值
Returns:
bool: 是否達到閾值
"""
return confidence >= threshold
def apply_architectural_boost(self, confidence: float, architectural_analysis: Dict[str, Any],
landmark_id: str) -> float:
"""
根據建築特徵分析調整信心度
Args:
confidence: 原始置信度
architectural_analysis: 建築特徵分析結果
landmark_id: 地標ID
Returns:
float: 調整後的信心度
"""
try:
confidence_boost = 0
landmark_id_lower = landmark_id.lower()
top_features = architectural_analysis.get("architectural_features", [])
primary_category = architectural_analysis.get("primary_category", "")
# 使用主要建築類別來調整置信度,使用通用條件而非特定地標名稱
if primary_category == "tower" and any(term in landmark_id_lower for term in ["tower", "spire", "needle"]):
confidence_boost += 0.05
elif primary_category == "skyscraper" and any(term in landmark_id_lower for term in ["building", "skyscraper", "tall"]):
confidence_boost += 0.05
elif primary_category == "historical" and any(term in landmark_id_lower for term in ["monument", "castle", "palace", "temple"]):
confidence_boost += 0.05
elif primary_category == "distinctive" and any(term in landmark_id_lower for term in ["unusual", "unique", "special", "famous"]):
confidence_boost += 0.05
# 根據特定特徵進一步微調,使用通用特徵描述而非特定地標
for feature, score in top_features:
if feature == "time_display" and "clock" in landmark_id_lower:
confidence_boost += 0.03
elif feature == "segmented_exterior" and "segmented" in landmark_id_lower:
confidence_boost += 0.03
elif feature == "slanted_design" and "leaning" in landmark_id_lower:
confidence_boost += 0.03
# 應用信心度調整
if confidence_boost > 0:
adjusted_confidence = confidence + confidence_boost
self.logger.info(f"Boosted confidence by {confidence_boost:.2f} based on architectural features ({primary_category})")
return adjusted_confidence
return confidence
except Exception as e:
self.logger.error(f"Error applying architectural boost: {e}")
self.logger.error(traceback.format_exc())
return confidence
def determine_detection_type_from_region(self, region_width: int, region_height: int,
image_width: int, image_height: int) -> str:
"""
根據區域大小自動判斷檢測類型
Args:
region_width: 區域寬度
region_height: 區域高度
image_width: 圖像寬度
image_height: 圖像高度
Returns:
str: 檢測類型
"""
try:
region_area_ratio = (region_width * region_height) / (image_width * image_height)
if region_area_ratio > 0.5:
return "close_up"
elif region_area_ratio > 0.2:
return "partial"
else:
return "distant"
except Exception as e:
self.logger.error(f"Error determining detection type from region: {e}")
self.logger.error(traceback.format_exc())
return "partial"
def adjust_detection_type_by_viewpoint(self, detection_type: str, dominant_viewpoint: str) -> str:
"""
根據視角調整檢測類型
Args:
detection_type: 原始檢測類型
dominant_viewpoint: 主要視角
Returns:
str: 調整後的檢測類型
"""
try:
if dominant_viewpoint == "close_up" and detection_type != "close_up":
return "close_up"
elif dominant_viewpoint == "distant" and detection_type != "distant":
return "distant"
elif dominant_viewpoint == "angled_view":
return "partial" # 角度視圖可能是部分可見
else:
return detection_type
except Exception as e:
self.logger.error(f"Error adjusting detection type by viewpoint: {e}")
self.logger.error(traceback.format_exc())
return detection_type
def get_batch_size(self) -> int:
"""
獲取當前批處理大小
Returns:
int: 批處理大小
"""
return self.batch_size
def get_all_threshold_multipliers(self) -> Dict[str, float]:
"""
獲取所有置信度閾值乘數
Returns:
Dict[str, float]: 閾值乘數字典
"""
return self.confidence_threshold_multipliers.copy()
def get_all_landmark_type_thresholds(self) -> Dict[str, float]:
"""
獲取所有地標類型閾值
Returns:
Dict[str, float]: 地標類型閾值字典
"""
return self.landmark_type_thresholds.copy()
|