Blog
Algoritmo de Intercambio de Caras
- Publicado por: Rafael Fernandez
- Categoría: Blog DLib OpenCV Procesamiento de Imagenes

-Aquí te mostramos un algoritmo que sirve para intercambiar las caras, citaremos el código y te mostraremos algunos resultados con imágenes de personas reales.
Desde hace un tiempo las aplicaciones para intercambiar caras se han puesto de moda y por eso hoy quiero traeros un algoritmo muy divertido de Intercambio de Caras.
Algoritmo en Python para Intercambio de Caras
Veamos un ejemplo con dos políticos bastante conocidos, Trump y Merkel:
¿Como seria un intercambio de caras entre estos dos personajes?
Ejemplo de Intercambio de Caras
Os presentamos a Tremkel ???
Requisitos para correr el algoritmo
Bueno visto lo que podemos hacer con este código vamos a ponernos manos a la obra. Lo primero que tenemos que saber es que necesitamos tener 3 librerias y un archivo:
- cv2 (librería openCV)
- dlib
- numpy
- archivo : shape_predictor_68_face_landmarks.dat (lo puedes descargar desde este link)
Código en python para el intercambio de caras
El código en python para el intercambio de caras es el siguiente
import cv2 import dlib import numpy PREDICTOR_PATH = "shape_predictor_68_face_landmarks.dat" SCALE_FACTOR = 1 FEATHER_AMOUNT = 11 FACE_POINTS = list(range(17, 68)) MOUTH_POINTS = list(range(48, 61)) RIGHT_BROW_POINTS = list(range(17, 22)) LEFT_BROW_POINTS = list(range(22, 27)) RIGHT_EYE_POINTS = list(range(36, 42)) LEFT_EYE_POINTS = list(range(42, 48)) NOSE_POINTS = list(range(27, 35)) JAW_POINTS = list(range(0, 17)) # Puntos utilizados para alinear las imágenes. ALIGN_POINTS = (LEFT_BROW_POINTS + RIGHT_EYE_POINTS + LEFT_EYE_POINTS + RIGHT_BROW_POINTS + NOSE_POINTS + MOUTH_POINTS) # Puntos de la segunda imagen para superponer en la primera. El casco convexo de cada # Elemento será superpuesto. OVERLAY_POINTS = [ LEFT_EYE_POINTS + RIGHT_EYE_POINTS + LEFT_BROW_POINTS + RIGHT_BROW_POINTS, NOSE_POINTS + MOUTH_POINTS, ] COLOUR_CORRECT_BLUR_FRAC = 0.6 detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor(PREDICTOR_PATH) class TooManyFaces(Exception): pass class NoFaces(Exception): pass def get_landmarks(im): rects = detector(im, 1) if len(rects) > 1: raise TooManyFaces if len(rects) == 0: raise NoFaces return numpy.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()]) def annotate_landmarks(im, landmarks): im = im.copy() for idx, point in enumerate(landmarks): pos = (point[0, 0], point[0, 1]) cv2.putText(im, str(idx), pos, fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale=0.4, color=(0, 0, 255)) cv2.circle(im, pos, 3, color=(0, 255, 255)) return im def draw_convex_hull(im, points, color): points = cv2.convexHull(points) cv2.fillConvexPoly(im, points, color=color) def get_face_mask(im, landmarks): im = numpy.zeros(im.shape[:2], dtype=numpy.float64) for group in OVERLAY_POINTS: draw_convex_hull(im, landmarks[group], color=1) im = numpy.array([im, im, im]).transpose((1, 2, 0)) im = (cv2.GaussianBlur(im, (FEATHER_AMOUNT, FEATHER_AMOUNT), 0) > 0) * 1.0 im = cv2.GaussianBlur(im, (FEATHER_AMOUNT, FEATHER_AMOUNT), 0) return im def transformation_from_points(points1, points2): # Resolver el problema de procrustes restando los centroides, escalando por el # Desviación estándar, y luego usar el SVD para calcular la rotación. Ver # Lo siguiente para más detalles: # https://en.wikipedia.org/wiki/Orthogonal_Procrustes_problem points1 = points1.astype(numpy.float64) points2 = points2.astype(numpy.float64) c1 = numpy.mean(points1, axis=0) c2 = numpy.mean(points2, axis=0) points1 -= c1 points2 -= c2 s1 = numpy.std(points1) s2 = numpy.std(points2) points1 /= s1 points2 /= s2 U, S, Vt = numpy.linalg.svd(points1.T * points2) # El R que buscamos es, de hecho, la transposición de la dada por U * Vt. Esto # Es porque la formulación anterior asume que la matriz va a la derecha # (Con vectores de fila) donde como nuestra solución requiere que la matriz esté en la # Izquierda (con vectores columna) R = (U * Vt).T return numpy.vstack([numpy.hstack(((s2 / s1) * R, c2.T - (s2 / s1) * R * c1.T)), numpy.matrix([0., 0., 1.])]) def read_im_and_landmarks(fname): im = cv2.imread(fname, cv2.IMREAD_COLOR) im = cv2.resize(im, (im.shape[1] * SCALE_FACTOR, im.shape[0] * SCALE_FACTOR)) s = get_landmarks(im) return im, s def warp_im(im, M, dshape): output_im = numpy.zeros(dshape, dtype=im.dtype) cv2.warpAffine(im, M[:2], (dshape[1], dshape[0]), dst=output_im, borderMode=cv2.BORDER_TRANSPARENT, flags=cv2.WARP_INVERSE_MAP) return output_im def correct_colours(im1, im2, landmarks1): blur_amount = COLOUR_CORRECT_BLUR_FRAC * numpy.linalg.norm( numpy.mean(landmarks1[LEFT_EYE_POINTS], axis=0) - numpy.mean(landmarks1[RIGHT_EYE_POINTS], axis=0)) blur_amount = int(blur_amount) if blur_amount % 2 == 0: blur_amount += 1 im1_blur = cv2.GaussianBlur(im1, (blur_amount, blur_amount), 0) im2_blur = cv2.GaussianBlur(im2, (blur_amount, blur_amount), 0) # evitamos dividir por 0 im2_blur += (128 * (im2_blur <= 1.0)).astype(im2_blur.dtype) return (im2.astype(numpy.float64) * im1_blur.astype(numpy.float64) / im2_blur.astype(numpy.float64)) #aqui se añaden las imagenes que queremos usar im1, landmarks1 = read_im_and_landmarks('5.jpg') im2, landmarks2 = read_im_and_landmarks('6.jpg') M = transformation_from_points(landmarks1[ALIGN_POINTS], landmarks2[ALIGN_POINTS]) mask = get_face_mask(im2, landmarks2) warped_mask = warp_im(mask, M, im1.shape) combined_mask = numpy.max([get_face_mask(im1, landmarks1), warped_mask], axis=0) warped_im2 = warp_im(im2, M, im1.shape) warped_corrected_im2 = correct_colours(im1, warped_im2, landmarks1) output_im = im1 * (1.0 - combined_mask) + warped_corrected_im2 * combined_mask #imagen de salida cv2.imwrite('output.jpg', output_im)
El código se compone de:
- 2 clases “TooManyFaces” y “NoFaces”
- 7 funciones (get_landmarks, annotate_landmarks, draw_convex_hull, get_face_mask, transformation_from_points, read_im_and_landmarks, warp_im, correct_colours)
No olvidéis cambiar las imágenes en las líneas 149 y 150 del código y de tener en una misma carpeta las imagenes, el codigo y el archivo shape_predictor_68_face_landmarks.dat
Ejemplo de Anna Kúrnikova y Madonna
Aqui os damos mas ejemplos que hemos hecho con el código de intercambio de caras en python. ¿Como sería quedaria la mezcla entre la tenista Anna Kúrnikova y la cantande Madonna?
Ejemplo de Obama y Denzel Washington
¿Como sería quedaría la mezcla entre el ex presidente Obama y el actor Denzel Washington?
¿Y al revés entre Madonna y Anna Kúrnikova? ???
➡ Aprende mucho mas en nuestro curso de Dlib y OpenCV:
[…] Share Tweet Google+ Email Prev Article Next Article […]
[…] Curso de Python Avanzado con Dlib & OpenCV, Tutorial 3º […]