Transcripciones
1. Introducción: Aquí hay un cambio de cara. Esto lo has visto en fotos, videos, broches de presión, lo que quieras. Es tonto, divertido, y a veces malditamente espeluznante. Podrás intercambiar caras con tu amigo, una celebridad, tu bebé, o incluso con tu perro. Construyamos este cambio de cara. Hola, soy Aldo, profesor de Ciencias de la Computación y estudiante de doctorado de la UC Berkeley. Ayudo a la computadora a ver, estudiando visión computarizada para realidad virtual y autos autoconducidos. He cortado a más de 15 mil estudiantes y no puedo esperar a mostrarles la magia también. En esta clase, aprenderás los conceptos básicos de la visión por computadora. Pongo esta clase para cualquiera interesado; codificadores, diseñadores, líderes empresariales, cualquiera, si no conoces Python, no hay problema. Ponte al día con mi curso Coding 101, Python para principiantes. ¿ No conoces AML? Eso también está bien. Toma mis herramientas masterclass de inteligencia artificial para el aprendizaje automático. Al final de esta clase, entenderás las imágenes, el procesamiento de
imágenes, la detección de rostros, y más. También tendrás una aplicación de escritorio de cambio de cara totalmente funcional que puede intercambiar caras por imágenes framer las partes. Esto te llevará solo una hora; nada que instalar, ninguna configuración complicada. Solo necesitas una laptop con internet. Te alejarás con un swapper facial y un know-how en visión computarizada en poco tiempo. Espero que estés emocionado porque sé que lo estoy. Hagamos esto.
2. ¿Qué es la visión artificial?: Empecemos por contestar, ¿qué es la visión por computadora? Aquí está la definición. Visión por computadora, definida
en sentido amplio es la vista para la IA. Existen una serie de tareas de visión por computadora que reflejan esto, como la detección de objetos, que caja y clasifica todos los objetos de la escena como la flor de la izquierda. Súper resolución, que alucina detalles para que tus imágenes sean más nítidas, como el color nítido de la derecha, contrastado con los arbustos borrosos de la izquierda. Estimación keypoint que identifica puntos clave como articulaciones y extremidades, como el bailarín antiguo de la izquierda. Ahora podemos volver a responder ¿qué es la visión por computadora de una manera aplicada? La visión por computadora es más específicamente extraer información de o generar imágenes. Sin embargo, para entender mejor este campo, veamos el marco para el
aprendizaje automático que cubrimos en nuestra masterclass de IA. Si aún no has tomado este curso, te
recomiendo hacerlo. En nuestra masterclass de IA, discutimos compartimentar nuestros conocimientos ML en cuatro categorías. Datos, modelo, objetivo, y algoritmo. Los datos describen las entradas y salidas, de
qué aprendemos y qué predecimos. Modelo describe cómo hacer predicciones. Objetivo describe la meta, qué se está optimizando el modelo. Por último, algoritmo describe cómo aprende el modelo. No hemos discutido mucho algoritmo, y lo vamos a saltar de nuevo esta vez. En la visión por computadora, los datos son siempre visuales, es
decir, imágenes y videos. Adicionalmente podemos utilizar otras señales relacionadas como audio o profundidad encima de imágenes y videos. Nos centraremos en los datos de esta lección. Nuestros modelos en visión por computadora clásica y en aprendizaje profundo hoy extraen patrones de la imagen utilizando una herramienta llamada filtros. Discutiremos esto en lecciones posteriores. Por último, nuestro objetivo suele ser maximizar la precisión. Como de costumbre, saltaremos los algoritmos. Para entender el resto de la visión por computadora, necesitamos entender cómo se representan las imágenes. ¿ Qué es una imagen? ¿ Cómo se representa una imagen como números? Veamos un ejemplo. Podemos construir una imagen en blanco y negro utilizando números donde cero corresponde al negro y uno al blanco. Enfoque en la línea divisoria entre unos y ceros. ¿ Qué forma ves? Guardar esta matriz de números como imagen nos da esto. Resulta que es un diamante. ¿ Y si queremos imágenes en escala de grises, no solo en blanco y negro? Bueno, aún usando cero para negro y uno para blanco, también
podemos usar cualquier valor entre cero y uno como 0.1,0.26, o 0.74391. números más cercanos a cero son más oscuros y los números más cercanos a uno o más ligeros. Esto nos permite representar el blanco, negro, y cualquier tono de gris. Considera lo siguiente, por ejemplo, puedes decir qué es esto? Nuevamente, cada número corresponde al brillo de un píxel. Guardar esta caja de números como imagen nos da esto, una bola pokey. Esta es imposible de ver solo por los números de la diapositiva anterior, pero ahora se sabe cómo se representan numéricamente las imágenes en escala en blanco y negro y gris. Para introducir el color, necesitamos una forma de codificar más información. Aquí te dejamos cómo. En primer lugar, cada imagen tiene un alto y ancho. Esta imagen es h por w Cada píxel, como vimos antes en una imagen a escala de grises tiene un valor. Podemos decir de manera equivalente que nuestra imagen tiene dimensiones H por W por una. Actualizar esta imagen en escala de grises a una imagen en color implica lo siguiente. Para una representación de color, representamos el color de cada píxel utilizando tres valores entre cero y uno. Un número corresponde al grado de rojo, uno al grado de verde, y el último al grado de azul. esto lo llamamos el espacio de color RGB. Esto significa que por cada píxel de nuestra imagen, tenemos tres valores, R, G, y B. Como resultado, nuestras imágenes ahora H por W por tres. Es así como obtienes una imagen en color como esta. En realidad, cada valor oscila entre 0- 255 en lugar de 0-1. Pero la idea es la misma. Diferentes combinaciones de números corresponden a diferentes colores, como 171, 180, 190 azul claro completo, o 200, 199,188, marrón claro completo. En resumen, cada imagen se representará como una caja de números que tiene tres dimensiones, altura, anchura y tres canales de color. Manipular esta caja de números directamente equivale a manipular la imagen, y así es como las imágenes se representan como números. En resumen, definimos la visión por computadora como extraer información de o generar imágenes. Cubrimos abstracciones de ML para visión
computarizada, datos, modelo, objetivo y algoritmo. Por último, discutimos cómo se representan numéricamente las imágenes. Con todo este conocimiento, estás bien equipado para empezar a trabajar con imágenes codificadas. Para una copia de estas diapositivas y más recursos mezcla echa un vistazo a esta URL. Eso concluye esta introducción. Vamos a conseguir la codificación en la siguiente lección.
3. Conceptos básicos del código OpenCV: Bienvenido a la primera lección de codificación de este curso. Vamos a ensuciarnos las manos con algún código. Si quieres una rápida introducción a la programación en Python, asegúrate de revisar mi curso de Python para principiantes antes de comenzar esta lección. Aquí puedes pausar el video para acceder a esa URL. En un nivel alto, generaremos una imagen luego probaremos nuestra webcam. El objetivo es explorar utilidades fundamentales de OpenCV. Comience accediendo a esta URL. Esto creará un entorno para nosotros de forma remota para
que no tengamos que hacer ninguna configuración en nuestros equipos. Ya verás por el lado derecho, ya lo
he hecho. Para este tutorial, recomiendo encarecidamente usar Google Chrome. Desafortunadamente, he probado el código en algunos navegadores diferentes y solo Google Chrome es compatible en este momento. Tu objetivo será generar esta imagen. paso uno es crear la representación numérica de la imagen así. Recordemos desde antes que unos y ceros pueden hacer una imagen en blanco y negro como discutimos, cero aquí es negro y uno es blanco. No obstante, en realidad, los números van de 0 a 255, por lo que usaremos 255 para blanco y cero para negro. Vamos a crear esta matriz en código ahora. En el lado derecho, voy a dar click en la X, bueno, estoy aquí arriba a la derecha para que podamos cerrar esta ventana de vista previa. A la izquierda, haga clic en Nuevo archivo y escriba generate.py. Esto creará un nuevo archivo para nosotros. Ahora minimicemos este navegador de archivos. Ahora voy a acercar mi código para que puedas ver mejor lo que estoy haciendo. Para empezar, en tu generate.py, importar numpy, que contiene tus utilidades de álgebra lineal. Por convención, cambiamos el nombre numpy a np para mayor comodidad más adelante. Después importa OpenCV, que contiene tus utilidades de visión e imagen computarizada. Primero crearemos una representación numérica de nuestra imagen. Adelante y teclear imagen es igual a una matriz numpy y esta matriz numpy tomará en una lista de listas que especifica los números que tenemos en el lado izquierdo. Escribiendo esos números ahora. Después de introducir los números, defina un tipo de datos. Este tipo de datos va a ser un entero sin signo. Este tipo de datos aquí es importante. Establecemos el tipo de datos en un entero sin signo porque todos nuestros enteros en esta imagen son positivos. Esto es necesario para que OpenCV o cv2 guarde correctamente su matriz como imagen. A continuación, vamos a redimensionar nuestra imagen. Aquí te mostramos cómo cambiar el tamaño, llamar a cv2.resize en la imagen para cambiar el tamaño y pasar en el tamaño deseado de la imagen. En este caso, nuestra imagen es alta. Por lo que queremos un ancho de 90 píxeles y una altura de 150 píxeles. Pero si ejecutamos este código, estaríamos muy decepcionados. Nuestro ocho de tamaño alto se vería feo así. En cambio, queremos un ocho afilado. Por lo que vamos a aumentar el tamaño usando otra técnica de cambio de tamaño llamada vecinos más cercanos. Para ello, agregaremos un tercer argumento a nuestra función de redimensionamiento. De nuevo, aquí está el redimensionamiento. Pasamos en la imagen para redimensionar el tamaño final y el tercer argumento le dice a cv2 que use la técnica de up-sampling vecino más cercano. Probemos esto en código ahora. Ahora vamos a escribir, imagen es igual a cv2.resize imagen coma 90, 150. Entonces finalmente el método de interpolación, que es CV2.inter_nearest. Verás lamentablemente que mi código está cortado en el lado derecho. Esto de aquí dice que la interpolación es igual a CV2.inter_nearest. Con nuestra imagen redimensionada, todo lo que queda es salvarla. Para guardar la imagen, utilice cv2.imwrite, como se muestra aquí. El primer argumento es el camino, y el segundo argumento es la imagen. Probemos esto. Después de su código existente, escriba cv2.imwrite proporcionará la ruta de la imagen y la imagen en sí y eso es todo. Ya estamos listos para ejecutar este código. Hemos terminado de escribir nuestro código en un archivo Python llamado generate.py. En lecciones anteriores de Python, especialmente las de Repl.it, tocaríamos el botón verde de ejecución en la parte superior de la pantalla para ejecutar el archivo Python. No tenemos un bonito botón verde, así que lo haremos manualmente y ejecutaremos nuestro archivo Python a través de la línea de comandos. Para iniciar la línea de comandos, vuelve a abrir tu navegador de archivos en el lado izquierdo haciendo clic en la flecha. Una vez que hagas eso, verás el diálogo de una herramienta en la parte inferior izquierda, haz clic en Herramientas, y en el menú desplegable, selecciona Terminal. En esa Terminal, verás alguna configuración como yo veo aquí. Voy a alejarme un poco. Una vez que veas esta terminal, ahora
puedes introducir tu comando. En particular, el comando es Python y el argumento es la ruta del archivo, que es generate.py en este caso. Adelante y teclee Python generate.py y pulsa Enter. Después de ejecutar tu código, deberías ver un 8.png en tu barra lateral izquierda. Haz click en él para ver tu imagen generada y voila, has generado tu primera imagen. Empecemos ahora a manipular las salidas de la webcam. Navega a esta URL. Una vez cargada la página, cierra la vista previa en el lado derecho, haciendo clic en la X en la parte superior derecha. En el lado izquierdo, ahora
crearemos un nuevo archivo. En esta parte de la lección, nuestro objetivo es conectar nuestras utilidades OpenCV a la webcam. Empecemos lanzando una aplicación web mínima usando una biblioteca personalizada construida solo para este curso llamado Web OpenCV. En el lado derecho, haga clic en Nuevo archivo y escriba app.py. Aquí voy a minimizar esta barra lateral haciendo clic en la flecha en la parte superior izquierda. En esta parte de la lección, nuestro objetivo es conectarnos a nuestra webcam utilizando las utilidades OpenCV que se proporcionan en esta lección. Empecemos lanzando una aplicación web mínima usando una biblioteca personalizada construida solo para este curso llamado Web OpenCV. Importar webopencv como WCV. Después importaremos OpenCV para nuestras utilidades generales de visión por computadora. Por lo que importar cv2. A continuación, crearemos una instancia de su aplicación web. Se puede hacer esto escribiendo en la aplicación es igual a wcv.WebApplication. Por último, puedes ejecutar tu aplicación web, app.run, y eso es todo. Para previsualizar tu nueva aplicación, haz click en Mostrar en la parte superior izquierda. Para mí, he minimizado tanto mi pantalla que solo puedo ver un par de gafas de sol. Haga click en En una Ventana Nueva. Esta es mi nueva ventana. Desafortunadamente, la parte superior está cortada, en esta nueva ventana, haga clic en Mostrar y luego haga clic en Permitir. Una vez que hayas terminado, haz clic en Detener para detener la webcam. Si te preocupa la privacidad, no te preocupes, los datos de esa webcam solo se están
comunicando desde tu computadora a tu propio servidor de glitch, que es en lo que estás codificando en este momento. Por lo que solo tu código y el servidor está procesando tu webcam. Nadie más lo ve. Ahora eres el desarrollador. Ahora agrega tu primera transformación de imagen a la aplicación web. Esta transformación en última instancia escribirá texto sobre la imagen que recibe. Pero por ahora, vamos a transformar eso no hace nada. Crear una función llamada Hola. Toma dos argumentos, la imagen y otro objeto llamado el marco, y devuelve la imagen. Todas las transformaciones excepto las imágenes como entrada y devuelven la imagen procesada. También necesitamos un decorador llamado app.transform. Nos saltaremos los detalles técnicos de cómo funciona un decorador. Por ahora, solo tienes que saber que este decorador registra se transforman con nuestra aplicación web. Cualquier transformación registrada aparecerá en nuestra interfaz web. Adicionalmente, el texto en rosa se utilizará como nombre de los transformadores. Probemos esto ahora en código. Debajo de donde está definida tu app, agrega tu nuevo decorador, con el nombre de la transformación Hola. Ahora vamos a aplicar un argumento de palabra clave, el valor predeterminado es cierto. Esto asegura que la transformación Hello se aplique automáticamente cuando se carga la webcam. Defina su función hello, que toma en la imagen y otro argumento llamado el marco, y finalmente, devuelva la imagen. Ahora si actualizas la página en una ventana nueva, verás que la transformación Hola se elige de forma predeterminada. Aquí tenemos Hola. A continuación, escribiremos algo de texto de HelloWorld en la transmisión en vivo de la webcam. Aquí te explicamos cómo hacer eso. Aquí te dejamos la imagen a anotar. El texto que queremos mostrar, la posición del texto,
la fuente que queremos utilizar, y el tamaño de fuente de manera efectiva. Esto se da en realidad como una escala relativa al tamaño de fuente predeterminado. Por último, tenemos el color en RGB. Entonces aquí 255, 0, 0 significa rojo. En la función Hola ahora agregará texto a la imagen justo arriba donde devuelves o tipo de imagen y cv2.putText. Pasaremos en la imagen, la cadena Hello World, la posición, la fuente. Le daremos un tamaño de fuente de uno. Por último, usaremos el color verde. Aquí, usaremos 0, 255, 0. Ahora, navega a tu aplicación web. Haga clic en Inicio, y verá aplicado el texto Hola Mundo. Ahí vamos. Estos son los pasos que cubrimos. Cubrimos OpenCV, redacción de
imágenes y utilidades de adición de texto. No hay necesidad de memorizar estos. Siempre puedes buscarlos. Yo solo quería darte alguna práctica por trabajar con estas utilidades. Para una copia de estas diapositivas, el código terminado, y más recursos, asegúrese de consultar esta URL. Eso es todo para los conceptos básicos de OpenCV.
4. ¿Cómo funcionan los intercambios de caras?: Vamos a cavar en los permutas de cara. Algo que se parece a esto. ¿ Cómo funciona esto? Déjame explicarte. Empezaremos por descomponer esta cara intercambiando producto de
IA en subproblemas. ¿Qué es un swap facial? En nuestra versión simple del cambio de cara,
un swap de cara da dos pasos, detecta todas las caras e intercambia píxeles por esas caras. Hablemos ahora de estos dos pasos con más detalle. primer paso, la detección facial, detección facial
resumida toma una imagen como esta y dibuja cajas alrededor de las caras. Describamos esos algoritmos de dibujo de caja con más detalle ahora. Introduciremos la detección facial describiendo los datos asociados, modelo, objetivo y algoritmo. A modo de refresco, esto es lo que significan cada uno de estos términos. En primer lugar, los datos. Nuestro modelo de detección facial acepta una imagen y predice una caja que contiene la cara. Estas casillas están representadas usando cuatro números. Cada descripción de caja incluye la esquina superior izquierda, x e y, y la altura, y el ancho. Estos cuatro números definen de manera única una caja. Un modelo de detección de caras predice estas cuatro coordenadas para una cara. Segundo modelo, el modelo de detección facial particular que usaremos se llama clasificador en cascada Haar. Discutiremos este modelo con más detalle en una lección posterior. Tercer objetivo, el objetivo de nuestro modelo es maximizar la precisión de detección facial. Para medir la precisión, utilizamos una métrica llamada intersección sobre unión o IoU. Hablemos de cómo se calcula el IoU. Así es como funciona IoU o intersección sobre sindicato. Diga que esta caja roja es nuestra caja predecida, el azul es nuestra verdad tierra. Intuitivamente, cuanto menos se superpongan estas dos cajas, menor será
la precisión. Cuanto más se superpongan, mayor debe ser nuestra precisión. Calculamos la superposición denotada en rosa para mezclar tus cajas más grandes para obtener automáticamente mayor precisión. También dividimos por el sindicato denotado en verde. Esta intersección sobre unión o IoU es la forma en que medimos la precisión para los detectores de objetos. Por último, como de costumbre, saltaremos el algoritmo. Esto concluye nuestra introducción a la detección facial. Discutiremos la detección de caras con más detalle en una lección posterior. Por ahora, pasemos al segundo paso del swap facial, el propio cambio. El segundo paso es un swap de píxeles, tendremos que hacer algo de redimensionamiento en caso de que las dos caras detectadas sean de diferentes tamaños, pero esto es por lo demás bastante sencillo. Ahora, veamos un ejemplo de estos dos pasos juntos. En primer lugar, detectar ambas caras y luego intercambiarlas. Es cierto que esto no parece convincente. Para esta clase construiremos este sencillo cambio facial, pero permítanme explicar cómo los swaps faciales de grado industrial hacen que esto sea más realista. Vamos a rehacer la rotura de los productos de IA de cambio de cara. Esta fue nuestra comprensión previa del cambio facial. primer lugar, en lugar de solo detectar caras, ahora detectará puntos clave en la cara. Aquí te presentamos un ejemplo visual de puntos clave faciales. Los puntos clave faciales pueden corresponder a partes significativas de la cara, como el puente nasal, área justo encima de una ceja, hoyuelos y más. Con nuestros puntos clave, entonces
deformamos píxeles para que cada región de la cara se deforme a la región correspondiente de una segunda fase. Para visualizar esto, digamos que ahora tenemos dos caras, tenemos los puntos clave faciales de antes para la persona de la izquierda. También contamos con los mismos puntos clave faciales para la persona de la derecha. Centrémonos en los tres puntos clave alrededor de su ojo izquierdo. Estos puntos clave forman triángulos, para enfrentar el swap deformará el triángulo de la izquierda hacia el triángulo de la derecha. Después de algunas técnicas de mezcla de imágenes, entonces
tendremos un cambio facial fotorrealista, algo así. Eso es todo. Cubrimos una versión mínima del swap facial que construirá, que consiste en dos pasos, detectar las caras e intercambiar los píxeles. También cubrimos las técnicas de cambio facial profesional utilizadas por aplicaciones
populares para una copia de estas diapositivas y más recursos, asegúrate de que pagas esta URL y ahora ya sabes cómo funcionan los swaps faciales. Consigamos codificando una vez más para empezar a construir nuestro propio swap facial.
5. Detección de rostros por código: En esta lección, experimentaremos con un detector facial. A un nivel alto, detectaremos rostros en una imagen, y luego detectaremos rostros en nuestra webcam. El objetivo es explorar las utilidades de detección de espacio. Empieza por acceder a esta URL como lo he hecho en el lado derecho. Esto creará un entorno para nosotros de forma remota para que como antes, no
hagamos ninguna configuración en nuestros equipos. En el lado derecho aquí para prepararme para nuestro desarrollo, voy a cerrar esta vista previa en el lado derecho haciendo clic en la x en la parte superior derecha. En el navegador de archivos, voy a hacer clic en Nuevo archivo, luego escriba detect.py. Entonces esto automáticamente va a abrir detect.py en nuestro editor. Voy a minimizar nuestro navegador de archivos haciendo clic en esta flecha izquierda. Entonces voy a acercarme para que veas mejor lo que estoy haciendo. Empezaremos leyendo y escribiendo una sola imagen. Para leer la imagen, utilice cv2.imread como se muestra aquí. El primer argumento es el camino de la imagen a leer. Probemos esto, en tu nuevo archivo Python, empiece importando OpenCV, importando cv2. Después lee la imagen, kids.jpg. Aquí, escribiremos en imagen es igual a cv2.imread y kids.jpg. Para guardar la imagen, utilice cv2.imwrite, como se muestra aquí. El primer argumento es el camino y el segundo argumento es la imagen. Probemos esto ahora, escribamos la imagen en un nuevo archivo llamado out.jpg, cv2.imwrite a out.jpg, y luego incluimos la imagen a la derecha. Después vamos a reabrir nuestro navegador de archivos y en el lado izquierdo, haga clic en Herramientas en la parte inferior y luego haga clic en Terminal. Espere a que termine la configuración. Una vez realizada la configuración, serás recibido con un prompt como éste. Aquí vamos a escribir python detect.py. Hit Enter. Esto ejecutará el script de Python que acabas de escribir. El script leerá kids.jpg, y guardará eso en out.jpg. Para comprobar, abre out.jpg a la izquierda. Aquí, verás que out.jpg coincide con kids.jpg. Ahora instanciemos a nuestro detector facial. Si quieres un refresco sobre qué es la instanciación o cuáles son los objetos, asegúrate de revisar mi clase de programación orientada a objetos de nivel intermedio. Aquí puedes pausar el video para acceder a esa URL. Instanciar el detector facial, y pasar los parámetros del modelo. Aquí, los parámetros del modelo se almacenan en un archivo llamado parameters.xml. En tu navegador de archivos, haz clic en detect.py una vez más. Aquí voy a volver a cerrar mi terminal en la parte inferior haciendo
clic en la x También voy a minimizar mi navegador de archivos. No necesitas hacer ninguna de estas cosas. Solo estoy desagrupando el video para que puedas ver mejor mi código. Justo encima de la imagen, ahora
vamos a instanciar el detector facial. Detector es igual a CV2.CascadeClassifier. Nuevamente, el argumento es parameters.xml. Ahora usemos el detector facial para detectar rostros. Lo haremos usando el método DetectMultiScale, pasaremos la imagen a este método y adicionalmente pasaremos un nuevo argumento de palabra clave llamado ScaleFactor es igual a 1.3. Discutiremos qué significa este ScaleFactor más adelante. Por ahora, pasaremos
ambos argumentos y el método luego devolverá un montón de rectángulos, cada rectángulo correspondiente a una cara en la imagen. Probemos esto ahora. Después de haber definido tu detector facial y después de que hayas cargado en la imagen, ahora
detectaremos todas las caras corriendo, rectángulos es igual al detector.DetectMultiscale, y como hemos escrito ahí a la izquierda, nosotros van a pasar en la imagen y el ScaleFactor. Por último, dibujemos rectángulos en la imagen correspondiente a las caras detectadas. Aquí te explicamos cómo hacer eso. Llame a la función cv2.rectángulo. Aquí pasaremos en la imagen para dibujar rectángulos sobre, las coordenadas para la esquina superior izquierda del rectángulo, coordenadas para la esquina inferior derecha del rectángulo, el color del borde del rectángulo. Recuerda, el primer número aquí representa la cantidad de rojo, el segundo la cantidad de verde, y el último la cantidad de azul, con el monto oscila entre 0 y 255. En consecuencia, 0, 255, 0 significa verde. Aquí hay una sutileza. El esquema de color en realidad no tiene RGB sino BGR para OpenCV, pero por ahora estamos omitiendo ese detalle. Pero si intentas cambiar estos colores, sería por eso
que el primer número realmente controla el grado de azul. Por último, definiremos el ancho de línea para el borde del rectángulo, que tiene dos píxeles de ancho. Probemos ahora esto en código. En el lado izquierdo, vamos a recorrer todos los rectángulos. Aquí, sabemos que el rectángulo es una tupla de cuatro números como hablamos en la lección anterior. Ahora podemos escribir x, y, w, h es igual a rectángulo. Esta sintaxis nos permite asignar x al primer número, y al segundo, w al tercero, y h al cuarto. Ahora, dibuja el rectángulo usando la función que discutimos. CV2.rectángulo, la imagen, la coordenada inicial, la coordenada final, el color verde, y finalmente el ancho del borde. Si aún no lo has hecho, abre el navegador de archivos de la izquierda, haz clic en Herramientas y selecciona Terminal. En la parte inferior, verás alguna configuración. Una vez que tu terminal esté lista, escribe python detect.py en la terminal. Esto ejecuta el script de detección facial de Python que acabas de escribir. Después de ejecutar este script, haga clic en out.jpg a la izquierda, verá que la imagen ahora tiene rectángulos dibujados alrededor de cada cara. Ahora repetiremos la detección de rostros pero para nuestra propia webcam. Comience accediendo a esta URL. Una vez cargada tu página, al igual que antes, minimiza tu vista previa haciendo clic en la x en la parte superior derecha. Ahora, ya tenemos un archivo creado para nosotros. Esto es de la lección anterior. Voy a cerrar el navegador de archivos del lado izquierdo haciendo clic en la flecha izquierda. Para empezar, cambiaremos la velocidad de fotogramas de nuestra fuente de video basada en web. Esto evita que nuestra aplicación web se quede demasiado rezagada. Agrega una tasa de fotogramas de argumento de palabra clave al constructor así. En nuestro código voy a escribir en framerate igual a 5. Adicionalmente, vamos a eliminar CV2.putText, lo
reemplazaremos más adelante. Al igual que antes, instanciaremos el detector facial. Nuevamente, como antes, pasa los parámetros del modelo en parameters.xml a este CascadeClassifier. Justo encima de la definición de la app, voy a escribir en detector es igual a CV2.CascadeClassifier parameters.xml. A continuación, detectar todas las caras de la imagen. Estamos configurando ligeramente la detección facial, como antes de pasar la imagen para detectar caras
encendidas y como antes adicionalmente pasar en ScaleFactor es igual a 1.3. Este ScaleFactor nos permite detectar caras de mayor tamaño. Aquí te explicamos cómo, digamos, el detector facial fue entrenado para detectar rostros de este tamaño. Aquí el cuadrado azul es la imagen, el círculo es una representación abstracta de una cara. Durante la inferencia, normalmente se
perdería una cara más grande como esta ya que nuestro detector no está entrenado para rostros tan grandes. Para sortear esto, reducimos la imagen en un 30 por ciento y ejecutamos el detector sobre ella. Después repite esto, escale la imagen en
otro 30 por ciento y vuelva a ejecutar el detector sobre ella. En este último paso, nuestro rostro durante la inferencia es del mismo tamaño los rostros durante el entrenamiento por lo que nuestro detector es capaz de detectar el rostro. Esto es lo que significa DetectMultiscale. Vamos a codificar esto ahora. En primer lugar, cambiemos el nombre de esta transformación de Hola Mundo a Buscar Caras. También cambiaremos el nombre de la función a find_faces. A continuación, encuentra todas las caras en la imagen como lo hicimos antes. También añadiremos el factor de escala como mencionamos anteriormente, para que el detector sea más robusto a diferentes tamaños de cara, rectángulos es igual a detector.DetectMultiscale, y vamos a pasar en la imagen y un ScaleFactor de 1.3. Por último, dibuja rectángulos alrededor de todas las caras como antes. Aquí otra vez, cómo dibujar un rectángulo en OpenCV. Hagámoslo ahora. Vamos a recorrer todos los rectángulos. Vamos a desestructurar el rectángulo en cuatro variables como lo hicimos antes. Por último, vamos a dibujar rectángulos alrededor de todas las caras. Ahora bien, tenga en cuenta que en realidad podemos simplificar este for-loop. Dado que x, y, w, h es igual a rectángulo, en realidad
podemos sustituir rectángulo por estas cuatro variables. Ahora voy a borrar esta línea. Aquí tenemos para x, y, w, h en rectángulos. Ahora, da click en Mostrar en la parte superior izquierda. Para mí, desafortunadamente, mi ventana es demasiado pequeña, por lo que parece un par de gafas de sol. Esto abrirá una vista previa de su aplicación web. Voy a volver a acercar para que puedas ver. A continuación voy a dar click en Inicio y verás un feed de webcam excepto con la cara en caja. De nuevo, haga clic en Permitir si es necesario. Eso es todo para esta lección, ahora
has explorado las utilidades de detección de rostros en OpenCV para obtener una copia de estas diapositivas, el código terminado y más recursos, asegúrate de revisar esta URL.
6. ¿Cómo funcionan los detectores de caras?: Permítanme dar un paso atrás para explicar cómo funcionan los detectores de rostro. Empezaremos con detectar características simples como bordes. Toma nuestra imagen de la lección anterior. Digamos que queremos extraer pequeñas características simples como bordes. En un nivel alto, queremos encontrar estas pequeñas características en cada posible parche de la imagen. Digamos que cada parche es de dos por dos para empezar. Empezaremos desde la parte superior izquierda y preguntaremos, ¿encontramos aquí la característica? ¿ Qué hay de aquí? ¿Qué hay de aquí? Entonces y así sucesivamente hasta que hayas cubierto toda la imagen. Ahora bien, ¿cómo encuentras pequeñas características como bordes en cada uno de estos parches dos por dos? Considera un parche de dos por dos con un borde y otros parches sin bordes. Ahora considere sus representaciones numéricas. Recordemos que el negro es cero y uno es blanco, por lo que la caja izquierda contiene tanto ceros como unos. El cajón central contiene todos los unos y la caja derecha contiene todos los ceros. Consideremos ahora un filtro dos por dos, que es sólo una matriz de números dos por dos. Multiplica el filtro dos por dos con nuestro parche dos por dos. Elemente-sabio, multiplicar el negativo rojo 1 por el cero rojo. Multiplica el negro negativo 1 por el cero negro. Multiplique los verdes, y multiplique los azules. Por último, sumadlas todas juntas y obtenemos dos. Haz lo mismo para la imagen media y obtenemos cero. Haz lo mismo por la imagen correcta y obtenemos cero de nuevo. Esto es perfecto. Nuestro filtro produce valores positivos para bordes
verticales y produce cero para imágenes sin bordes. Esto es solo para un pequeño parche de dos por dos aunque. Consideremos ahora toda la imagen. Esta es ahora la representación numérica de nuestra imagen de diamante. Recorriremos cada parche dos por dos de la imagen. En cada parche, multiplicamos y sumamos el filtro de dos por dos con un parche de dos por dos. Esto nos da una matriz de salidas donde uno denota un borde con negro a la izquierda y blanco a la derecha. Negativo 1 denota una arista en sentido inverso. Visualizados como una imagen, tenemos el blanco como borde izquierdo, negro como un borde derecho, y el gris como ningún borde. Nosotros lo llamamos así convolviendo un filtro con la imagen. Esto también funciona para imágenes genéricas en color. Aquí hay un pájaro a la izquierda. Convolverse la imagen con el filtro de borde nos consigue la imagen de la derecha, resaltando los bordes como se esperaba. Para el detector facial de hoy, usaremos filtros Haar o características de Haar. Algunas características Haar encuentran bordes como el que acabamos de probar. Otros encuentran líneas, sin embargo otros encuentran patrones abstractos. Hay multitudes de filtros posibles y también hay muchos, muchos parches en una imagen grande. Ejecutar todos los filtros sobre todos los parches es caro. Hagamos esto más eficiente. Necesitamos una forma de ahorrar costo computacional. Para ello, el detector facial en este curso utiliza un método llamado en cascada. Para entender cómo se computa el CVS en cascada, necesitamos entender la intuición. Mira esa imagen en la caja roja. Es básicamente verde monótono. Definitivamente no contiene cara porque es todo de un solo color y bastante aburrido. Sabiendo esto, podríamos ejecutar un simple como detector primero para encontrar todas las partes sin bordes de la imagen. Convolverse un filtro de borde con la imagen nos da esta salida. Observe que esta parte monótona de la imagen encaja en rojo a la izquierda es todo negra. Ahora podemos ignorar esas partes de la imagen y enfocar posteriormente los filtros en las partes más interesantes de la imagen denotadas en verde, y esa es la intuición. Ejecuta un pequeño conjunto de filtros de la imagen. esto lo llamamos etapa 1. Determinar qué partes son interesantes escogiendo los píxeles con los valores de salida más altos. Después ejecuta el siguiente conjunto de filtros en las partes interesantes. Refinar qué partes de la imagen se consideran interesantes, y repetir para el siguiente conjunto de filtros, refinando de nuevo qué partes de la imagen son interesantes y seguir haciendo esto. Se podría repetir esto indefinidamente. En nuestro modelo de detección facial hoy en día, el modelo utiliza 38 de este tipo de etapas. Estos filtros en cascada nos permiten entonces realizar esta detección. Específicamente, esa etapa final de las 38 etapas arrojará valores altos para los rostros. Dibuja una caja alrededor de valores en la imagen que superen un umbral, luego visualice encima de su imagen original, y ahí la tiene, una detección facial exitosa. Recapitulemos los pasos. En resumen, discutimos cómo extraer características simples como bordes usando filtros. Luego discutimos cómo se utilizan esas características simples para
encontrar iterativamente partes interesantes de la imagen utilizando un patrón en cascada. Por último, la cascada produce salidas de alto valor para caras. En la etapa final, dibujamos un cuadro alrededor de salidas de alto valor, y estos cuadros identifican caras en la imagen. Para obtener una copia de estas diapositivas y más recursos, asegúrate de consultar esta URL. Ahora que ya sabes cómo funcionan los detectores de rostro, vamos a terminar de codificar nuestro cambiador facial.
7. Intercambio de caras en código: Ahora tenemos código para procesar nuestra webcam y para detectar rostros, estamos listos para terminar el intercambio facial. En un nivel alto, seguiremos el mismo proceso de dos pasos que antes. En primer lugar, probaremos el intercambio facial en una imagen después implementaremos el intercambio facial para tu webcam. Empieza accediendo a esta URL como tengo en el lado derecho. Esto creará un entorno para nosotros de forma remota, de
nuevo, para que no queramos hacer ninguna configuración en nuestras propias computadoras. Antes de una nueva función, vamos a crear un nuevo archivo. En el lado izquierdo aquí, si tu navegador de archivos se ha derrumbado como el mío, adelante y haz clic en eso para expandirlo. En el extremo derecho, voy a cerrar mi vista previa haciendo clic en la x superior derecha. En este archivo, voy a dar clic en detect.py, y ese es el archivo que deseamos editar. Adelante y cierra el archivo haciendo clic en esta flecha izquierda en la parte superior izquierda. En este archivo, vamos a crear una nueva función, intercambiar caras para sostener tu código de detección facial y dibujo de caja. Vamos a definir una función llamada caras de intercambio por encima de nuestro código actual. Esta función va a tomar en la imagen y el detector facial. Dentro vamos a llevar este código partiendo del código de detección hasta el código de dibujo de caja. Voy a cortar eso y luego pegarlo en nuestra nueva función. Una vez que lo pegues, vas a necesitar ajustar la sangría. Para mí, las líneas 6 a 10 necesitan sangrarse una vez más. Ahora, vamos a emparejar los rectángulos, o en otras palabras, las caras en grupos de dos. Déjame explicarte cómo vamos a hacer eso. Pretender que la lista de rectángulos contiene solo números como este. Entonces rectángulos de 2። 2 seleccionarán cada otro número. En este caso, tendríamos 0, 2, 4. A continuación, rectángulos, 1። 2 omitirá el primero, luego seleccionará cada otro número. En este caso, tendríamos 1, 3, 5. La indexación es un tema bastante complicado así que no te preocupes si no entiendes esto completamente,
solo debes saber que esto es conceptualmente lo que está pasando. Por último, zip recogerá el primer elemento de ambas listas. En este caso, 0,1 entonces recogerá el segundo ítem de ambas listas, en este caso, 2,3. Por último, el tercer ítem de ambas listas haciendo 4,5. Todo esto para decir que expresión de aspecto complicado, zip rectángulos con un montón de columnas y números, selecciona cada dos rectángulos o cada dos caras. Vamos a codificar esto ahora. En tu código de la izquierda, vamos a cambiar este for-loop para que tengamos para rectángulo1, rectángulo2 en zip, y luego la expresión que teníamos antes de los rectángulos 1። 2, y coma. Voy a golpear Enter y aquí voy a escribir, pasar y eliminar nuestro código de dibujo de caja original. Ahora extrayamos ambas caras de la imagen. Vamos a empezar definiendo una función auxiliar. Debajo de las caras de intercambio, vamos a definir get face selector. Esta función, dado un rectángulo, devolverá una máscara para que seleccionemos la cara. En primer lugar, desestructuraremos el rectángulo en los cuatro valores, tal como lo hicimos antes. Aquí devolverá luego un objeto rebanado. Un objeto de corte le permite seleccionar una parte de la lista. En este caso, dos rebanadas permiten seleccionar parte de una matriz 2D o, en otras palabras, una parte de la imagen. Aquí devolveremos dos objetos de corte. El primer objeto de corte cortará desde lo largo de la primera dimensión o el eje y de y a y más h El segundo objeto de corte cortará a lo largo la segunda dimensión o el eje x de x a x más el ancho. Ahora vamos a usar esta función get face selector, arriba, usando nuestra nueva función helper, convertir el primer rectángulo en una máscara facial dentro de nuestro for-loop. Aquí escribiremos mask1 es igual para obtener selector de cara rectángulo1. Repite lo mismo para el segundo rectángulo. Ahora, usa las máscaras para seleccionar ambas caras de la imagen. Face1 es igual a imagen de mask1 y face2 es igual a imagen de mask2. Ahora, dado que las dos caras pueden ser de diferentes tamaños, necesitamos cambiar el tamaño de cada cara para que quepa dentro de la otra. Aquí te explicamos conceptualmente cómo vamos a hacer eso. Digamos que estamos tratando de encajar la caja verde dentro de la caja azul, observe que la altura azul es menor que la altura verde. Dado que la caja verde es más alta, acortaremos para que las alturas de ambas cajas sean las mismas. En este caso, la relación entre la altura azul y la altura verde nos dice cuánto necesitábamos encogernos en el rectángulo verde. Diga ahora que la caja verde es más ancha que la caja azul, observe que el ancho azul es menor que el ancho verde. Lo encogeremos para que los anchos de ambos rectángulos sean los mismos. En este caso, la relación entre el ancho azul y el ancho verde nos dice cuánto necesitábamos para reducir el rectángulo verde. En realidad no sabemos si el rectángulo es demasiado alto o demasiado ancho por lo que tomamos el mínimo de ambas ratios para estar seguros. Esto asegura que el rectángulo verde se haya encogido lo suficiente, ya sea demasiado alto o demasiado ancho, para caber dentro del rectángulo azul. Ahora vamos a codificar esto. Al igual que antes vamos a empezar definiendo una función auxiliar debajo de get face selector to find, redimensionar para encajar. Esta función tomará en dos caras, face1 y face2. En primer lugar, desestructura la forma de la cara para obtener el ancho y la altura de la cara. Escribiremos face1_height, face1_width, subrayado es que tienes que enfrentar1.shape. El rostro en realidad tiene tres dimensiones por su forma. Si recuerdas de nuestra lección anterior, todas las imágenes son h por w por 3. No necesitamos esa última dimensión, por lo que usamos un guión bajo. El subrayado es convención para ignorar esta variable. También vamos a repetir esto con la segunda cara, face2_h, face2_w es igual a face2.shape. Después calcula la cantidad requerida para reducir la primera cara para caber en la segunda cara. Este es el factor que mencionamos antes. El factor es igual al mínimo entre la altura de la cara2 dividida por la altura de la cara1, y luego el ancho de la cara2 dividido por el ancho de la cara1. Por último, redimensionaremos face1. Aquí, la función de cambio de tamaño que tomaremos en la primera cara y el segundo argumento es si argumento
requerido aunque no vamos a usar así que pase en ninguno por ahora. Después escribiremos el factor a escalar en la dimensión x, y luego el factor a escalar en la dimensión y. Por último, devuelve esto. Ahora utilizaremos el método de ayuda, redimensionar para encajar, para cambiar el tamaño de ambas caras para que encajen en la otra. Empezar con face1 arriba en el for-loop escribirá en redimensionado1 es igual a redimensionar para encajar face1, face2. Hacer lo mismo para la otra cara resize2 es igual a redimensionar para caber face2 en face1. Ahora en realidad pegaremos cada cara sobre la otra. Conceptualmente simplemente pegará el rectángulo verde en el azul. De nuevo, comenzaremos con el método de ayuda. Voy a desplazarme hacia abajo y debajo redimensionar para encajar definimos, asegurarnos de retroceder para que empieces una nueva función fuera, definimos aplicar, que toma en la cara redimensionada y la cara para pegarla. Desestructurar la forma de la cara en su altura y ancho redimensionado1 alto, redimensionado1 ancho y subrayado para ignorar que la tercera dimensión es igual a resize1.shape y luego pegar la cara en cara2. Aquí face2, ahora pegaremos la cara redimensionada en face2. Por último, regresa la segunda cara. Nuevamente, la indexación es un tema bastante complicado así que si no entiendes lo que significa esta línea, no te preocupes. Por ahora, sólo hay que saber así es como
pegó la cara redimensionada en la segunda cara. Desplazando de nuevo hasta el for-loop que ahora vamos a usar aplicar, para aplicar cada cara. Pegue la cara redimensionada2 en la cara1. Mask1 es igual a aplicar redimensionado2 face1. Repita lo mismo para la otra máscara de imagen de cara2 es igual para aplicar redimensionado1 face2. Para el paso final, en realidad
vamos a aplicar nuestra
función de swap faces a nuestra imagen y al detector facial correspondiente, desplácese hacia abajo hasta la parte inferior de su archivo después de que haya instanciado su detector y lee tu imagen en. Ahora vamos a llamar a rostros de swap en la imagen y el detector facial. Ahora terminamos con el guión. Haga clic en el navegador de archivos del lado izquierdo, haga clic en Herramientas, y luego terminal. Espere una configuración. Una vez realizada la configuración, escriba Python detect.py. Esto ejecutará tu código de cambio de cara. Después de ejecutar este script checkout out.JPEG en el lado izquierdo. Parece que la imagen no cambió tal vez,
bueno, mira más de cerca. En realidad se intercambian las caras de los niños. Esto es más obvio cuando cambio entre la imagen original y la intercambiada. Aquí está la imagen original y aquí está la intercambiada. Ahora aplicemos el cambio de caras a nuestra webcam. Comience accediendo a esta URL. Una vez cargada esta página, voy a dar clic en Cerrar en la vista previa del lado derecho, recomiendo hacer lo mismo para crear más espacio. En el lado izquierdo, voy a cerrar el navegador de archivos haciendo clic en la flecha de la parte superior izquierda. Para empezar, vamos a copiar todas las funciones de ayuda que escribimos en el último paso. Voy a pegarlos justo encima de nuestra instanciación detector facial. Aquí los pegaré. Tenga en cuenta que realmente no importa dónde pegue estas funciones. Si sí quieres pegar exactamente en la misma ubicación, lo
he pegado después de mis importaciones, pero antes de que se instancie el detector facial. Ahora definamos una nueva transformación para nuestra aplicación web aplique a la transmisión en vivo de webcam. Desplazándose hacia abajo después de todas nuestras funciones existentes, voy a crear una nueva transformación. Al igual que en una lección anterior, utilizaremos el decorador de CV abierto web en app.transform. Le daremos a esta transformación un nombre de intercambio facial y también haremos esta nueva transformación el valor predeterminado escribiendo por defecto igual a true. Voy a eliminar este valor predeterminado es igual a true
abajo porque no podemos tener dos transformaciones por defecto. Ahora definiremos una función de intercambio de caras que tome tanto la imagen como el marco, luego llamaremos al método de ayuda de caras de intercambio que escribiste en la última sección. Escriba las caras de intercambio y pase tanto la imagen como el detector facial y devuelva la imagen. Por último, eso es todo. Da click en Mostrar en la parte superior izquierda. Para mí parece que tenía icono de gafas de sol. Después selecciona en una nueva ventana, esto abre una vista previa de tu aplicación web. Voy a acercar para que veas lo que está pasando y luego haz clic en Inicio. En este caso, estoy de cara intercambiándome por una foto mía tomada en el pasado. Asegúrate de hacer clic en Inicio y luego Permitir. Eso concluye nuestro cambio facial. Ahora puedes compartir este cambio facial con tus amigos y familiares. Haz caras divertidas, comparte tantas fotos y diviértete con tu propia aplicación de intercambio facial. Buen trabajo completando esta lección, fue una larga. Para una copia de estas diapositivas, el código terminado, y más recursos asegúrese de revisar esta URL. Consulta la siguiente lección para los próximos pasos para aprender más visión por computadora.
8. Próximos pasos: Enhorabuena. Ya terminaste tu rostro intercambiando obra maestra. Cubrimos cómo se representan las imágenes, cómo extraer significado de las imágenes, modelos de detección de
rostros, y más. Si esto ha escogido tu interés en el aprendizaje automático y la visión por computadora, sígueme en Skillshare para que te notifiquen cuando se lance la siguiente clase. Si también te interesan los temas de ciencia de datos, echa un vistazo a mi clase Data Science 101; el juego con datos, o la clase SQL 101 para consultar y diseñar bases de datos. Gracias por unirte a mí para esta clase de intercambia de rostro. Enhorabuena una vez más haciéndolo al final del curso y hasta la próxima vez.