Kesheratmex commited on
Commit
ac3a9cb
·
1 Parent(s): 474ba8a

Corrige salida de vídeo en Gradio usando streaming e OpenCV VideoWriter

Browse files
Files changed (1) hide show
  1. app.py +50 -27
app.py CHANGED
@@ -2,45 +2,71 @@ import gradio as gr
2
  import tempfile
3
  import shutil
4
  import os
 
5
  from ultralytics import YOLO
6
 
7
- # Evita el error de OpenMP
8
- os.environ["OMP_NUM_THREADS"] = "1"
9
-
10
  # ────────────────────────────
11
- # Modelo
12
  # ────────────────────────────
13
- model = YOLO("best.pt") # se carga una vez al arrancar
14
-
15
- def infer(video):
16
- """Corre la detección sobre el vídeo subido y devuelve el vídeo con boxes"""
17
- tmp = tempfile.mkdtemp()
18
- inp = os.path.join(tmp, "in.mp4")
19
- shutil.copy(video, inp)
20
- results = model.predict(source=inp, save=True, conf=0.25, iou=0.45)
21
- # results es una lista; cogemos el primer objeto y su carpeta de guardado
22
- save_dir = results[0].save_dir
23
- return os.path.join(save_dir, "in.mp4")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  def show_classes():
26
- """Devuelve las clases aprendidas por el modelo"""
27
  names = model.names
28
  if isinstance(names, dict):
29
- # dict: iteramos por clave ordenada y recogemos los valores
30
- class_list = [names[i] for i in sorted(names.keys())]
31
  else:
32
- # lista de strings
33
  class_list = names
34
  return ", ".join(class_list)
35
 
36
  # ────────────────────────────
37
- # UI en Blocks
38
  # ────────────────────────────
39
  with gr.Blocks(title="Kesherat · Inspección de palas eólicas") as demo:
40
- gr.Markdown("## Inspección de palas eólicas con YOLO")
41
 
42
- video_in = gr.Video(label="Sube tu video de inspección")
43
- video_out = gr.Video(label="Video con defectos detectados")
44
 
45
  btn_detect = gr.Button("Detectar defectos")
46
  btn_detect.click(fn=infer, inputs=video_in, outputs=video_out)
@@ -50,7 +76,4 @@ with gr.Blocks(title="Kesherat · Inspección de palas eólicas") as demo:
50
  btn_classes.click(fn=show_classes, outputs=txt_classes)
51
 
52
  if __name__ == "__main__":
53
- demo.launch(
54
- share=True,
55
- allowed_paths=["/home/user/.pyenv/runs/detect/predict"]
56
- )
 
2
  import tempfile
3
  import shutil
4
  import os
5
+ import cv2
6
  from ultralytics import YOLO
7
 
 
 
 
8
  # ────────────────────────────
9
+ # Configuración
10
  # ────────────────────────────
11
+ os.environ["OMP_NUM_THREADS"] = "1" # para evitar warnings de OpenMP
12
+ model = YOLO("best.pt") # carga el modelo solo una vez
13
+
14
+ def infer(video_path):
15
+ """
16
+ Procesa el vídeo en modo streaming, anota cada frame
17
+ y genera un nuevo MP4 con las detecciones.
18
+ """
19
+ # 1) Copiamos el input a un tmp para asegurar ruta persistente
20
+ tmpdir = tempfile.mkdtemp()
21
+ in_vid = os.path.join(tmpdir, "in.mp4")
22
+ shutil.copy(video_path, in_vid)
23
+
24
+ # 2) Preparamos el writer de OpenCV en None
25
+ out_vid = os.path.join(tmpdir, "out.mp4")
26
+ writer = None
27
+ fps = 30 # asume 30 FPS; ajústalo si tu vídeo es distinto
28
+
29
+ # 3) Streaming: riene un generador de resultados por frame
30
+ results = model.predict(source=in_vid, conf=0.25, iou=0.45, stream=True)
31
+
32
+ for r in results:
33
+ # r.orig_img es el frame original en BGR
34
+ frame = r.orig_img
35
+ # r.plot() devuelve una copia anotada del frame
36
+ annotated = r.plot()
37
+
38
+ # Inicializa el VideoWriter cuando conozcamos tamaño:
39
+ if writer is None:
40
+ h, w = annotated.shape[:2]
41
+ fourcc = cv2.VideoWriter_fourcc(*"mp4v")
42
+ writer = cv2.VideoWriter(out_vid, fourcc, fps, (w, h))
43
+
44
+ writer.write(annotated)
45
+
46
+ # 4) Cerramos el writer
47
+ if writer is not None:
48
+ writer.release()
49
+
50
+ return out_vid
51
 
52
  def show_classes():
53
+ """Devuelve las clases que el modelo conoce."""
54
  names = model.names
55
  if isinstance(names, dict):
56
+ # ordenamos por clave
57
+ class_list = [names[k] for k in sorted(names)]
58
  else:
 
59
  class_list = names
60
  return ", ".join(class_list)
61
 
62
  # ────────────────────────────
63
+ # Interfaz Gradio
64
  # ────────────────────────────
65
  with gr.Blocks(title="Kesherat · Inspección de palas eólicas") as demo:
66
+ gr.Markdown("## Inspección de palas eólicas con YOLOv8")
67
 
68
+ video_in = gr.Video(label="Sube tu vídeo de inspección")
69
+ video_out = gr.Video(label="Vídeo anotado")
70
 
71
  btn_detect = gr.Button("Detectar defectos")
72
  btn_detect.click(fn=infer, inputs=video_in, outputs=video_out)
 
76
  btn_classes.click(fn=show_classes, outputs=txt_classes)
77
 
78
  if __name__ == "__main__":
79
+ demo.launch()