- Update ASR, face, OCR, pose processors - Add release pre-flight check script - Add synonym generation, chunk processing scripts - Add face recognition, stamp search utilities
235 lines
6.8 KiB
Python
235 lines
6.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
測試人臉識別 API 端點
|
|
"""
|
|
|
|
import requests
|
|
import json
|
|
import base64
|
|
import cv2
|
|
import numpy as np
|
|
import sys
|
|
import os
|
|
|
|
# API 配置
|
|
API_BASE_URL = "http://localhost:3002"
|
|
API_KEY = "muser_7ff810b88d6440c6ab31094ecae7dc32_1774870448_54b7c8e9"
|
|
|
|
|
|
def create_headers():
|
|
"""創建帶有 API 密鑰的請求頭部"""
|
|
return {"X-API-Key": API_KEY, "Content-Type": "application/json"}
|
|
|
|
|
|
def test_health():
|
|
"""測試健康檢查端點"""
|
|
print("測試健康檢查端點...")
|
|
try:
|
|
response = requests.get(f"{API_BASE_URL}/health")
|
|
if response.status_code == 200:
|
|
print(f"✅ 健康檢查通過: {response.json()}")
|
|
return True
|
|
else:
|
|
print(f"❌ 健康檢查失敗: {response.status_code}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ 健康檢查異常: {e}")
|
|
return False
|
|
|
|
|
|
def test_list_faces():
|
|
"""測試列出人臉端點"""
|
|
print("\n測試列出人臉端點...")
|
|
try:
|
|
response = requests.get(
|
|
f"{API_BASE_URL}/api/v1/face/list", headers=create_headers()
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
print(f"✅ 列出人臉成功: 找到 {len(data.get('faces', []))} 個人臉")
|
|
return True
|
|
else:
|
|
print(f"❌ 列出人臉失敗: {response.status_code} - {response.text}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ 列出人臉異常: {e}")
|
|
return False
|
|
|
|
|
|
def test_recognize_faces():
|
|
"""測試人臉識別端點"""
|
|
print("\n測試人臉識別端點...")
|
|
|
|
# 下載測試圖像
|
|
try:
|
|
import urllib.request
|
|
|
|
test_image_url = "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/lena.jpg"
|
|
test_image_path = "/tmp/lena_api_test.jpg"
|
|
|
|
if not os.path.exists(test_image_path):
|
|
print("下載測試圖像...")
|
|
urllib.request.urlretrieve(test_image_url, test_image_path)
|
|
|
|
# 讀取圖像並轉換為 base64
|
|
image = cv2.imread(test_image_path)
|
|
if image is None:
|
|
print("❌ 無法讀取測試圖像")
|
|
return False
|
|
|
|
# 將圖像轉換為 base64
|
|
_, buffer = cv2.imencode(".jpg", image)
|
|
image_base64 = base64.b64encode(buffer).decode("utf-8")
|
|
|
|
# 準備請求數據
|
|
request_data = {
|
|
"image": image_base64,
|
|
"image_format": "jpg",
|
|
"threshold": 0.6,
|
|
"max_faces": 10,
|
|
}
|
|
|
|
response = requests.post(
|
|
f"{API_BASE_URL}/api/v1/face/recognize",
|
|
headers=create_headers(),
|
|
json=request_data,
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
faces = data.get("faces", [])
|
|
print(f"✅ 人臉識別成功: 檢測到 {len(faces)} 個人臉")
|
|
|
|
if len(faces) > 0:
|
|
for i, face in enumerate(faces):
|
|
print(f" 人臉 {i + 1}:")
|
|
print(
|
|
f" - 位置: x={face.get('x')}, y={face.get('y')}, width={face.get('width')}, height={face.get('height')}"
|
|
)
|
|
print(f" - 置信度: {face.get('confidence', 0):.4f}")
|
|
if "identity" in face and face["identity"]:
|
|
print(f" - 身份: {face['identity']}")
|
|
|
|
return True
|
|
else:
|
|
print(f"❌ 人臉識別失敗: {response.status_code} - {response.text}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ 人臉識別異常: {e}")
|
|
import traceback
|
|
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
|
|
def test_search_faces():
|
|
"""測試人臉搜索端點"""
|
|
print("\n測試人臉搜索端點...")
|
|
|
|
# 創建一個測試向量
|
|
test_vector = [0.1] * 512 # 512 維向量
|
|
|
|
request_data = {"vector": test_vector, "threshold": 0.5, "limit": 5}
|
|
|
|
try:
|
|
response = requests.post(
|
|
f"{API_BASE_URL}/api/v1/face/search",
|
|
headers=create_headers(),
|
|
json=request_data,
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
matches = data.get("matches", [])
|
|
print(f"✅ 人臉搜索成功: 找到 {len(matches)} 個匹配")
|
|
return True
|
|
else:
|
|
print(f"❌ 人臉搜索失敗: {response.status_code} - {response.text}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ 人臉搜索異常: {e}")
|
|
return False
|
|
|
|
|
|
def test_video_list():
|
|
"""測試視頻列表端點"""
|
|
print("\n測試視頻列表端點...")
|
|
try:
|
|
response = requests.get(
|
|
f"{API_BASE_URL}/api/v1/videos", headers=create_headers()
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
videos = data.get("videos", [])
|
|
print(f"✅ 視頻列表成功: 找到 {len(videos)} 個視頻")
|
|
|
|
if len(videos) > 0:
|
|
for i, video in enumerate(videos[:2]): # 只顯示前兩個
|
|
print(
|
|
f" 視頻 {i + 1}: {video.get('file_name')} (UUID: {video.get('uuid')})"
|
|
)
|
|
|
|
return True
|
|
else:
|
|
print(f"❌ 視頻列表失敗: {response.status_code} - {response.text}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ 視頻列表異常: {e}")
|
|
return False
|
|
|
|
|
|
def main():
|
|
"""主測試函數"""
|
|
print("=" * 60)
|
|
print("人臉識別 API 測試")
|
|
print("=" * 60)
|
|
|
|
tests = [
|
|
("健康檢查", test_health),
|
|
("視頻列表", test_video_list),
|
|
("列出人臉", test_list_faces),
|
|
("人臉識別", test_recognize_faces),
|
|
("人臉搜索", test_search_faces),
|
|
]
|
|
|
|
results = []
|
|
|
|
for test_name, test_func in tests:
|
|
print(f"\n{test_name}:")
|
|
print("-" * 40)
|
|
try:
|
|
success = test_func()
|
|
results.append((test_name, success))
|
|
except Exception as e:
|
|
print(f"❌ {test_name} 測試異常: {e}")
|
|
results.append((test_name, False))
|
|
|
|
# 顯示測試結果
|
|
print("\n" + "=" * 60)
|
|
print("測試結果摘要")
|
|
print("=" * 60)
|
|
|
|
passed = 0
|
|
for test_name, success in results:
|
|
status = "✅ 通過" if success else "❌ 失敗"
|
|
print(f"{test_name}: {status}")
|
|
if success:
|
|
passed += 1
|
|
|
|
print(f"\n總計: {passed}/{len(results)} 個測試通過")
|
|
|
|
if passed == len(results):
|
|
print("\n🎉 所有 API 測試通過!")
|
|
else:
|
|
print(f"\n⚠️ 有 {len(results) - passed} 個測試失敗")
|
|
|
|
return passed == len(results)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
success = main()
|
|
sys.exit(0 if success else 1)
|