- Frontend v4 accessible sur réseau local (192.168.1.40) - Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard) - Ollama GPU fonctionnel - Self-healing interactif - Dashboard confiance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
157 lines
5.1 KiB
Python
157 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test du Détecteur Hybride OpenCV + VLM
|
|
|
|
Ce script teste l'approche hybride qui combine:
|
|
- OpenCV pour détecter rapidement les régions
|
|
- VLM pour classifier intelligemment chaque région
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
import time
|
|
|
|
# Ajouter le répertoire parent au path
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
from core.detection.ui_detector_hybrid import HybridUIDetector, DetectionConfig, create_hybrid_detector
|
|
from core.detection.ollama_client import check_ollama_available
|
|
|
|
|
|
def test_hybrid_detection(screenshot_path: str):
|
|
"""Tester la détection hybride"""
|
|
print("=" * 80)
|
|
print("TEST: Détection Hybride OpenCV + VLM")
|
|
print("=" * 80)
|
|
|
|
# Vérifier qu'Ollama est disponible
|
|
print("\n1. Vérification d'Ollama...")
|
|
ollama_available = check_ollama_available()
|
|
if ollama_available:
|
|
print("✓ Ollama est disponible - VLM sera utilisé pour la classification")
|
|
else:
|
|
print("⚠ Ollama non disponible - Fallback vers classification basique")
|
|
|
|
# Créer le détecteur hybride
|
|
print("\n2. Initialisation du détecteur hybride...")
|
|
detector = create_hybrid_detector(
|
|
vlm_model="qwen3-vl:8b",
|
|
confidence_threshold=0.7, # Seuil production (évite faux positifs)
|
|
use_vlm=ollama_available
|
|
)
|
|
print("✓ Détecteur hybride initialisé")
|
|
|
|
# Détecter les éléments
|
|
print(f"\n3. Détection des éléments dans: {screenshot_path}")
|
|
print("-" * 80)
|
|
|
|
start_time = time.time()
|
|
elements = detector.detect(screenshot_path)
|
|
detection_time = time.time() - start_time
|
|
|
|
print("-" * 80)
|
|
print(f"\n✓ Détection terminée en {detection_time:.2f}s")
|
|
print(f"✓ {len(elements)} éléments détectés")
|
|
|
|
if len(elements) == 0:
|
|
print("\n⚠ Aucun élément détecté!")
|
|
return False
|
|
|
|
# Afficher les résultats
|
|
print("\n4. Éléments détectés:")
|
|
print("=" * 80)
|
|
|
|
for i, elem in enumerate(elements, 1):
|
|
print(f"\n{i}. {elem.type.upper()} - {elem.role}")
|
|
print(f" Label: {elem.label or '(aucun)'}")
|
|
print(f" Position: ({elem.bbox[0]}, {elem.bbox[1]})")
|
|
print(f" Taille: {elem.bbox[2]}x{elem.bbox[3]}")
|
|
print(f" Centre: {elem.center}")
|
|
print(f" Confiance: {elem.confidence:.2%}")
|
|
print(f" Détecté par: {elem.metadata.get('detected_by', 'unknown')}")
|
|
print(f" Méthode: {elem.metadata.get('detection_method', 'unknown')}")
|
|
|
|
# Statistiques
|
|
print("\n" + "=" * 80)
|
|
print("STATISTIQUES:")
|
|
print(f" Temps total: {detection_time:.2f}s")
|
|
print(f" Temps/élément: {detection_time/len(elements):.3f}s")
|
|
|
|
types_count = {}
|
|
roles_count = {}
|
|
methods_count = {}
|
|
|
|
for elem in elements:
|
|
types_count[elem.type] = types_count.get(elem.type, 0) + 1
|
|
roles_count[elem.role] = roles_count.get(elem.role, 0) + 1
|
|
method = elem.metadata.get('detection_method', 'unknown')
|
|
methods_count[method] = methods_count.get(method, 0) + 1
|
|
|
|
print("\nTypes d'éléments:")
|
|
for elem_type, count in sorted(types_count.items()):
|
|
print(f" - {elem_type}: {count}")
|
|
|
|
print("\nRôles sémantiques:")
|
|
for role, count in sorted(roles_count.items()):
|
|
print(f" - {role}: {count}")
|
|
|
|
print("\nMéthodes de détection:")
|
|
for method, count in sorted(methods_count.items()):
|
|
print(f" - {method}: {count}")
|
|
|
|
avg_confidence = sum(e.confidence for e in elements) / len(elements)
|
|
print(f"\nConfiance moyenne: {avg_confidence:.2%}")
|
|
|
|
print("\n" + "=" * 80)
|
|
print("✓ Test de détection hybride réussi!")
|
|
print("=" * 80)
|
|
|
|
return True
|
|
|
|
|
|
def compare_with_pure_vlm():
|
|
"""Comparer l'approche hybride avec le VLM pur"""
|
|
print("\n" + "=" * 80)
|
|
print("COMPARAISON: Hybride vs VLM Pur")
|
|
print("=" * 80)
|
|
|
|
# TODO: Implémenter comparaison si nécessaire
|
|
print("\n⚠ Comparaison non implémentée")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print("\n🚀 Test du Détecteur Hybride\n")
|
|
|
|
# Vérifier les arguments
|
|
if len(sys.argv) > 1:
|
|
screenshot_path = sys.argv[1]
|
|
else:
|
|
# Utiliser le screenshot de test par défaut
|
|
screenshot_path = "rpa_vision_v3/examples/test_ui_screenshot.png"
|
|
if not Path(screenshot_path).exists():
|
|
print(f"❌ Screenshot de test non trouvé: {screenshot_path}")
|
|
print("\nUsage: python test_hybrid_detection.py <screenshot_path>")
|
|
sys.exit(1)
|
|
|
|
# Vérifier que le fichier existe
|
|
if not Path(screenshot_path).exists():
|
|
print(f"❌ Le fichier {screenshot_path} n'existe pas")
|
|
sys.exit(1)
|
|
|
|
# Lancer le test
|
|
success = test_hybrid_detection(screenshot_path)
|
|
|
|
# Résumé
|
|
print("\n" + "=" * 80)
|
|
print("RÉSUMÉ")
|
|
print("=" * 80)
|
|
print(f"Détection hybride: {'✓ PASS' if success else '❌ FAIL'}")
|
|
print("=" * 80)
|
|
|
|
if success:
|
|
print("\n🎉 Test réussi!")
|
|
sys.exit(0)
|
|
else:
|
|
print("\n⚠ Test échoué")
|
|
sys.exit(1)
|