Restructure content and add notes from HolaMundo

Signed-off-by: Manuel Vergara <manuel@vergaracarmona.es>
This commit is contained in:
2023-05-20 09:36:26 +02:00
parent 64ed03f811
commit f4e9797c4b
430 changed files with 889 additions and 24 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -0,0 +1,26 @@
# Día 14 - Programa un controlador de asistencia
## Índice
- [Día 14 - Programa un controlador de asistencia](#día-14---programa-un-controlador-de-asistencia)
- [Índice](#índice)
- [14.1. - Bibliotecas](#141---bibliotecas)
- [Ficheros y documentación](#ficheros-y-documentación)
## 14.1. - Bibliotecas
## Ficheros y documentación
- [asistencia.py](asistencia.py)
- [Empleados](Empleados/)
- [FotoA.jpg](FotoA.jpg)
- [FotoB.jpg](FotoB.jpg)
- [FotoC.jpg](FotoC.jpg)
- [FotoD.jpg](FotoD.jpg)
- [reconocimiento_facial.py](reconocimiento_facial.py)
- [registro.csv](registro.csv)
[Documentación del día](../doc_curso/14_asistencia/)
---
Enlaces a todos los días: [dia 1 - creador de nombres](../dia_01/README.md) / [dia 2 - calculador de comisiones](../dia_02/README.md) / [dia 3 - analizador de texto](../dia_03/README.md) / [dia 4 - juego "adivina el número"](../dia_04/README.md) / [dia 5 - juego "El ahorcado"](../dia_05/README.md) / [dia 6 - recetario](../dia_06/README.md) / [dia 7 - cuenta bancaria](../dia_07/README.md) / [dia 8 - consola de turnos](../dia_08/README.md) / [dia 9 - buscador de números de serie](../dia_09/README.md) / [dia 10 - juego "Invasión espacial"](../dia_10/README.md) / [dia 11 - web scraping](../dia_11/README.md) / [dia 12 - gestor de restaurantes](../dia_12/README.md) / [dia 13 - asistente de voz](../dia_13/README.md) / [dia 14 - controlador de asistencia](../dia_14/README.md) / [dia 15 - machine learning](../dia_15/README.md) / [dia 16 - aplicación web de tareas pendientes](../dia_16/README.md)

View File

@@ -0,0 +1,185 @@
"""
Programa dia 13 - Asistente virtual
Bibliotecas:
cmake
dlib
face-recognition
numpy
opencv-python
"""
import os
import cv2
import face_recognition as fr
import numpy
from datetime import datetime
# Crear base de datos
ruta = 'Empleados'
mis_imagenes = []
# Obtener nombres de las fotos
nombre_empleados = []
# Nombres con la extensión .jpg
lista_empleados = os.listdir(ruta)
# Cargar imágenes con loop
for nombre in lista_empleados:
# Leer la imagen
imagen_actual = cv2.imread(f'{ruta}/{nombre}')
# Añadimos las coordenadas de la imagen en una nueva lista
mis_imagenes.append(imagen_actual)
# Añadimos tan solo el nombre del empleado
nombre_empleados.append(os.path.splitext(nombre)[0])
# Mostrar lista creada
print(nombre_empleados)
def codificar(imagenes):
""" Codificar las imágenes """
# Crear una lista nueva
lista_codificada = []
# Loop para procesar las imágenes
for imagen in imagenes:
# Pasar imágenes a RGB
imagen = cv2.cvtColor(imagen, cv2.COLOR_BGR2RGB)
# Codificar
codificado = fr.face_encodings(imagen)[0]
# Agregar a la lista codificada
lista_codificada.append(codificado)
# Devolver lista codificada que se ha procesado
return lista_codificada
def registrar_ingresos(persona):
""" Recoger los datos de las capturas """
# Creamos el fichero registro.csv con Nombre, Hora
# Aquí lo abrimos para leer
f = open('registro.csv', 'r+')
# Hacemos un listado con las líneas del fichero
lista_datos = f.readlines()
# Lista vacía para almacenar los registros
nombres_registro = []
for linea in lista_datos:
# leemos separando por comas
ingreso = linea.split(',')
# Añadimos a la lista
nombres_registro.append(ingreso[0])
if persona not in nombres_registro:
# Determinamos la hora actual
ahora = datetime.now()
# Le damos formato a la hora
string_ahora = ahora.strftime('%H:%M:%S')
# Escribimos la persona
f.writelines(f'\n{persona}, {string_ahora}')
# Llamar a la función
lista_empleados_codificada = codificar(mis_imagenes)
# Mostrar número de imágenes codificadas en la función
# print(len(lista_empleados_codificada))
# Tomar una imágen de cámara web
captura = cv2.VideoCapture(0)
# Configuración de la captura para Linux
captura.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
captura.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
sleep = 'sleep 3'
os.system(sleep)
captura.set(cv2.CAP_PROP_EXPOSURE, -8.0)
# Leer la imágen de la cámara
# El método read() arroja dos elementos:
# - Si se ha podido realizar la captura
# - Devuelve la imágen
exito, imagen = captura.read()
if not exito:
print('No se pudo tomar la captura')
else:
# Primero intentamos reconocer la cara en captura
cara_captura = fr.face_locations(imagen)
# Codificar la cara capturada
cara_captura_codificada = fr.face_encodings(imagen, cara_captura)
# Busquemos coincidencias entre las imágenes capturadas
# y la lista de imágenes de empleados
for caracodif, caraubic in zip(cara_captura_codificada, cara_captura):
# Comparación
coincidencias = fr.compare_faces(lista_empleados_codificada, caracodif)
# Distancias de comparación
distancias = fr.face_distance(lista_empleados_codificada, caracodif)
# La distancia menor de la lista "distancias"
# será la que indique el parecido más cercano
print(distancias)
# Buscar el valor mínimo y añadir a variable
indice_coincidencia = numpy.argmin(distancias)
# Mostrar coincidencias si las hay
if distancias[indice_coincidencia] > 0.6:
texto = 'No coincide'
else:
# Buscar el nombre del empleado encontrado
texto = nombre_empleados[indice_coincidencia]
# Crear rectangulo cara
y1, x2, y2, x1 = caraubic
cv2.rectangle(
imagen,
(x1, y1),
(x2, y2),
(0, 255, 0),
2
)
# Crear rectangulo verde de texto
cv2.rectangle(
imagen,
(x1, y2 - 35),
(x2, y2),
(0, 255, 0),
cv2.FILLED
)
# Crear texto
cv2.putText(
imagen,
texto,
(x1 + 6, y2 - 6),
cv2.FONT_HERSHEY_COMPLEX,
0.6,
(255, 255, 255),
2
)
registrar_ingresos(nombre)
# Mostrar la imagen obtenida por la cámara
cv2.imshow('Imagen web', imagen)
# Mantener la ventana abierta
cv2.waitKey(0)

View File

@@ -0,0 +1,99 @@
"""
Reconocimiento facial
Bibliotecas:
cmake
dlib
face-recognition
numpy
opencv-python
"""
import cv2
import face_recognition as fr
# Cargar imágenes
foto_control = fr.load_image_file('FotoD.jpg')
foto_prueba = fr.load_image_file('FotoC.jpg')
# Nos aseguramos que el formato de la foto es rgb
# Las transformamos de BGR --> RGB
foto_control = cv2.cvtColor(foto_control, cv2.COLOR_BGR2RGB)
foto_prueba = cv2.cvtColor(foto_prueba, cv2.COLOR_BGR2RGB)
# Localizar cara control
lugar_cara_A = fr.face_locations(foto_control)[0]
# Podríamos ver las coordenadas
# print(lugar_cara_A)
# Codificar la cara
cara_codificada_A = fr.face_encodings(foto_control)[0]
# Localizar cara control
lugar_cara_B = fr.face_locations(foto_prueba)[0]
# Codificar la cara
cara_codificada_B = fr.face_encodings(foto_prueba)[0]
# Marcar donde está la cara con un rectángulo
# Añadimos la foto y los índices para marcar las coordenadas
# del vértice superior izquiero de la cara y el
# del vértice inferior derecho.
# Anadimos el color del rectangulo en verde
# y el borde
cv2.rectangle(
foto_control,
(lugar_cara_A[3], lugar_cara_A[0]),
(lugar_cara_A[1], lugar_cara_A[2]),
(0, 255, 0),
2
)
cv2.rectangle(
foto_prueba,
(lugar_cara_B[3], lugar_cara_B[0]),
(lugar_cara_B[1], lugar_cara_B[2]),
(0, 255, 0),
2
)
# Realizar comparación
# El método espera recibir una lista.
# Como tenemos un único objecto lo ponemos entre corchetes
# para que piense que es una lista de un solo objeto.
# El tercer valor es la torelancia de distancia de comparación
resultado = fr.compare_faces([cara_codificada_A], cara_codificada_B)
# print(resultado)
# Medida de la distancia de comparación
# por defecto es 0.6 el valor para admitir coincidencia con True
# Esto nos indica lo cerca que está
distancia = fr.face_distance([cara_codificada_A], cara_codificada_B)
# print(distancia)
# Mostrar resultado con texto
# Los parámetros son la imagén, el texto a introducir,
# la ubicación del texto, la fuente, la escala,
# el color y el grosor
cv2.putText(
foto_prueba,
f'{resultado} {distancia.round(2)}',
(50, 50),
cv2.FONT_HERSHEY_COMPLEX,
1,
(0, 255, 0),
2
)
# Mostrar imágenes
cv2.imshow('Foto Control', foto_control)
cv2.imshow('Foto Prueba', foto_prueba)
# Las imágenes se cierran, se necesitan mantener el programa abierto
cv2.waitKey(0)

View File

@@ -0,0 +1 @@
Nombre, Hora
1 Nombre Hora