Spaces:
Sleeping
Sleeping
Commit ·
fa906cb
1
Parent(s): fa3dba9
Poner la tabla de intrusos al lado del video analizado y titular cada recuadro
Browse filesCon la tabla arriba del video había que scrollear para verlo. Ahora la página es una grilla
de 2x2: video y zona arriba, tabla y video analizado abajo. La tabla toma la proporción del
video (16:9) y, si hay más intrusos de los que entran, scrollea adentro.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- camguard/ui.py +22 -13
camguard/ui.py
CHANGED
|
@@ -58,6 +58,8 @@ REFIT_EDITOR_JS = """() => {
|
|
| 58 |
# Las barras del editor (zoom, pincel, color, tamaño) se ocultan: solo se pinta, y deshacer es
|
| 59 |
# un botón de abajo. El recuadro toma la proporción de un video común (16:9) para medir
|
| 60 |
# lo mismo que el video de al lado; si el video es de otra proporción, quedan bordes.
|
|
|
|
|
|
|
| 61 |
EDITOR_CSS = """
|
| 62 |
.pixi-target, .pixi-target-crop { overflow: hidden; }
|
| 63 |
#zona .top-panel, #zona .toolbar-wrap { display: none !important; }
|
|
@@ -68,6 +70,8 @@ EDITOR_CSS = """
|
|
| 68 |
}
|
| 69 |
#camguard-hint.hidden { opacity: 0; }
|
| 70 |
#camguard-hint svg { width: 40%; max-width: 260px; filter: drop-shadow(0 1px 3px #0008); }
|
|
|
|
|
|
|
| 71 |
"""
|
| 72 |
|
| 73 |
# Sin texto, la imagen de la zona no dice que hay que pintar encima: un pincel pinta en loop un
|
|
@@ -239,12 +243,12 @@ def build_demo() -> gr.Blocks:
|
|
| 239 |
with gr.Row():
|
| 240 |
with gr.Column():
|
| 241 |
# Solo se reproduce: se cambia con el botón, más visible que la ✕ del componente.
|
| 242 |
-
video = gr.Video(value=example_video, label="Video", interactive=False)
|
| 243 |
upload = gr.UploadButton("Subir mi video", file_types=["video"], size="sm")
|
| 244 |
with gr.Column():
|
| 245 |
editor = gr.ImageEditor(
|
| 246 |
value=example_editor,
|
| 247 |
-
label="
|
| 248 |
elem_id="zona", # ahí se dibuja ZONE_HINT_JS
|
| 249 |
type="numpy",
|
| 250 |
sources=[], # la imagen siempre es el primer cuadro del video
|
|
@@ -256,17 +260,22 @@ def build_demo() -> gr.Blocks:
|
|
| 256 |
)
|
| 257 |
undo = gr.Button("Deshacer", size="sm")
|
| 258 |
run = gr.Button("Analizar", variant="primary")
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 270 |
|
| 271 |
demo.load(None, js=ZONE_RESET_JS)
|
| 272 |
upload.upload(use_video, upload, [video, editor, table, result]).then(
|
|
|
|
| 58 |
# Las barras del editor (zoom, pincel, color, tamaño) se ocultan: solo se pinta, y deshacer es
|
| 59 |
# un botón de abajo. El recuadro toma la proporción de un video común (16:9) para medir
|
| 60 |
# lo mismo que el video de al lado; si el video es de otra proporción, quedan bordes.
|
| 61 |
+
# La tabla de intrusos también toma 16:9 para medir lo mismo que el video analizado: con más
|
| 62 |
+
# intrusos de los que entran, scrollea adentro (34 px son los de su título).
|
| 63 |
EDITOR_CSS = """
|
| 64 |
.pixi-target, .pixi-target-crop { overflow: hidden; }
|
| 65 |
#zona .top-panel, #zona .toolbar-wrap { display: none !important; }
|
|
|
|
| 70 |
}
|
| 71 |
#camguard-hint.hidden { opacity: 0; }
|
| 72 |
#camguard-hint svg { width: 40%; max-width: 260px; filter: drop-shadow(0 1px 3px #0008); }
|
| 73 |
+
#intrusos { aspect-ratio: 16 / 9; container-type: inline-size; }
|
| 74 |
+
#intrusos .virtual-table-viewport { max-height: calc(56.25cqw - 34px) !important; }
|
| 75 |
"""
|
| 76 |
|
| 77 |
# Sin texto, la imagen de la zona no dice que hay que pintar encima: un pincel pinta en loop un
|
|
|
|
| 243 |
with gr.Row():
|
| 244 |
with gr.Column():
|
| 245 |
# Solo se reproduce: se cambia con el botón, más visible que la ✕ del componente.
|
| 246 |
+
video = gr.Video(value=example_video, label="Input Video", interactive=False)
|
| 247 |
upload = gr.UploadButton("Subir mi video", file_types=["video"], size="sm")
|
| 248 |
with gr.Column():
|
| 249 |
editor = gr.ImageEditor(
|
| 250 |
value=example_editor,
|
| 251 |
+
label="Draw Restricted Area",
|
| 252 |
elem_id="zona", # ahí se dibuja ZONE_HINT_JS
|
| 253 |
type="numpy",
|
| 254 |
sources=[], # la imagen siempre es el primer cuadro del video
|
|
|
|
| 260 |
)
|
| 261 |
undo = gr.Button("Deshacer", size="sm")
|
| 262 |
run = gr.Button("Analizar", variant="primary")
|
| 263 |
+
# Lado a lado, como la fila de arriba: con la tabla arriba del video había que scrollear
|
| 264 |
+
# para verlo. Si hay más intrusos de los que entran, la tabla scrollea adentro.
|
| 265 |
+
with gr.Row():
|
| 266 |
+
with gr.Column():
|
| 267 |
+
table = gr.Dataframe(
|
| 268 |
+
headers=HEADERS,
|
| 269 |
+
datatype=["number", "number", "number", "number", "html"],
|
| 270 |
+
label="Intruder Table",
|
| 271 |
+
elem_id="intrusos", # EDITOR_CSS le da el alto del video de al lado
|
| 272 |
+
visible=False, # hasta analizar: vacía era ruido
|
| 273 |
+
interactive=False,
|
| 274 |
+
wrap=True,
|
| 275 |
+
)
|
| 276 |
+
with gr.Column():
|
| 277 |
+
# Oculto hasta que termina el análisis: vacío parecía roto.
|
| 278 |
+
result = gr.Video(label="Output Video", visible=False)
|
| 279 |
|
| 280 |
demo.load(None, js=ZONE_RESET_JS)
|
| 281 |
upload.upload(use_video, upload, [video, editor, table, result]).then(
|