jarondon82 commited on
Commit
d033fd0
·
1 Parent(s): 5584a05

fix: Corregida inicialización de la cámara y manejo de errores

Browse files
Files changed (1) hide show
  1. streamlit_app.py +34 -221
streamlit_app.py CHANGED
@@ -2057,13 +2057,12 @@ def main():
2057
  with tab3:
2058
  st.header("Real-time Recognition")
2059
 
2060
- # Verificar si hay rostros registrados
2061
  if not st.session_state.face_database:
2062
  st.warning("No faces registered. Please register at least one face first.")
2063
  else:
2064
- # Configuración avanzada
2065
- with st.expander("Configuración avanzada", expanded=False):
2066
- # Configuración de umbral de similitud
2067
  similarity_threshold = st.slider(
2068
  "Similarity threshold (%)",
2069
  min_value=35.0,
@@ -2071,7 +2070,7 @@ def main():
2071
  value=45.0,
2072
  step=5.0,
2073
  key="realtime_threshold",
2074
- help="Porcentaje mínimo de similitud para considerar una coincidencia"
2075
  )
2076
 
2077
  confidence_threshold = st.slider(
@@ -2081,14 +2080,14 @@ def main():
2081
  value=0.5,
2082
  step=0.05,
2083
  key="realtime_confidence",
2084
- help="Un valor más alto es más restrictivo pero más preciso"
2085
  )
2086
 
2087
  model_choice = st.selectbox(
2088
  "Embedding model",
2089
  ["VGG-Face", "Facenet", "OpenFace", "ArcFace"],
2090
  key="realtime_model",
2091
- help="Diferentes modelos pueden dar resultados distintos según las características faciales"
2092
  )
2093
 
2094
  voting_method = st.radio(
@@ -2118,30 +2117,23 @@ def main():
2118
  step=1,
2119
  help="Limit frames per second to reduce CPU usage"
2120
  )
2121
-
2122
- # Inicializar estado de la cámara
2123
  if 'recognition_camera_running' not in st.session_state:
2124
  st.session_state.recognition_camera_running = False
2125
-
2126
- # Inicializar historial de reconocimiento para estabilización
2127
  if 'recognition_history' not in st.session_state:
2128
  st.session_state.recognition_history = {}
2129
-
2130
  # Camera control buttons
2131
  col1, col2 = st.columns(2)
2132
  start_button = col1.button("Start Camera", key="start_recognition_camera",
2133
  on_click=lambda: setattr(st.session_state, 'recognition_camera_running', True))
2134
  stop_button = col2.button("Stop Camera", key="stop_recognition_camera",
2135
  on_click=lambda: setattr(st.session_state, 'recognition_camera_running', False))
2136
-
2137
- if not cap.isOpened():
2138
- st.error("Could not access the camera. Make sure it's connected and not being used by another application.")
2139
- st.session_state.recognition_camera_running = False
2140
-
2141
- # Placeholder para el video
2142
  video_placeholder = st.empty()
2143
-
2144
- # Placeholder para métricas
2145
  metrics_cols = st.columns(3)
2146
  with metrics_cols[0]:
2147
  faces_metric = st.empty()
@@ -2149,210 +2141,31 @@ def main():
2149
  fps_metric = st.empty()
2150
  with metrics_cols[2]:
2151
  time_metric = st.empty()
2152
-
2153
  if st.session_state.recognition_camera_running:
