Spaces:
Build error
Build error
File size: 10,020 Bytes
9fd78b1 aafeadf 9fd78b1 c95c949 9fd78b1 c95c949 9fd78b1 aafeadf 9fd78b1 c95c949 9fd78b1 c95c949 9fd78b1 c95c949 9fd78b1 c95c949 9fd78b1 c95c949 9fd78b1 c95c949 9fd78b1 aafeadf c95c949 aafeadf c95c949 aafeadf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
"""
Utilidades para manejar la persistencia de la base de datos de rostros.
"""
import os
import pickle
import streamlit as st
import json
import base64
import numpy as np
# Configurar ruta para la base de datos
DATABASE_FILE = "face_database.pkl"
def save_face_database(database):
"""
Guarda la base de datos de rostros en un archivo persistente.
Args:
database (dict): La base de datos de rostros a guardar
"""
try:
# Verificar si hay datos para guardar
if not database:
# Si la base de datos está vacía, eliminar el archivo si existe
if os.path.exists(DATABASE_FILE):
os.remove(DATABASE_FILE)
st.sidebar.write("Database was empty - removed existing file")
return True
# Convertir numpy arrays a listas para poder serializarlas
serializable_db = {}
for name, info in database.items():
serializable_db[name] = {}
# Manejar diferentes formatos de la base de datos
if 'embeddings' in info:
serializable_db[name]['embeddings'] = [emb.tolist() if isinstance(emb, np.ndarray) else emb for emb in info['embeddings']]
serializable_db[name]['models'] = info['models']
serializable_db[name]['count'] = info['count']
# Guardar imagen facial si existe
if 'face_image' in info:
serializable_db[name]['face_image'] = info['face_image'].tolist() if isinstance(info['face_image'], np.ndarray) else info['face_image']
elif 'embedding' in info:
# Formato antiguo
serializable_db[name]['embedding'] = info['embedding'].tolist() if isinstance(info['embedding'], np.ndarray) else info['embedding']
serializable_db[name]['count'] = info.get('count', 1)
# Guardar imagen facial si existe
if 'face_image' in info:
serializable_db[name]['face_image'] = info['face_image'].tolist() if isinstance(info['face_image'], np.ndarray) else info['face_image']
# Guardar en un archivo pickle
with open(DATABASE_FILE, 'wb') as f:
pickle.dump(serializable_db, f)
# Verificar que el archivo se creó correctamente
if os.path.exists(DATABASE_FILE):
st.sidebar.write(f"Database saved to {DATABASE_FILE} ({len(serializable_db)} entries)")
return True
except Exception as e:
st.error(f"Error al guardar la base de datos: {str(e)}")
return False
def load_face_database():
"""
Carga la base de datos de rostros desde un archivo persistente.
Returns:
dict: La base de datos de rostros cargada, o un diccionario vacío si no existe el archivo.
"""
if not os.path.exists(DATABASE_FILE):
return {}
try:
with open(DATABASE_FILE, 'rb') as f:
database = pickle.load(f)
# Convertir listas a numpy arrays
for name, info in database.items():
if 'embeddings' in info:
database[name]['embeddings'] = [np.array(emb) if isinstance(emb, list) else emb for emb in info['embeddings']]
# Cargar imagen facial si existe
if 'face_image' in info:
database[name]['face_image'] = np.array(info['face_image']) if isinstance(info['face_image'], list) else info['face_image']
elif 'embedding' in info:
database[name]['embedding'] = np.array(info['embedding']) if isinstance(info['embedding'], list) else info['embedding']
# Cargar imagen facial si existe
if 'face_image' in info:
database[name]['face_image'] = np.array(info['face_image']) if isinstance(info['face_image'], list) else info['face_image']
return database
except Exception as e:
st.error(f"Error al cargar la base de datos: {str(e)}")
return {}
def export_database_json():
"""
Exporta la base de datos a un archivo JSON para compartir o hacer backup.
Returns:
str: Ruta al archivo JSON exportado.
"""
try:
if 'face_database' in st.session_state and st.session_state.face_database:
# Crear una versión serializable de la base de datos
serializable_db = {}
for name, info in st.session_state.face_database.items():
serializable_db[name] = {}
if 'embeddings' in info:
serializable_db[name]['embeddings'] = [
base64.b64encode(np.array(emb).tobytes()).decode('utf-8')
for emb in info['embeddings']
]
serializable_db[name]['models'] = info['models']
serializable_db[name]['count'] = info['count']
# Incluir imagen facial si existe
if 'face_image' in info:
serializable_db[name]['face_image'] = base64.b64encode(
np.array(info['face_image']).tobytes()
).decode('utf-8')
serializable_db[name]['face_image_shape'] = info['face_image'].shape
elif 'embedding' in info:
serializable_db[name]['embedding'] = base64.b64encode(
np.array(info['embedding']).tobytes()
).decode('utf-8')
serializable_db[name]['count'] = info.get('count', 1)
# Incluir imagen facial si existe
if 'face_image' in info:
serializable_db[name]['face_image'] = base64.b64encode(
np.array(info['face_image']).tobytes()
).decode('utf-8')
serializable_db[name]['face_image_shape'] = info['face_image'].shape
# Guardar en un archivo JSON
export_file = "face_database_export.json"
with open(export_file, 'w') as f:
json.dump(serializable_db, f, indent=2)
return export_file
return None
except Exception as e:
st.error(f"Error al exportar la base de datos: {str(e)}")
return None
def import_database_json(json_file):
"""
Importa una base de datos desde un archivo JSON.
Args:
json_file: El archivo JSON a importar
Returns:
dict: La base de datos importada.
"""
try:
content = json_file.read()
imported_db = json.loads(content)
# Convertir datos codificados en base64 a numpy arrays
for name, info in imported_db.items():
if 'embeddings' in info:
imported_db[name]['embeddings'] = [
np.frombuffer(base64.b64decode(emb), dtype=np.float32)
for emb in info['embeddings']
]
# Importar imagen facial si existe
if 'face_image' in info and 'face_image_shape' in info:
face_data = np.frombuffer(base64.b64decode(info['face_image']), dtype=np.uint8)
shape = info['face_image_shape']
imported_db[name]['face_image'] = face_data.reshape(shape)
elif 'embedding' in info:
imported_db[name]['embedding'] = np.frombuffer(
base64.b64decode(info['embedding']), dtype=np.float32
)
# Importar imagen facial si existe
if 'face_image' in info and 'face_image_shape' in info:
face_data = np.frombuffer(base64.b64decode(info['face_image']), dtype=np.uint8)
shape = info['face_image_shape']
imported_db[name]['face_image'] = face_data.reshape(shape)
return imported_db
except Exception as e:
st.error(f"Error al importar la base de datos: {str(e)}")
return {}
def print_database_info():
"""
Imprime información sobre la base de datos actual para depuración.
"""
if 'face_database' in st.session_state:
db = st.session_state.face_database
st.sidebar.write("--- Database Debug Info ---")
st.sidebar.write(f"Database contains {len(db)} entries")
# Mostrar nombres en la base de datos
if db:
names = list(db.keys())
st.sidebar.write(f"Names in database: {', '.join(names)}")
# Mostrar detalles del primer elemento
if names:
first_entry = db[names[0]]
st.sidebar.write(f"Sample entry for '{names[0]}':")
if 'embeddings' in first_entry:
st.sidebar.write(f"- Has {len(first_entry['embeddings'])} embeddings")
st.sidebar.write(f"- Models: {', '.join(first_entry['models'])}")
st.sidebar.write(f"- Count: {first_entry['count']}")
# Mostrar si tiene imagen
if 'face_image' in first_entry:
st.sidebar.write(f"- Has reference face image: {first_entry['face_image'].shape}")
else:
st.sidebar.write("- No reference image")
elif 'embedding' in first_entry:
st.sidebar.write("- Has single embedding (old format)")
# Mostrar si tiene imagen
if 'face_image' in first_entry:
st.sidebar.write(f"- Has reference face image: {first_entry['face_image'].shape}")
else:
st.sidebar.write("- No reference image")
else:
st.sidebar.write("Database is empty") |