Update app.py
Browse files
app.py
CHANGED
|
@@ -1201,6 +1201,125 @@ def init_database():
|
|
| 1201 |
finally:
|
| 1202 |
if conn:
|
| 1203 |
conn.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1204 |
|
| 1205 |
# ------------------------------
|
| 1206 |
# 6. INTERFACE GRADIO
|
|
@@ -1252,7 +1371,7 @@ with gr.Blocks(title="🚗 Système de Reconnaissance de Véhicules Algériens",
|
|
| 1252 |
|
| 1253 |
# Ajout du lecteur vidéo compact (initialement caché)
|
| 1254 |
video_player = gr.Video(
|
| 1255 |
-
visible=
|
| 1256 |
label="Aperçu vidéo",
|
| 1257 |
interactive=False,
|
| 1258 |
height=150 # Hauteur réduite pour un espace compact
|
|
@@ -1276,6 +1395,8 @@ with gr.Blocks(title="🚗 Système de Reconnaissance de Véhicules Algériens",
|
|
| 1276 |
|
| 1277 |
with gr.Row():
|
| 1278 |
next_frame_btn = gr.Button("Next Frame", visible=False)
|
|
|
|
|
|
|
| 1279 |
|
| 1280 |
|
| 1281 |
with gr.Column():
|
|
@@ -1312,6 +1433,7 @@ with gr.Blocks(title="🚗 Système de Reconnaissance de Véhicules Algériens",
|
|
| 1312 |
algerian_check_output = gr.Textbox(label="Origine", scale=2)
|
| 1313 |
action_output = gr.Textbox(label="Action recommandée", scale=3)
|
| 1314 |
|
|
|
|
| 1315 |
# Page de gestion d'accès
|
| 1316 |
with gr.Tab("Access Management", id="access"):
|
| 1317 |
with gr.Column():
|
|
@@ -1342,7 +1464,7 @@ with gr.Blocks(title="🚗 Système de Reconnaissance de Véhicules Algériens",
|
|
| 1342 |
with gr.Column():
|
| 1343 |
with gr.Row():
|
| 1344 |
refresh_db_btn = gr.Button("🔄 Refresh", variant="secondary")
|
| 1345 |
-
export_csv_btn = gr.Button("📤
|
| 1346 |
export_db_btn = gr.Button("💾 Exporter DB", variant="secondary")
|
| 1347 |
|
| 1348 |
db_table = gr.Dataframe(
|
|
@@ -1635,6 +1757,10 @@ with gr.Blocks(title="🚗 Système de Reconnaissance de Véhicules Algériens",
|
|
| 1635 |
logo_output, model_output,
|
| 1636 |
plate_classification, vehicle_type_output]
|
| 1637 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1638 |
|
| 1639 |
# Connecter les nouveaux composants
|
| 1640 |
time_range.change(
|
|
|
|
| 1201 |
finally:
|
| 1202 |
if conn:
|
| 1203 |
conn.close()
|
| 1204 |
+
def process_video_frame(frame):
|
| 1205 |
+
"""Traiter un frame vidéo avec toutes les détections"""
|
| 1206 |
+
# Charger le frame
|
| 1207 |
+
shared_results["img_rgb"] = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
| 1208 |
+
shared_results["img_draw"] = shared_results["img_rgb"].copy()
|
| 1209 |
+
|
| 1210 |
+
# Exécuter toutes les détections
|
| 1211 |
+
detect_vehicle()
|
| 1212 |
+
detect_color()
|
| 1213 |
+
detect_orientation()
|
| 1214 |
+
detect_logo_and_model()
|
| 1215 |
+
detect_plate()
|
| 1216 |
+
|
| 1217 |
+
# Retourner le frame annoté
|
| 1218 |
+
return shared_results["img_draw"]
|
| 1219 |
+
|
| 1220 |
+
def save_modified_video():
|
| 1221 |
+
"""Sauvegarder la vidéo annotée avec toutes les détections"""
|
| 1222 |
+
if not shared_results.get("video_path"):
|
| 1223 |
+
raise gr.Error("Aucune vidéo chargée")
|
| 1224 |
+
|
| 1225 |
+
# Préparer le writer vidéo
|
| 1226 |
+
cap = cv2.VideoCapture(shared_results["video_path"])
|
| 1227 |
+
if not cap.isOpened():
|
| 1228 |
+
raise gr.Error("Impossible de lire la vidéo source")
|
| 1229 |
+
|
| 1230 |
+
fps = cap.get(cv2.CAP_PROP_FPS)
|
| 1231 |
+
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
| 1232 |
+
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
| 1233 |
+
|
| 1234 |
+
# Créer un fichier temporaire pour la sortie
|
| 1235 |
+
temp_dir = tempfile.gettempdir()
|
| 1236 |
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 1237 |
+
output_path = os.path.join(temp_dir, f"annotated_{timestamp}.mp4")
|
| 1238 |
+
|
| 1239 |
+
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
| 1240 |
+
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
|
| 1241 |
+
|
| 1242 |
+
frame_count = 0
|
| 1243 |
+
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
| 1244 |
+
progress = gr.Progress()
|
| 1245 |
+
|
| 1246 |
+
try:
|
| 1247 |
+
while True:
|
| 1248 |
+
ret, frame = cap.read()
|
| 1249 |
+
if not ret:
|
| 1250 |
+
break
|
| 1251 |
+
|
| 1252 |
+
progress(frame_count / total_frames, f"Traitement du frame {frame_count}/{total_frames}")
|
| 1253 |
+
|
| 1254 |
+
# Utiliser le frame pré-annoté si disponible
|
| 1255 |
+
if frame_count in shared_results.get("modified_frames", {}):
|
| 1256 |
+
annotated_frame = np.array(shared_results["modified_frames"][frame_count])
|
| 1257 |
+
else:
|
| 1258 |
+
# Traiter le frame en temps réel si non déjà annoté
|
| 1259 |
+
shared_results["img_rgb"] = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
| 1260 |
+
shared_results["img_draw"] = shared_results["img_rgb"].copy()
|
| 1261 |
+
shared_results["frame_count"] = frame_count
|
| 1262 |
+
|
| 1263 |
+
# Exécuter toutes les détections
|
| 1264 |
+
detect_vehicle()
|
| 1265 |
+
detect_color()
|
| 1266 |
+
detect_orientation()
|
| 1267 |
+
detect_logo_and_model()
|
| 1268 |
+
detect_plate()
|
| 1269 |
+
|
| 1270 |
+
annotated_frame = shared_results["img_draw"]
|
| 1271 |
+
|
| 1272 |
+
# Convertir et écrire le frame
|
| 1273 |
+
out.write(cv2.cvtColor(annotated_frame, cv2.COLOR_RGB2BGR))
|
| 1274 |
+
frame_count += 1
|
| 1275 |
+
|
| 1276 |
+
except Exception as e:
|
| 1277 |
+
raise gr.Error(f"Erreur lors de la sauvegarde: {str(e)}")
|
| 1278 |
+
finally:
|
| 1279 |
+
cap.release()
|
| 1280 |
+
out.release()
|
| 1281 |
+
|
| 1282 |
+
# Vérifier que la vidéo a bien été créée
|
| 1283 |
+
if not os.path.exists(output_path):
|
| 1284 |
+
raise gr.Error("Échec de la création de la vidéo")
|
| 1285 |
+
|
| 1286 |
+
return output_path
|
| 1287 |
+
|
| 1288 |
+
def process_and_save_video():
|
| 1289 |
+
"""Traiter et sauvegarder la vidéo annotée"""
|
| 1290 |
+
if not shared_results.get("video_path"):
|
| 1291 |
+
raise gr.Error("Aucune vidéo chargée")
|
| 1292 |
+
|
| 1293 |
+
# Créer un fichier temporaire pour la sortie
|
| 1294 |
+
output_path = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False).name
|
| 1295 |
+
|
| 1296 |
+
cap = cv2.VideoCapture(shared_results["video_path"])
|
| 1297 |
+
fps = cap.get(cv2.CAP_PROP_FPS)
|
| 1298 |
+
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
| 1299 |
+
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
| 1300 |
+
|
| 1301 |
+
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
| 1302 |
+
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
|
| 1303 |
+
|
| 1304 |
+
frame_count = 0
|
| 1305 |
+
while True:
|
| 1306 |
+
ret, frame = cap.read()
|
| 1307 |
+
if not ret:
|
| 1308 |
+
break
|
| 1309 |
+
|
| 1310 |
+
# Si le frame a été modifié, utiliser la version annotée
|
| 1311 |
+
if frame_count in shared_results.get("modified_frames", {}):
|
| 1312 |
+
annotated_frame = np.array(shared_results["modified_frames"][frame_count])
|
| 1313 |
+
out.write(cv2.cvtColor(annotated_frame, cv2.COLOR_RGB2BGR))
|
| 1314 |
+
else:
|
| 1315 |
+
out.write(frame)
|
| 1316 |
+
|
| 1317 |
+
frame_count += 1
|
| 1318 |
+
|
| 1319 |
+
cap.release()
|
| 1320 |
+
out.release()
|
| 1321 |
+
|
| 1322 |
+
return output_path
|
| 1323 |
|
| 1324 |
# ------------------------------
|
| 1325 |
# 6. INTERFACE GRADIO
|
|
|
|
| 1371 |
|
| 1372 |
# Ajout du lecteur vidéo compact (initialement caché)
|
| 1373 |
video_player = gr.Video(
|
| 1374 |
+
visible=True,
|
| 1375 |
label="Aperçu vidéo",
|
| 1376 |
interactive=False,
|
| 1377 |
height=150 # Hauteur réduite pour un espace compact
|
|
|
|
| 1395 |
|
| 1396 |
with gr.Row():
|
| 1397 |
next_frame_btn = gr.Button("Next Frame", visible=False)
|
| 1398 |
+
save_video_btn = gr.Button("Save Video", visible=True, variant="primary")
|
| 1399 |
+
saved_video = gr.Video(label="annotated video saved", visible= True, interactive=False)
|
| 1400 |
|
| 1401 |
|
| 1402 |
with gr.Column():
|
|
|
|
| 1433 |
algerian_check_output = gr.Textbox(label="Origine", scale=2)
|
| 1434 |
action_output = gr.Textbox(label="Action recommandée", scale=3)
|
| 1435 |
|
| 1436 |
+
|
| 1437 |
# Page de gestion d'accès
|
| 1438 |
with gr.Tab("Access Management", id="access"):
|
| 1439 |
with gr.Column():
|
|
|
|
| 1464 |
with gr.Column():
|
| 1465 |
with gr.Row():
|
| 1466 |
refresh_db_btn = gr.Button("🔄 Refresh", variant="secondary")
|
| 1467 |
+
export_csv_btn = gr.Button("📤 Export CSV", variant="secondary")
|
| 1468 |
export_db_btn = gr.Button("💾 Exporter DB", variant="secondary")
|
| 1469 |
|
| 1470 |
db_table = gr.Dataframe(
|
|
|
|
| 1757 |
logo_output, model_output,
|
| 1758 |
plate_classification, vehicle_type_output]
|
| 1759 |
)
|
| 1760 |
+
save_video_btn.click(
|
| 1761 |
+
fn=process_and_save_video,
|
| 1762 |
+
outputs=saved_video
|
| 1763 |
+
)
|
| 1764 |
|
| 1765 |
# Connecter les nouveaux composants
|
| 1766 |
time_range.change(
|