- Remove session-ses_2f27.md (161KB raw session log) - Remove 49 ROOT_* duplicate files across REFERENCE/ - Remove 14 duplicate files between REFERENCE/ root and history/ - Remove asr_legacy.rs (dead code, replaced by asr.rs) - Remove src/core/worker/ (duplicate JobWorker) - Remove src/core/layers/ (empty directory) - Remove 4 .bak files in src/ - Remove 7 dead private methods in worker/processor.rs - Remove backup directory from git tracking
114 lines
3.3 KiB
Python
114 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
簡單人臉統計
|
|
"""
|
|
|
|
import psycopg2
|
|
from datetime import datetime
|
|
|
|
|
|
def get_simple_stats():
|
|
"""獲取簡單統計"""
|
|
conn = psycopg2.connect(
|
|
host="localhost",
|
|
port=5432,
|
|
database="momentry",
|
|
user="accusys",
|
|
password="accusys",
|
|
)
|
|
|
|
cursor = conn.cursor()
|
|
|
|
# 總體統計
|
|
cursor.execute("""
|
|
SELECT
|
|
COUNT(*) as total_faces,
|
|
SUM(CASE WHEN attributes->>'gender' = 'male' THEN 1 ELSE 0 END) as male_count,
|
|
SUM(CASE WHEN attributes->>'gender' = 'female' THEN 1 ELSE 0 END) as female_count,
|
|
ROUND(AVG(CASE WHEN attributes->>'age' ~ '^[0-9]+$' THEN (attributes->>'age')::numeric ELSE NULL END)::numeric, 1) as avg_age,
|
|
MIN(CASE WHEN attributes->>'age' ~ '^[0-9]+$' THEN (attributes->>'age')::numeric ELSE NULL END) as min_age,
|
|
MAX(CASE WHEN attributes->>'age' ~ '^[0-9]+$' THEN (attributes->>'age')::numeric ELSE NULL END) as max_age
|
|
FROM face_detections
|
|
""")
|
|
|
|
total_stats = cursor.fetchone()
|
|
|
|
# 按視頻統計
|
|
cursor.execute("""
|
|
SELECT
|
|
video_uuid,
|
|
COUNT(*) as total_faces
|
|
FROM face_detections
|
|
GROUP BY video_uuid
|
|
ORDER BY total_faces DESC
|
|
""")
|
|
|
|
video_stats = cursor.fetchall()
|
|
|
|
cursor.close()
|
|
conn.close()
|
|
|
|
return total_stats, video_stats
|
|
|
|
|
|
def main():
|
|
print("=" * 60)
|
|
print("人臉識別統計報告")
|
|
print("=" * 60)
|
|
print(f"生成時間: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
print()
|
|
|
|
try:
|
|
total_stats, video_stats = get_simple_stats()
|
|
|
|
total_faces, male_count, female_count, avg_age, min_age, max_age = total_stats
|
|
|
|
print("📊 總體統計")
|
|
print("-" * 40)
|
|
print(f"總人臉數: {total_faces}")
|
|
print(f"男性: {male_count} ({male_count / total_faces * 100:.1f}%)")
|
|
print(f"女性: {female_count} ({female_count / total_faces * 100:.1f}%)")
|
|
print(f"平均年齡: {avg_age} 歲")
|
|
print(f"年齡範圍: {min_age} - {max_age} 歲")
|
|
print()
|
|
|
|
print("🎬 視頻統計")
|
|
print("-" * 40)
|
|
|
|
video_names = {
|
|
"384b0ff44aaaa1f1": "Old_Time_Movie_Show_-_Charade_1963.HD.mov",
|
|
"9760d0820f0cf9a7": "ExaSAN PCIe series - Director Ou Yu-Zhi Shares His Experience.mp4",
|
|
}
|
|
|
|
for video_uuid, face_count in video_stats:
|
|
video_name = video_names.get(video_uuid, video_uuid)
|
|
print(f"{video_name}:")
|
|
print(f" UUID: {video_uuid}")
|
|
print(f" 檢測到人臉: {face_count}")
|
|
print()
|
|
|
|
print("=" * 60)
|
|
print()
|
|
|
|
# 直接回答問題
|
|
print("📝 問題回答:")
|
|
print("-" * 40)
|
|
print("Q: 這兩個影片內有幾個人?")
|
|
print(f"A: 總共檢測到 {total_faces} 個人臉")
|
|
print()
|
|
print("Q: 幾男幾女?")
|
|
print(f"A: 男性 {male_count} 人 ({male_count / total_faces * 100:.1f}%)")
|
|
print(f" 女性 {female_count} 人 ({female_count / total_faces * 100:.1f}%)")
|
|
print()
|
|
print("Q: 平均年齡?")
|
|
print(f"A: 平均 {avg_age} 歲 (範圍: {min_age}-{max_age}歲)")
|
|
print()
|
|
print("=" * 60)
|
|
|
|
except Exception as e:
|
|
print(f"❌ 獲取統計數據時出錯: {e}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|