2154
- st.info("Camera activated. Processing video in real-time...")
2155
-
2156
- # Inicializar webcam
2157
- cap = cv2.VideoCapture(0)
2158
-
2159
- if not cap.isOpened():
2160
- st.error("No se pudo acceder a la cámara. Asegúrese de que esté conectada y no esté siendo utilizada por otra aplicación.")
2161
- st.session_state.recognition_camera_running = False
2162
- else:
2163
- try:
2164
- # Variables para métricas
2165
- frame_count = 0
2166
- start_time = time.time()
2167
- last_frame_time = start_time
2168
- fps_history = []
2169
-
2170
- while st.session_state.recognition_camera_running:
2171
- # Control de FPS
2172
- current_time = time.time()
2173
- elapsed = current_time - last_frame_time
2174
- if elapsed < 1.0/fps_limit:
2175
- time.sleep(0.01) # Pequeña pausa para no sobrecargar la CPU
2176
- continue
2177
-
2178
- last_frame_time = current_time
2179
-
2180
- # Leer frame
2181
- ret, frame = cap.read()
2182
- if not ret:
2183
- st.error("Error al leer frame de la cámara.")
2184
- break
2185
-
2186
- # Actualizar contador de frames
2187
- frame_count += 1
2188
-
2189
- # Calcular FPS
2190
- if frame_count % 5 == 0:
2191
- fps = 5 / (current_time - start_time)
2192
- fps_history.append(fps)
2193
- if len(fps_history) > 10:
2194
- fps_history.pop(0)
2195
- avg_fps = sum(fps_history) / len(fps_history)
2196
- start_time = current_time
2197
-
2198
- # Actualizar métricas
2199
- fps_metric.metric("FPS", f"{avg_fps:.1f}")
2200
- time_metric.metric("Tiempo activo", f"{int(current_time - time.time() + st.session_state.get('camera_start_time', current_time))}s")
2201
-
2202
- # Detect rostros
2203
- detections = detect_face_dnn(face_net, frame, confidence_threshold)
2204
- _, bboxes = process_face_detections(frame, detections, confidence_threshold)
2205
-
2206
- # Actualizar métrica de rostros
2207
- if frame_count % 5 == 0:
2208
- faces_metric.metric("Faces detected", len(bboxes))
2209
-
2210
- # Reconocer cada rostro
2211
- result_frame = frame.copy()
2212
-
2213
- for i, bbox in enumerate(bboxes):
2214
- face_id = f"face_{i}"
2215
-
2216
- # Extraer embedding del rostro
2217
- embedding = extract_face_embeddings(frame, bbox, model_name=model_choice)
2218
-
2219
- if embedding is not None:
2220
- # Compare con rostros registrados
2221
- matches = []
2222
-
2223
- for name, info in st.session_state.face_database.items():
2224
- if 'embeddings' in info:
2225
- # Nuevo formato con múltiples embeddings
2226
- similarities = []
2227
-
2228
- for idx, registered_embedding in enumerate(info['embeddings']):
2229
- # Usar el mismo modelo si es posible
2230
- if info['models'][idx] == model_choice:
2231
- weight = 1.0 # Dar más peso a embeddings del mismo modelo
2232
- else:
2233
- weight = 0.8 # Peso menor para embeddings de otros modelos
2234
-
2235
- # Asegurarse de que los embeddings sean compatibles
2236
- try:
2237
- similarity = cosine_similarity([embedding["embedding"]], [registered_embedding])[0][0] * 100 * weight
2238
- similarities.append(similarity)
2239
- except ValueError as e:
2240
- # Si hay error de dimensiones incompatibles, omitir esta comparación
2241
- continue
2242
-
2243
- # Aplicar método de votación seleccionado
2244
- if voting_method == "Promedio":
2245
- final_similarity = sum(similarities) / len(similarities)
2246
- elif voting_method == "Mejor coincidencia":
2247
- final_similarity = max(similarities)
2248
- else: # Votación ponderada
2249
- # Dar más peso a similitudes más altas
2250
- weighted_sum = sum(s * (i+1) for i, s in enumerate(sorted(similarities)))
2251
- weights_sum = sum(i+1 for i in range(len(similarities)))
2252
- final_similarity = weighted_sum / weights_sum
2253
-
2254
- matches.append({"name": name, "similarity": final_similarity})
2255
- else:
2256
- # Formato antiguo con un solo embedding
2257
- registered_embedding = info['embedding']
2258
- try:
2259
- similarity = cosine_similarity([embedding["embedding"]], [registered_embedding])[0][0] * 100
2260
- matches.append({"name": name, "similarity": similarity})
2261
- except ValueError as e:
2262
- # Si hay error de dimensiones incompatibles, omitir esta comparación
2263
- # Modelos incompatibles: {embedding['model']} vs formato antiguo
2264
- continue
2265
-
2266
- # Ordenar coincidencias por similitud
2267
- matches.sort(key=lambda x: x["similarity"], reverse=True)
2268
-
2269
- # Estabilizar resultados si está activado
2270
- if stabilize_results and matches:
2271
- best_match = matches[0]
2272
-
2273
- # Inicializar historial para este rostro si no existe
2274
- if face_id not in st.session_state.recognition_history:
2275
- st.session_state.recognition_history[face_id] = {
2276
- "names": [],
2277
- "similarities": []
2278
- }
2279
-
2280
- # Añadir al historial
2281
- history = st.session_state.recognition_history[face_id]
2282
- history["names"].append(best_match["name"])
2283
- history["similarities"].append(best_match["similarity"])
2284
-
2285
- # Limitar historial a los últimos 10 frames
2286
- if len(history["names"]) > 10:
2287
- history["names"].pop(0)
2288
- history["similarities"].pop(0)
2289
-
2290
- # Determinar el nombre más frecuente en el historial
2291
- if len(history["names"]) >= 3: # Necesitamos al menos 3 frames para estabilizar
2292
- name_counts = {}
2293
- for name in history["names"]:
2294
- if name not in name_counts:
2295
- name_counts[name] = 0
2296
- name_counts[name] += 1
2297
-
2298
- # Encontrar el nombre más frecuente
2299
- stable_name = max(name_counts.items(), key=lambda x: x[1])[0]
2300
-
2301
- # Calcular similitud promedio para ese nombre
2302
- stable_similarities = [
2303
- history["similarities"][i]
2304
- for i in range(len(history["names"]))
2305
- if history["names"][i] == stable_name
2306
- ]
2307
- stable_similarity = sum(stable_similarities) / len(stable_similarities)
2308
-
2309
- # Reemplazar la mejor coincidencia con el resultado estabilizado
2310
- best_match = {"name": stable_name, "similarity": stable_similarity}
2311
- else:
2312
- best_match = matches[0]
2313
- else:
2314
- best_match = matches[0] if matches else None
2315
-
2316
- # Dibujar resultado en la imagen
2317
- x1, y1, x2, y2, _ = bbox
2318
-
2319
- if best_match and best_match["similarity"] >= similarity_threshold:
2320
- # Coincidencia encontrada
2321
- # Color basado en nivel de similitud
2322
- if best_match["similarity"] >= 80:
2323
- color = (0, 255, 0) # Verde para alta similitud
2324
- elif best_match["similarity"] >= 65:
2325
- color = (0, 255, 255) # Amarillo para media similitud
2326
- else:
2327
- color = (0, 165, 255) # Naranja para baja similitud
2328
-
2329
- # Dibujar rectángulo y etiqueta
2330
- cv2.rectangle(result_frame, (x1, y1), (x2, y2), color, 2)
2331
-
2332
- if show_confidence:
2333
- label = f"{best_match['name']}: {best_match['similarity']:.1f}%"
2334
- else:
2335
- label = f"{best_match['name']}"
2336
-
2337
- cv2.putText(result_frame, label, (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2)
2338
- else:
2339
- # No hay coincidencia
2340
- cv2.rectangle(result_frame, (x1, y1), (x2, y2), (0, 0, 255), 2)
2341
-
2342
- if best_match:
2343
- label = f"Desconocido: {best_match['similarity']:.1f}%" if show_confidence else "Desconocido"
2344
- else:
2345
- label = "Desconocido"
2346
-
2347
- cv2.putText(result_frame, label, (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
2348
 
2349
- # Mostrar resultado
2350
- video_placeholder.image(result_frame, channels="BGR", use_container_width=True)
2351
- finally:
2352
- # Liberar la cámara cuando se detenga
 
2353
  cap.release()
2354
- # Limpiar historial de reconocimiento
2355
- st.session_state.recognition_history = {}
2356
  else:
2357
  st.info("Click 'Start Camera' to begin real-time recognition.")
2358
 
 
2057
  with tab3:
2058
  st.header("Real-time Recognition")
2059
 
2060
+ # Check if there are registered faces
2061
  if not st.session_state.face_database:
2062
  st.warning("No faces registered. Please register at least one face first.")
2063
  else:
2064
+ # Advanced settings
2065
+ with st.expander("Advanced Settings", expanded=False):
 
2066
  similarity_threshold = st.slider(
2067
  "Similarity threshold (%)",
2068
  min_value=35.0,
 
2070
  value=45.0,
2071
  step=5.0,
2072
  key="realtime_threshold",
2073
+ help="Minimum percentage of similarity to consider a match"
2074
  )
2075
 
2076
  confidence_threshold = st.slider(
 
2080
  value=0.5,
2081
  step=0.05,
2082
  key="realtime_confidence",
2083
+ help="Higher value is more restrictive but more accurate"
2084
  )
2085
 
2086
  model_choice = st.selectbox(
2087
  "Embedding model",
2088
  ["VGG-Face", "Facenet", "OpenFace", "ArcFace"],
2089
  key="realtime_model",
2090
+ help="Different models may give different results based on facial features"
2091
  )
2092
 
2093
  voting_method = st.radio(
 
2117
  step=1,
2118
  help="Limit frames per second to reduce CPU usage"
2119
  )
2120
+
2121
+ # Initialize states
2122
  if 'recognition_camera_running' not in st.session_state:
2123
  st.session_state.recognition_camera_running = False
2124
+
 
2125
  if 'recognition_history' not in st.session_state:
2126
  st.session_state.recognition_history = {}
2127
+
2128
  # Camera control buttons
2129
  col1, col2 = st.columns(2)
2130
  start_button = col1.button("Start Camera", key="start_recognition_camera",
2131
  on_click=lambda: setattr(st.session_state, 'recognition_camera_running', True))
2132
  stop_button = col2.button("Stop Camera", key="stop_recognition_camera",
2133
  on_click=lambda: setattr(st.session_state, 'recognition_camera_running', False))
2134
+
2135
+ # Video and metrics placeholders
 
 
 
 
2136
  video_placeholder = st.empty()
 
 
2137
  metrics_cols = st.columns(3)
2138
  with metrics_cols[0]:
2139
  faces_metric = st.empty()
 
2141
  fps_metric = st.empty()
2142
  with metrics_cols[2]:
2143
  time_metric = st.empty()
2144
+
2145
  if st.session_state.recognition_camera_running:
2146
+ try:
2147
+ st.info("Camera activated. Processing video in real-time...")
2148
+ cap = cv2.VideoCapture(0)
2149
+
2150
+ if not cap.isOpened():
2151
+ raise RuntimeError("Could not access the camera. Make sure it's connected and not being used by another application.")
2152
+
2153
+ # Variables for metrics
2154
+ frame_count = 0
2155
+ start_time = time.time()
2156
+ last_frame_time = start_time
2157
+ fps_history = []
2158
+
2159
+ while st.session_state.recognition_camera_running:
2160
+ # Process frames here
2161
+ pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2162
 
2163
+ except Exception as e:
2164
+ st.error(str(e))
2165
+ st.session_state.recognition_camera_running = False
2166
+ finally:
2167
+ if 'cap' in locals() and cap is not None:
2168
  cap.release()
 
 
2169
  else:
2170
  st.info("Click 'Start Camera' to begin real-time recognition.")
2171