|
|
""" |
|
|
Modèles de données pour l'application Detection |
|
|
Créé par Marino ATOHOUN - FireWatch AI Project |
|
|
""" |
|
|
from django.db import models |
|
|
from django.utils import timezone |
|
|
import uuid |
|
|
import os |
|
|
|
|
|
|
|
|
def upload_to_images(instance, filename): |
|
|
"""Fonction pour définir le chemin d'upload des images""" |
|
|
ext = filename.split('.')[-1] |
|
|
filename = f"{uuid.uuid4()}.{ext}" |
|
|
return os.path.join('uploads/images/', filename) |
|
|
|
|
|
|
|
|
def upload_to_videos(instance, filename): |
|
|
"""Fonction pour définir le chemin d'upload des vidéos""" |
|
|
ext = filename.split('.')[-1] |
|
|
filename = f"{uuid.uuid4()}.{ext}" |
|
|
return os.path.join('uploads/videos/', filename) |
|
|
|
|
|
|
|
|
def upload_to_results(instance, filename): |
|
|
"""Fonction pour définir le chemin d'upload des résultats""" |
|
|
ext = filename.split('.')[-1] |
|
|
filename = f"result_{uuid.uuid4()}.{ext}" |
|
|
return os.path.join('results/', filename) |
|
|
|
|
|
|
|
|
class Contact(models.Model): |
|
|
""" |
|
|
Modèle pour stocker les messages de contact |
|
|
Par Marino ATOHOUN |
|
|
""" |
|
|
name = models.CharField(max_length=100, verbose_name="Nom") |
|
|
email = models.EmailField(verbose_name="Email") |
|
|
message = models.TextField(verbose_name="Message") |
|
|
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Date de création") |
|
|
is_read = models.BooleanField(default=False, verbose_name="Lu") |
|
|
|
|
|
class Meta: |
|
|
verbose_name = "Contact" |
|
|
verbose_name_plural = "Contacts" |
|
|
ordering = ['-created_at'] |
|
|
|
|
|
def __str__(self): |
|
|
return f"Message de {self.name} ({self.email}) - {self.created_at.strftime('%d/%m/%Y %H:%M')}" |
|
|
|
|
|
|
|
|
class DetectionSession(models.Model): |
|
|
""" |
|
|
Modèle pour stocker les sessions de détection |
|
|
Par Marino ATOHOUN |
|
|
""" |
|
|
DETECTION_TYPES = [ |
|
|
('image', 'Image'), |
|
|
('video', 'Vidéo'), |
|
|
('camera', 'Caméra'), |
|
|
] |
|
|
|
|
|
session_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) |
|
|
detection_type = models.CharField(max_length=10, choices=DETECTION_TYPES, verbose_name="Type de détection") |
|
|
original_file = models.FileField(upload_to=upload_to_images, null=True, blank=True, verbose_name="Fichier original") |
|
|
result_file = models.FileField(upload_to=upload_to_results, null=True, blank=True, verbose_name="Fichier résultat") |
|
|
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Date de création") |
|
|
processing_time = models.FloatField(null=True, blank=True, verbose_name="Temps de traitement (secondes)") |
|
|
is_processed = models.BooleanField(default=False, verbose_name="Traité") |
|
|
|
|
|
class Meta: |
|
|
verbose_name = "Session de détection" |
|
|
verbose_name_plural = "Sessions de détection" |
|
|
ordering = ['-created_at'] |
|
|
|
|
|
def __str__(self): |
|
|
return f"Session {self.session_id} - {self.get_detection_type_display()} - {self.created_at.strftime('%d/%m/%Y %H:%M')}" |
|
|
|
|
|
|
|
|
class Detection(models.Model): |
|
|
""" |
|
|
Modèle pour stocker les résultats de détection individuels |
|
|
Par Marino ATOHOUN |
|
|
""" |
|
|
DETECTION_CLASSES = [ |
|
|
('fire', 'Incendie'), |
|
|
('smoke', 'Fumée'), |
|
|
('person', 'Personne'), |
|
|
('intrusion', 'Intrusion'), |
|
|
('vehicle', 'Véhicule'), |
|
|
('other', 'Autre'), |
|
|
] |
|
|
|
|
|
session = models.ForeignKey(DetectionSession, on_delete=models.CASCADE, related_name='detections') |
|
|
class_name = models.CharField(max_length=20, choices=DETECTION_CLASSES, verbose_name="Classe détectée") |
|
|
confidence = models.FloatField(verbose_name="Confiance") |
|
|
bbox_x = models.FloatField(verbose_name="Boîte englobante X") |
|
|
bbox_y = models.FloatField(verbose_name="Boîte englobante Y") |
|
|
bbox_width = models.FloatField(verbose_name="Largeur boîte englobante") |
|
|
bbox_height = models.FloatField(verbose_name="Hauteur boîte englobante") |
|
|
frame_number = models.IntegerField(default=0, verbose_name="Numéro de frame (pour vidéo)") |
|
|
timestamp = models.FloatField(null=True, blank=True, verbose_name="Timestamp (pour vidéo)") |
|
|
|
|
|
class Meta: |
|
|
verbose_name = "Détection" |
|
|
verbose_name_plural = "Détections" |
|
|
ordering = ['-session__created_at', 'frame_number'] |
|
|
|
|
|
def __str__(self): |
|
|
return f"{self.get_class_name_display()} - {self.confidence:.2%} - Session {self.session.session_id}" |
|
|
|
|
|
@property |
|
|
def bbox_dict(self): |
|
|
"""Retourne la bounding box sous forme de dictionnaire""" |
|
|
return { |
|
|
'x': self.bbox_x, |
|
|
'y': self.bbox_y, |
|
|
'width': self.bbox_width, |
|
|
'height': self.bbox_height |
|
|
} |
|
|
|
|
|
|
|
|
class AIModelStatus(models.Model): |
|
|
""" |
|
|
Modèle pour suivre le statut des modèles IA |
|
|
Par Marino ATOHOUN |
|
|
""" |
|
|
MODEL_TYPES = [ |
|
|
('fire', 'Modèle Incendie'), |
|
|
('intrusion', 'Modèle Intrusion'), |
|
|
] |
|
|
|
|
|
model_type = models.CharField(max_length=20, choices=MODEL_TYPES, unique=True, verbose_name="Type de modèle") |
|
|
model_path = models.CharField(max_length=500, verbose_name="Chemin du modèle") |
|
|
is_loaded = models.BooleanField(default=False, verbose_name="Modèle chargé") |
|
|
last_loaded = models.DateTimeField(null=True, blank=True, verbose_name="Dernière fois chargé") |
|
|
model_version = models.CharField(max_length=50, null=True, blank=True, verbose_name="Version du modèle") |
|
|
accuracy = models.FloatField(null=True, blank=True, verbose_name="Précision du modèle") |
|
|
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Date de création") |
|
|
updated_at = models.DateTimeField(auto_now=True, verbose_name="Date de mise à jour") |
|
|
|
|
|
class Meta: |
|
|
verbose_name = "Statut du modèle IA" |
|
|
verbose_name_plural = "Statuts des modèles IA" |
|
|
|
|
|
def __str__(self): |
|
|
status = "Chargé" if self.is_loaded else "Non chargé" |
|
|
return f"{self.get_model_type_display()} - {status}" |
|
|
|
|
|
|