- Move test scripts to tests/ directory for better organization - Add improved YOLOv5 postprocessing with reference implementation - Update gitignore to exclude *.mflow files and include main.spec - Add debug capabilities and coordinate scaling improvements - Enhance multi-series support with proper validation - Add AGENTS.md documentation and example utilities 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
149 lines
5.4 KiB
Python
149 lines
5.4 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Debug script to investigate abnormal detection results.
|
||
檢查異常偵測結果的調試腳本。
|
||
"""
|
||
|
||
import sys
|
||
import os
|
||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||
|
||
from core.functions.Multidongle import BoundingBox, ObjectDetectionResult
|
||
|
||
def analyze_detection_result(result: ObjectDetectionResult):
|
||
"""分析偵測結果,找出異常情況"""
|
||
print("=== DETECTION RESULT ANALYSIS ===")
|
||
print(f"Class count: {result.class_count}")
|
||
print(f"Box count: {result.box_count}")
|
||
|
||
if not result.box_list:
|
||
print("No bounding boxes found.")
|
||
return
|
||
|
||
# 統計分析
|
||
class_counts = {}
|
||
coordinate_issues = []
|
||
score_issues = []
|
||
|
||
for i, box in enumerate(result.box_list):
|
||
# 統計每個類別的數量
|
||
class_counts[box.class_name] = class_counts.get(box.class_name, 0) + 1
|
||
|
||
# 檢查座標問題
|
||
if box.x1 < 0 or box.y1 < 0 or box.x2 < 0 or box.y2 < 0:
|
||
coordinate_issues.append(f"Box {i}: Negative coordinates ({box.x1},{box.y1},{box.x2},{box.y2})")
|
||
|
||
if box.x1 >= box.x2 or box.y1 >= box.y2:
|
||
coordinate_issues.append(f"Box {i}: Invalid box dimensions ({box.x1},{box.y1},{box.x2},{box.y2})")
|
||
|
||
if box.x1 == box.x2 and box.y1 == box.y2:
|
||
coordinate_issues.append(f"Box {i}: Zero-area box ({box.x1},{box.y1},{box.x2},{box.y2})")
|
||
|
||
# 檢查分數問題
|
||
if box.score < 0 or box.score > 1:
|
||
score_issues.append(f"Box {i}: Unusual score {box.score} for {box.class_name}")
|
||
|
||
# 報告結果
|
||
print("\n--- CLASS DISTRIBUTION ---")
|
||
for class_name, count in sorted(class_counts.items()):
|
||
if count > 50: # 標記異常高的數量
|
||
print(f"⚠ {class_name}: {count} (ABNORMALLY HIGH)")
|
||
else:
|
||
print(f"✓ {class_name}: {count}")
|
||
|
||
print(f"\n--- COORDINATE ISSUES ({len(coordinate_issues)}) ---")
|
||
for issue in coordinate_issues[:10]: # 只顯示前10個
|
||
print(f"⚠ {issue}")
|
||
if len(coordinate_issues) > 10:
|
||
print(f"... and {len(coordinate_issues) - 10} more coordinate issues")
|
||
|
||
print(f"\n--- SCORE ISSUES ({len(score_issues)}) ---")
|
||
for issue in score_issues[:10]: # 只顯示前10個
|
||
print(f"⚠ {issue}")
|
||
if len(score_issues) > 10:
|
||
print(f"... and {len(score_issues) - 10} more score issues")
|
||
|
||
# 建議
|
||
print("\n--- RECOMMENDATIONS ---")
|
||
if any(count > 50 for count in class_counts.values()):
|
||
print("⚠ Abnormally high detection counts suggest:")
|
||
print(" 1. Model output format mismatch")
|
||
print(" 2. Confidence threshold too low")
|
||
print(" 3. Test/debug mode accidentally enabled")
|
||
|
||
if coordinate_issues:
|
||
print("⚠ Coordinate issues suggest:")
|
||
print(" 1. Coordinate transformation problems")
|
||
print(" 2. Model output scaling issues")
|
||
print(" 3. Hardware preprocessing info missing")
|
||
|
||
if score_issues:
|
||
print("⚠ Score issues suggest:")
|
||
print(" 1. Score values might be in log space")
|
||
print(" 2. Wrong score interpretation")
|
||
print(" 3. Need score normalization")
|
||
|
||
def create_mock_problematic_result():
|
||
"""創建一個模擬的有問題的偵測結果用於測試"""
|
||
boxes = []
|
||
|
||
# 模擬您遇到的問題
|
||
class_names = ['person', 'bicycle', 'car', 'motorbike', 'aeroplane', 'bus', 'toothbrush', 'hair drier']
|
||
|
||
# 添加大量異常的邊界框
|
||
for i in range(100):
|
||
box = BoundingBox(
|
||
x1=i % 5, # 很小的座標
|
||
y1=(i + 1) % 4,
|
||
x2=(i + 2) % 6,
|
||
y2=(i + 3) % 5,
|
||
score=2.0 + (i * 0.1), # 異常的分數值
|
||
class_num=i % len(class_names),
|
||
class_name=class_names[i % len(class_names)]
|
||
)
|
||
boxes.append(box)
|
||
|
||
return ObjectDetectionResult(
|
||
class_count=len(class_names),
|
||
box_count=len(boxes),
|
||
box_list=boxes
|
||
)
|
||
|
||
def suggest_fixes():
|
||
"""提供修復建議"""
|
||
print("\n=== SUGGESTED FIXES ===")
|
||
|
||
print("\n1. 檢查模型配置:")
|
||
print(" - 確認使用正確的後處理類型(YOLO_V3, YOLO_V5, etc.)")
|
||
print(" - 檢查類別名稱列表是否正確")
|
||
print(" - 驗證信心閾值設定(建議 0.3-0.7)")
|
||
|
||
print("\n2. 檢查座標轉換:")
|
||
print(" - 確認模型輸出格式(中心座標 vs 角點座標)")
|
||
print(" - 檢查圖片尺寸縮放")
|
||
print(" - 驗證硬體預處理信息")
|
||
|
||
print("\n3. 添加結果過濾:")
|
||
print(" - 過濾無效座標的邊界框")
|
||
print(" - 限制每個類別的最大檢測數量")
|
||
print(" - 添加 NMS(非極大值抑制)")
|
||
|
||
print("\n4. 調試步驟:")
|
||
print(" - 添加詳細的調試日誌")
|
||
print(" - 檢查原始模型輸出")
|
||
print(" - 測試不同的後處理參數")
|
||
|
||
if __name__ == "__main__":
|
||
print("Detection Issues Debug Tool")
|
||
print("=" * 50)
|
||
|
||
# 測試與您遇到類似問題的模擬結果
|
||
print("Testing with mock problematic result...")
|
||
mock_result = create_mock_problematic_result()
|
||
analyze_detection_result(mock_result)
|
||
|
||
suggest_fixes()
|
||
|
||
print("\nTo use this tool with real results:")
|
||
print("from debug_detection_issues import analyze_detection_result")
|
||
print("analyze_detection_result(your_detection_result)") |