Pabloler21 Claude Opus 5.5 commited on
Commit
4415afe
·
1 Parent(s): 933bcf5

Agregar interfaz web con video de ejemplo

Browse files

Página Gradio local (127.0.0.1): subir video, pintar la zona, analizar.
Arranca con un video de ejemplo y una zona ya marcada; el video se
descarga en examples/ (ignorado por git) porque su licencia no es clara.
Reemplaza el main.py de ejemplo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Files changed (3) hide show
  1. .gitignore +3 -0
  2. app.py +53 -0
  3. main.py +0 -6
.gitignore CHANGED
@@ -8,3 +8,6 @@ wheels/
8
 
9
  # Virtual environments
10
  .venv
 
 
 
 
8
 
9
  # Virtual environments
10
  .venv
11
+
12
+ # Video de ejemplo (se descarga solo)
13
+ examples/
app.py CHANGED
@@ -63,6 +63,22 @@ def first_frame(video_path):
63
  return {"background": frame[:, :, ::-1], "layers": [], "composite": None}
64
 
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  def draw(frame, det, inside, zone):
67
  out = frame.copy()
68
  out[zone] = (0.6 * out[zone] + 0.4 * np.array([0, 0, 255])).astype(np.uint8) # rojo (BGR)
@@ -122,3 +138,40 @@ def analyze(video_path, editor, progress=gr.Progress()):
122
  if not rows:
123
  gr.Info("No hubo intrusiones en la zona.")
124
  return out_path, rows, snapshots
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  return {"background": frame[:, :, ::-1], "layers": [], "composite": None}
64
 
65
 
66
+ def example():
67
+ """Video de ejemplo (se baja la primera vez) con una zona ya pintada abajo a la derecha."""
68
+ from supervision.assets import VideoAssets, download_assets
69
+
70
+ try:
71
+ path = download_assets(VideoAssets.PEOPLE_WALKING, directory="examples")
72
+ except Exception: # sin internet: arranca sin ejemplo
73
+ return None, None
74
+ editor = first_frame(path)
75
+ h, w = editor["background"].shape[:2]
76
+ layer = np.zeros((h, w, 4), np.uint8)
77
+ layer[int(h * 0.55) :, w // 2 :] = (255, 0, 0, 255)
78
+ editor["layers"] = [layer]
79
+ return path, editor
80
+
81
+
82
  def draw(frame, det, inside, zone):
83
  out = frame.copy()
84
  out[zone] = (0.6 * out[zone] + 0.4 * np.array([0, 0, 255])).astype(np.uint8) # rojo (BGR)
 
138
  if not rows:
139
  gr.Info("No hubo intrusiones en la zona.")
140
  return out_path, rows, snapshots
141
+
142
+
143
+ def main():
144
+ global model
145
+ from rfdetr import RFDETRSmall
146
+
147
+ model = RFDETRSmall()
148
+ example_video, example_zone = example()
149
+ with gr.Blocks(title="CamGuard") as demo:
150
+ gr.Markdown(
151
+ "# CamGuard — Intruso en zona\n"
152
+ "**Para probar rápido:** ya viene cargado un video de ejemplo con la zona marcada. Tocá **Analizar**.\n\n"
153
+ "**Con tu propio video:** tocá la ✕ del video, subí el tuyo, pintá encima de la imagen el área "
154
+ "restringida y tocá **Analizar**.\n\n"
155
+ f"Se analizan {FPS} cuadros por segundo y hasta {MAX_SECONDS} s de video. Todo corre en esta PC."
156
+ )
157
+ with gr.Row():
158
+ video = gr.Video(value=example_video, label="Video", sources=["upload"])
159
+ editor = gr.ImageEditor(
160
+ value=example_zone,
161
+ label="Zona restringida (pintá encima)",
162
+ type="numpy",
163
+ sources=[],
164
+ brush=gr.Brush(default_size=120, colors=["#ff0000"], color_mode="fixed"),
165
+ )
166
+ run = gr.Button("Analizar", variant="primary")
167
+ result = gr.Video(label="Resultado")
168
+ table = gr.Dataframe(headers=["ID", "Entró (s)", "Salió (s)", "Duración (s)"], label="Eventos")
169
+ gallery = gr.Gallery(label="Momento de entrada de cada intruso", columns=4)
170
+
171
+ video.upload(first_frame, video, editor)
172
+ run.click(analyze, [video, editor], [result, table, gallery])
173
+ demo.launch(inbrowser=True)
174
+
175
+
176
+ if __name__ == "__main__":
177
+ main()
main.py DELETED
@@ -1,6 +0,0 @@
1
- def main():
2
- print("Hello from camguard!")
3
-
4
-
5
- if __name__ == "__main__":
6
- main()