😀RECONOCIMIENTO FACIAL PARA CONTROL DE ASISTENCIA

// Some code

```python
#!P4IMReconFacial.py - OFICIAL TERMINADO - es un control de asistencia que utiliza el reconocimiento facial - By P4IM0N & gpt

#?------------------------------------------------------------------------------------------------------------------------------------------------------------------
#!explicacion de librerias
#?cv2 - es parte de OpenCV y se utiliza para el procesamiento de imágenes y visión por computadora.
#?face_recognition - es utilizada para el reconocimiento facial en imágenes y videos.
#?import csv - Permite trabajar con archivos CSV (Comma-Separated Values) para leer y escribir datos tabulares.
#?from datetime import datetime, timedelta - Permite trabajar con fechas y horas. datetime proporciona funciones y métodos para manipular fechas y horas, mientras que timedelta permite representar y realizar operaciones con diferencias de tiempo.
#?import os - Proporciona funciones para interactuar con el sistema operativo, como crear, renombrar o eliminar archivos y directorios, obtener información del sistema

#?------------------------------------------------------------------------------------------------------------------------------------------------------------------
#!IMPORTANTE - INSTALACION DE LIBRERIAS E INDICACIONES
#para instalar las librerias necesarias ejecutamos los siguientes comandos (pip install opencv-python) y (pip install face_recognition)

#?------------------------------------------------------------------------------------------------------------------------------------------------------------------
#!IMPORTAMOS LIBRERIAS NECESARIAS
import os
import cv2
import face_recognition
import csv
from datetime import datetime, timedelta



#?------------------------------------------------------------------------------------------------------------------------------------------------------------------
#!BANNER
print('''
__________  _____ .___   _____ __________                           ___________             .__       .__   
\______   \/  |  ||   | /     \\______   \ ____   ____  ____   ____ \_   _____/____    ____ |__|____  |  |  
 |     ___/   |  ||   |/  \ /  \|       _// __ \_/ ___\/  _ \ /    \ |    __) \__  \ _/ ___\|  \__  \ |  |  
 |    |  /    ^   /   /    Y    \    |   \  ___/\  \__(  <_> )   |  \|     \   / __ \\  \___|  |/ __ \|  |__
 |____|  \____   ||___\____|__  /____|_  /\___  >\___  >____/|___|  /\___  /  (____  /\___  >__(____  /____/
              |__|            \/       \/     \/     \/           \/     \/        \/     \/        \/      
                                                                                 By P4IM0N & gpt
------------------------------------------------------------------------------------
                          ░░┌┘     ░░░░░     └┐░░
                           ░│  ||  ▌░░░   ||  │░▐
                           ░│      ░░ ░░      │░
                           ─┘░░░░░░░   ░░░░░░░└─▀
                           ░░░   ▓░░   ░░▓   ░░░
                            ▄─┘   ░░░░░░░   └─▄
                             ░░  ─┬┬┬┬┬┬┬─  ░░
                             ░░░▀┬┼┼┼┼┼┼┼┬▀░░░
                              ░░░└┴┴┴┴┴┴┴┘░░░
                                ░░░░░░░░░░░      
---------------------------------------------------------------------------------''')

#?------------------------------------------------------------------------------------------------------------------------------------------------------------------
#!RUTAS principales de EMPLEADOS BASE DE DATOS e ITERACION para obtener cada imagen de cada uno y codificarla para su posterior comparacion con .face_recognition.compare_face
# Obtener la lista de nombres de los empleados desde la carpeta "empleados"
base_de_datos_path = "Empleados/"
# Obtenemos la ruta de la carpeta donde se encuentran los empleados.

lista_empleados = [os.path.splitext(empleado)[0] for empleado in os.listdir(base_de_datos_path)]
# Utilizamos os.listdir para obtener una lista de archivos en la carpeta especificada.
# Usamos os.path.splitext para dividir el nombre del archivo y la extensión, y obtener solo el nombre.

# Cargar las imágenes y codificarlas
lista_empleados_codificados = []
# Inicializamos una lista para almacenar las codificaciones faciales de los empleados.

for empleado in lista_empleados:
    # Cargar la imagen del empleado desde la carpeta "empleados"
    imagen_empleado = face_recognition.load_image_file(base_de_datos_path + empleado + ".jpg")
    # Utilizamos face_recognition.load_image_file para cargar la imagen del archivo especificado.

    # Codificar la imagen del empleado para su reconocimiento facial
    codificacion_empleado = face_recognition.face_encodings(imagen_empleado)[0]
    # Utilizamos face_recognition.face_encodings para codificar la imagen y obtener las características faciales.

    # Agregar la codificación del empleado a la lista de empleados codificados
    lista_empleados_codificados.append(codificacion_empleado)

# Inicializar la cámara
cam = cv2.VideoCapture(0)
# Utilizamos cv2.VideoCapture para inicializar la cámara.

# Crear un diccionario para almacenar la última asistencia registrada de cada empleado
ultima_asistencia = {}

#?------------------------------------------------------------------------------------------------------------------------------------------------------------------
#!LOOP principal para mantener el sistema corrriendo y capturando imagen para su comparacion
while True:
    # Capturar imagen de la cámara
    ret, imagen_capturada = cam.read()
    # Utilizamos cam.read para capturar una imagen de la cámara.

    # Convertir la imagen a formato RGB (necesario para face_recognition)
    imagen_capturada_rgb = cv2.cvtColor(imagen_capturada, cv2.COLOR_BGR2RGB)
    # Utilizamos cv2.cvtColor para convertir la imagen de BGR (formato de OpenCV) a RGB.

    # Detectar caras en la imagen capturada
    ubicacion_caras = face_recognition.face_locations(imagen_capturada_rgb)
    # Utilizamos face_recognition.face_locations para detectar las ubicaciones de las caras en la imagen.

    codificacion_caras = face_recognition.face_encodings(imagen_capturada_rgb, ubicacion_caras)
    # Utilizamos face_recognition.face_encodings para codificar las caras detectadas y obtener sus características.

    # Comparar las caras detectadas con las imágenes de los empleados
    for codificacion_cara, ubicacion_cara in zip(codificacion_caras, ubicacion_caras):
        resultados_comparacion = face_recognition.compare_faces(lista_empleados_codificados, codificacion_cara, tolerance=0.5)
        # Utilizamos face_recognition.compare_faces para comparar las caras detectadas con las caras de los empleados.

        nombre_empleado = "Desconocido"

        if True in resultados_comparacion:
            indice_empleado = resultados_comparacion.index(True)
            nombre_empleado = lista_empleados[indice_empleado]
            # Si se encuentra una coincidencia, obtenemos el nombre del empleado correspondiente.
        else:
            nombre_empleado = f"Desconocido_{datetime.now().strftime('%Y%m%d%H%M%S')}"
        
        with open('registro_asistencia.csv', 'r') as archivo_csv:
            reader = csv.reader(archivo_csv)
            ultima_asistencia = None

            # Obtener la última asistencia registrada para el empleado actual
            for row in reversed(list(reader)):
                if len(row) > 0 and row[0] == nombre_empleado:
                    ultima_asistencia = datetime.strptime(row[1], '%Y-%m-%d %H:%M:%S.%f')
                    break

            # Verificar si ha pasado un intervalo de 8 horas desde la última asistencia
            if ultima_asistencia is None or datetime.now() - ultima_asistencia >= timedelta(hours=8):

                # Dibujar un rectángulo alrededor de la cara detectada
                y1, x2, y2, x1 = ubicacion_cara
                color = (0, 255, 0) if nombre_empleado != "Desconocido" else (0, 0, 255)
                cv2.rectangle(imagen_capturada, (x1, y1), (x2, y2), color, 2)
                # Utilizamos cv2.rectangle para dibujar un rectángulo alrededor de la cara detectada.

                # Escribir el nombre del empleado en el rectángulo
                cv2.putText(imagen_capturada, nombre_empleado, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, color, 2)
                # Utilizamos cv2.putText para escribir el nombre del empleado en el rectángulo.

                # Guardar los datos en un archivo CSV
                with open('registro_asistencia.csv', 'a', newline='') as archivo_csv:
                    writer = csv.writer(archivo_csv)
                    writer.writerow([nombre_empleado, datetime.now()])
                # Abrimos un archivo CSV y utilizamos csv.writer para escribir los datos de asistencia.

                if nombre_empleado == "Desconocido":
                    if not os.path.exists("Desconocidos"):
                        os.makedirs("Desconocidos")
                    # Crear directorio "Desconocidos" si no existe
                
                if "Desconocido" in nombre_empleado:
                    # Guardar la captura de la persona desconocida como un archivo JPG
                    nombre_captura = datetime.now().strftime("%Y%m%d%H%M%S") + ".jpg"
                    ruta_captura = "Desconocidos/" + nombre_captura
                    cv2.imwrite(ruta_captura, imagen_capturada)

                    # Guardar los datos en el archivo CSV
                    with open('registro_asistencia.csv', 'a', newline='') as archivo_csv:
                        writer = csv.writer(archivo_csv)
                        writer.writerow(["Desconocido", datetime.now(), nombre_captura])
                else:
                    nombre_empleado = "Desconocido"
                    # Si no hay coincidencia, establecemos el nombre del empleado como "Desconocido".

                    
            
    # Dibujar un rectángulo alrededor de la cara detectada
    y1, x2, y2, x1 = ubicacion_cara
    color = (0, 255, 0) if nombre_empleado != "Desconocido" else (0, 0, 255)
    cv2.rectangle(imagen_capturada, (x1, y1), (x2, y2), color, 2)
    # Utilizamos cv2.rectangle para dibujar un rectángulo alrededor de la cara detectada.

    # Escribir el nombre del empleado en el rectángulo
    cv2.putText(imagen_capturada, nombre_empleado, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
    # Utilizamos cv2.putText para escribir el nombre del empleado en el rectángulo.

    # Mostrar la imagen capturada con las detecciones y nombres de los empleados
    cv2.imshow('Asistencia de Empleados', imagen_capturada)
    # Utilizamos cv2.imshow para mostrar la imagen capturada con las detecciones y nombres de los empleados.

    # Detener el bucle si se presiona la tecla 'q'
    key = cv2.waitKeyEx(1)
    # cv2.waitKeyEx(1) espera durante 1 milisegundo la entrada del teclado y devuelve un valor numérico.

#?------------------------------------------------------------------------------------------------------------------------------------------------------------------
#!PARAMOS EL LOOP al precionar Q para cerrar el sistema
    if key == ord('q'):
        break
        # Si el valor numérico de la tecla presionada coincide con el valor numérico de 'q' (113),
        # se sale del bucle y se cierra la aplicación.


#?------------------------------------------------------------------------------------------------------------------------------------------------------------------
#!CERRAMOS LA VENTANA Y REINICIAMOS LA CAMARA
# Liberar la cámara y cerrar las ventanas
cam.release()
cv2.destroyAllWindows()
# Liberamos la cámara y cerramos las ventanas abiertas.
```

CODEO DIA 14:

Last updated