#!/usr/bin/env python3 """ Quick fixes for detection result issues. 快速修復偵測結果問題的補丁程式。 """ import sys import os sys.path.append(os.path.dirname(os.path.abspath(__file__))) def apply_quick_fixes(): """應用快速修復到檢測結果""" print("=== 快速修復偵測結果問題 ===") print() # 修復建議 fixes = [ { "issue": "過多的偵測結果 (100+ 物件)", "cause": "可能的原因:模型輸出格式不匹配、閾值太低、測試模式", "solutions": [ "1. 提高信心閾值到 0.5-0.7", "2. 添加檢測數量限制", "3. 檢查是否在測試/調試模式", "4. 驗證模型輸出格式" ] }, { "issue": "座標異常 (0,0 或負值)", "cause": "可能的原因:座標轉換錯誤、輸出格式不匹配", "solutions": [ "1. 檢查座標轉換邏輯", "2. 驗證輸入圖片尺寸", "3. 確認模型輸出格式", "4. 添加座標有效性檢查" ] }, { "issue": "LiveView 卡頓", "cause": "可能的原因:處理過多檢測結果導致渲染瓶頸", "solutions": [ "1. 限制顯示的檢測數量", "2. 降低 FPS 或跳幀顯示", "3. 異步處理檢測結果", "4. 優化渲染代碼" ] } ] for fix in fixes: print(f"問題: {fix['issue']}") print(f"原因: {fix['cause']}") print("解決方案:") for solution in fix['solutions']: print(f" {solution}") print() # 立即可用的代碼修復 print("=== 立即可用的代碼修復 ===") print() print("1. 在 Multidongle.py 的 _process_yolo_generic 函數開頭添加:") print(""" # 緊急修復:限制檢測數量 MAX_DETECTIONS = 50 if len(boxes) > MAX_DETECTIONS: print(f"WARNING: Too many detections ({len(boxes)}), limiting to {MAX_DETECTIONS}") boxes = sorted(boxes, key=lambda x: x.score, reverse=True)[:MAX_DETECTIONS] """) print("\n2. 在創建 BoundingBox 之前添加驗證:") print(""" # 座標有效性檢查 if x1 < 0 or y1 < 0 or x1 >= x2 or y1 >= y2: continue # 跳過無效的邊界框 if (x2 - x1) * (y2 - y1) < 4: # 最小面積 continue # 跳過太小的框 if best_score > 2.0: # 檢查異常分數 continue # 跳過異常分數 """) print("\n3. 在 PostProcessorOptions 中設置更嚴格的參數:") print(""" postprocess_options = PostProcessorOptions( postprocess_type=PostProcessType.YOLO_V5, threshold=0.6, # 提高閾值 class_names=["person", "bicycle", "car", "motorbike", "aeroplane"], nms_threshold=0.4, max_detections_per_class=10 # 限制每類檢測數量 ) """) print("\n4. 添加檢測結果統計和警告:") print(""" # 在函數結尾添加 class_counts = {} for box in boxes: class_counts[box.class_name] = class_counts.get(box.class_name, 0) + 1 for class_name, count in class_counts.items(): if count > 20: print(f"WARNING: Abnormally high count for {class_name}: {count}") """) def create_emergency_filter(): """創建緊急過濾函數""" filter_code = ''' def emergency_filter_detections(boxes, max_total=50, max_per_class=10): """緊急過濾檢測結果""" if len(boxes) <= max_total: return boxes # 按類別分組 from collections import defaultdict class_groups = defaultdict(list) for box in boxes: class_groups[box.class_name].append(box) # 每類保留最高分數的檢測 filtered = [] for class_name, class_boxes in class_groups.items(): class_boxes.sort(key=lambda x: x.score, reverse=True) keep_count = min(len(class_boxes), max_per_class) filtered.extend(class_boxes[:keep_count]) # 總數限制 if len(filtered) > max_total: filtered.sort(key=lambda x: x.score, reverse=True) filtered = filtered[:max_total] return filtered ''' with open("emergency_filter.py", "w", encoding="utf-8") as f: f.write(filter_code) print("緊急過濾函數已保存到 emergency_filter.py") if __name__ == "__main__": apply_quick_fixes() create_emergency_filter() print("\n=== 下一步建議 ===") print("1. 檢查當前的後處理配置") print("2. 調整信心閾值和檢測限制") print("3. 使用 debug_detection_issues.py 分析結果") print("4. 考慮使用 improved_yolo_postprocessing.py 中的改進版本") print("5. 如果問題持續,請檢查模型文件和配置")