|
import requests
|
|
import json
|
|
from pathlib import Path
|
|
|
|
|
|
API_URL = "http://localhost:8000"
|
|
IMAGE_PATH = "examples/input/cam3.jpg"
|
|
|
|
VIDEO_PATH = "examples/input/FootDrone.mp4"
|
|
|
|
|
|
cam3_line_dict = {
|
|
"Big rect. right top": [
|
|
{"x": 1342.8861505076343, "y": 1076.997434976179},
|
|
{"x": 1484.7446330310781, "y": 906.3705391217808}
|
|
],
|
|
"Big rect. right main": [
|
|
{"x": 1484.7446330310781, "y": 906.3705391217808},
|
|
{"x": 1049.6210183678218, "y": 748.0287797688992},
|
|
{"x": 828.6491513601493, "y": 668.8579000924583},
|
|
{"x": 349.8767728435256, "y": 500.9610345717304},
|
|
{"x": 32.736572890025556, "y": 397.21988189225624}
|
|
],
|
|
"Big rect. right bottom": [
|
|
{"x": 32.736572890025556, "y": 397.21988189225624},
|
|
{"x": 0.3753980224568448, "y": 407.0286292126068}
|
|
],
|
|
"Small rect. right top": [
|
|
{"x": 312.24913494809687, "y": 1075.6461846681693},
|
|
{"x": 426.66666666666663, "y": 999.9279904137233}
|
|
],
|
|
"Small rect. right main": [
|
|
{"x": 426.66666666666663, "y": 999.9279904137233},
|
|
{"x": 0, "y": 769.079837198949}
|
|
],
|
|
"Circle right": [
|
|
{"x": 828.6491513601493, "y": 668.8579000924583},
|
|
{"x": 821.7759602949911, "y": 612.2830792373484},
|
|
{"x": 782.8739995106773, "y": 564.5621490047902},
|
|
{"x": 722.6387053930304, "y": 529.3993583071158},
|
|
{"x": 623.5014504910696, "y": 503.02726528386006},
|
|
{"x": 494.24654853028534, "y": 492.980753655953},
|
|
{"x": 349.8767728435256, "y": 500.9610345717304}
|
|
],
|
|
"Side line bottom": [
|
|
{"x": 2.0193824656299317, "y": 266.2605192109321},
|
|
{"x": 399.0443993689428, "y": 186.14824976426013},
|
|
{"x": 645.5533017804819, "y": 132.93313314748357},
|
|
{"x": 1001.1088573360372, "y": 53.39824942655338},
|
|
{"x": 1208.1676808654488, "y": 7.351737798646435}
|
|
],
|
|
"Middle line": [
|
|
{"x": 645.5533017804819, "y": 132.93313314748357},
|
|
{"x": 1106.0585089650835, "y": 200.22939899146556},
|
|
{"x": 1580.7388158704541, "y": 269.8451725000601},
|
|
{"x": 1917.6527118636336, "y": 318.9857185061268}
|
|
],
|
|
"Circle central": [
|
|
{"x": 1580.7388158704541, "y": 269.8451725000601},
|
|
{"x": 1580.7388158704541, "y": 269.8451725000601},
|
|
{"x": 1533.8366024891266, "y": 288.8643838246303},
|
|
{"x": 1441.810458698277, "y": 302.46903498742097},
|
|
{"x": 1316.3202626198458, "y": 304.5620582432349},
|
|
{"x": 1219.0653606590615, "y": 292.0039187083512},
|
|
{"x": 1135.4052299401073, "y": 274.2132210339326},
|
|
{"x": 1069.522876998931, "y": 237.5853140571884},
|
|
{"x": 1106.0585089650835, "y": 200.22939899146556},
|
|
{"x": 1139.5882364760548, "y": 189.4457791734675},
|
|
{"x": 1224.2941188289963, "y": 177.9341512664908},
|
|
{"x": 1314.2287593518718, "y": 174.79461638276985},
|
|
{"x": 1392.6601319008914, "y": 180.02717452230473},
|
|
{"x": 1465.8627462799764, "y": 190.49229080137454},
|
|
{"x": 1529.6535959531789, "y": 204.09694196416518},
|
|
{"x": 1581.9411776525253, "y": 230.2597326618396},
|
|
{"x": 1580.7388158704541, "y": 269.8451725000601}
|
|
],
|
|
"Side line left": [
|
|
{"x": 1208.1676808654488, "y": 7.351737798646435},
|
|
{"x": 1401.9652021886754, "y": 20.565213248502545},
|
|
{"x": 1582.3573590514204, "y": 30.37625976013045},
|
|
{"x": 1679.416182580832, "y": 34.300678364781604},
|
|
{"x": 1824.5142217965183, "y": 41.23091697692868},
|
|
{"x": 1918.6318688553417, "y": 42.21202162809147}
|
|
],
|
|
"Big rect. left bottom": [
|
|
{"x": 1401.9652021886754, "y": 20.565213248502545},
|
|
{"x": 1283.3377512082834, "y": 53.98527744204496}
|
|
],
|
|
"Big rect. left main": [
|
|
{"x": 1283.3377512082834, "y": 53.98527744204496},
|
|
{"x": 1510.7887316004399, "y": 73.60737046530076},
|
|
{"x": 1808.8279472867146, "y": 94.21056813971936},
|
|
{"x": 1918.6318688553417, "y": 100.0971960466961}
|
|
],
|
|
"Circle left": [
|
|
{"x": 1510.7887316004399, "y": 73.60737046530076},
|
|
{"x": 1548.0436335612244, "y": 86.36173093041702},
|
|
{"x": 1620.5926531690673, "y": 95.19167279088215},
|
|
{"x": 1681.3769668945574, "y": 97.15388209320773},
|
|
{"x": 1746.0828492474989, "y": 100.0971960466961},
|
|
{"x": 1808.8279472867146, "y": 94.21056813971936}
|
|
],
|
|
"Small rect. left bottom": [
|
|
{"x": 1550.9848100318127, "y": 42.21202162809147},
|
|
{"x": 1582.3573590514204, "y": 30.37625976013045}
|
|
],
|
|
"Small rect. left main": [
|
|
{"x": 1550.9848100318127, "y": 42.21202162809147},
|
|
{"x": 1918.418689198772, "y": 60.49417894940041}
|
|
]
|
|
}
|
|
|
|
def test_health():
|
|
"""Test du health check"""
|
|
try:
|
|
response = requests.get(f"{API_URL}/health")
|
|
print(f"Health check: {response.status_code} - {response.json()}")
|
|
return response.status_code == 200
|
|
except requests.exceptions.ConnectionError:
|
|
print("❌ Impossible de se connecter à l'API. Vérifiez qu'elle est démarrée.")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ Erreur health check: {e}")
|
|
return False
|
|
|
|
def test_calibration():
|
|
"""Test de l'API de calibration avec lignes manuelles"""
|
|
if not Path(IMAGE_PATH).exists():
|
|
print(f"❌ Image non trouvée: {IMAGE_PATH}")
|
|
print(f" Chemin absolu: {Path(IMAGE_PATH).absolute()}")
|
|
return
|
|
|
|
print(f"📁 Test avec l'image: {IMAGE_PATH}")
|
|
print(f" Taille du fichier: {Path(IMAGE_PATH).stat().st_size} bytes")
|
|
|
|
try:
|
|
with open(IMAGE_PATH, 'rb') as image_file:
|
|
files = {'image': (Path(IMAGE_PATH).name, image_file, 'image/jpeg')}
|
|
data = {'lines_data': json.dumps(cam3_line_dict)}
|
|
|
|
print("🚀 Envoi de la requête de calibration...")
|
|
response = requests.post(
|
|
f"{API_URL}/calibrate",
|
|
files=files,
|
|
data=data
|
|
)
|
|
|
|
print(f"📡 Réponse reçue: {response.status_code}")
|
|
|
|
if response.status_code == 200:
|
|
result = response.json()
|
|
print("✅ Calibration réussie!")
|
|
print("Paramètres de la caméra:")
|
|
print(json.dumps(result['camera_parameters'], indent=2))
|
|
else:
|
|
print(f"❌ Erreur calibration: {response.status_code}")
|
|
try:
|
|
error_detail = response.json()
|
|
print(f"Détail de l'erreur: {error_detail}")
|
|
except:
|
|
print(f"Réponse brute: {response.text}")
|
|
|
|
except Exception as e:
|
|
print(f"❌ Exception lors du test de calibration: {e}")
|
|
|
|
def test_inference_image():
|
|
"""Test de l'inférence automatique sur image"""
|
|
if not Path(IMAGE_PATH).exists():
|
|
print(f"❌ Image non trouvée: {IMAGE_PATH}")
|
|
print(f" Chemin absolu: {Path(IMAGE_PATH).absolute()}")
|
|
return
|
|
|
|
print(f"📁 Test inférence avec l'image: {IMAGE_PATH}")
|
|
print(f" Taille du fichier: {Path(IMAGE_PATH).stat().st_size} bytes")
|
|
|
|
try:
|
|
with open(IMAGE_PATH, 'rb') as image_file:
|
|
files = {'image': (Path(IMAGE_PATH).name, image_file, 'image/jpeg')}
|
|
data = {
|
|
'kp_threshold': 0.15,
|
|
'line_threshold': 0.15
|
|
}
|
|
|
|
print("🚀 Envoi de la requête d'inférence image...")
|
|
response = requests.post(
|
|
f"{API_URL}/inference/image",
|
|
files=files,
|
|
data=data
|
|
)
|
|
|
|
print(f"📡 Réponse reçue: {response.status_code}")
|
|
print(f"📡 Réponse reçue: {response.json()}")
|
|
|
|
if response.status_code == 200 and response.json()['status'] == 'success':
|
|
result = response.json()
|
|
print("✅ Inférence image réussie!")
|
|
print(f"Status: {result['status']}")
|
|
print(f"Image info: {result['image_info']}")
|
|
if result['camera_parameters']:
|
|
print("Paramètres de la caméra:")
|
|
cam_params = result['camera_parameters'].get('cam_params', {})
|
|
print(f" Position: {cam_params.get('position_meters', 'N/A')}")
|
|
print(f" Focale X: {cam_params.get('x_focal_length', 'N/A')}")
|
|
print(f" Focale Y: {cam_params.get('y_focal_length', 'N/A')}")
|
|
else:
|
|
print(f"❌ Erreur inférence image: {response.status_code}")
|
|
try:
|
|
error_detail = response.json()
|
|
print(f"Détail de l'erreur: {error_detail}")
|
|
except:
|
|
print(f"Réponse brute: {response.text}")
|
|
|
|
except Exception as e:
|
|
print(f"❌ Exception lors du test d'inférence image: {e}")
|
|
|
|
def test_inference_video():
|
|
"""Test de l'inférence automatique sur vidéo"""
|
|
if not Path(VIDEO_PATH).exists():
|
|
print(f"❌ Vidéo non trouvée: {VIDEO_PATH}")
|
|
print(f" Chemin absolu: {Path(VIDEO_PATH).absolute()}")
|
|
return
|
|
|
|
print(f"📁 Test inférence avec la vidéo: {VIDEO_PATH}")
|
|
print(f" Taille du fichier: {Path(VIDEO_PATH).stat().st_size} bytes")
|
|
print("🎬 Test inférence vidéo (peut prendre du temps...)")
|
|
|
|
try:
|
|
with open(VIDEO_PATH, 'rb') as video_file:
|
|
files = {'video': (Path(VIDEO_PATH).name, video_file, 'video/mp4')}
|
|
data = {
|
|
'kp_threshold': 0.15,
|
|
'line_threshold': 0.15,
|
|
'frame_step': 200
|
|
}
|
|
|
|
print("🚀 Envoi de la requête d'inférence vidéo...")
|
|
response = requests.post(
|
|
f"{API_URL}/inference/video",
|
|
files=files,
|
|
data=data
|
|
)
|
|
|
|
print(f"📡 Réponse reçue: {response.status_code}")
|
|
|
|
if response.status_code == 200:
|
|
result = response.json()
|
|
print("✅ Inférence vidéo réussie!")
|
|
print(f"Status: {result['status']}")
|
|
print(f"Frames traitées: {result['frames_processed']}")
|
|
print(f"Vidéo info: {result['video_info']}")
|
|
|
|
if result['camera_parameters']:
|
|
print(f"\n=== Exemples de paramètres ===")
|
|
for i, params in enumerate(result['camera_parameters'][:3]):
|
|
frame_num = params.get('frame_number', i)
|
|
timestamp = params.get('timestamp_seconds', 0)
|
|
print(f"Frame {frame_num} (t={timestamp:.2f}s):")
|
|
if 'cam_params' in params:
|
|
cam_params = params['cam_params']
|
|
print(f" Position: {cam_params.get('position_meters', 'N/A')}")
|
|
print(f" Focales: X={cam_params.get('x_focal_length', 'N/A')}, Y={cam_params.get('y_focal_length', 'N/A')}")
|
|
|
|
if len(result['camera_parameters']) > 3:
|
|
print(f"... et {len(result['camera_parameters']) - 3} autres frames")
|
|
else:
|
|
print(f"❌ Erreur inférence vidéo: {response.status_code}")
|
|
try:
|
|
error_detail = response.json()
|
|
print(f"Détail de l'erreur: {error_detail}")
|
|
except:
|
|
print(f"Réponse brute: {response.text}")
|
|
|
|
except Exception as e:
|
|
print(f"❌ Exception lors du test d'inférence vidéo: {e}")
|
|
|
|
def test_all():
|
|
"""Lance tous les tests"""
|
|
print("=== TEST DE L'API FOOTBALL VISION ===\n")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("4. Test Inférence Image (automatique)")
|
|
test_inference_image()
|
|
print()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
test_all() |