当前位置:网站首页>Mise en œuvre d'OpenCV + dlib pour changer le visage de Mona Lisa

Mise en œuvre d'OpenCV + dlib pour changer le visage de Mona Lisa

2022-07-03 10:10:00 Guozhou topmaker

opencv+dlibRéaliser un changement de visage pour Mona Lisa

Ce cas utiliseopencv+dlibPour changer le visage de Mona Lisa.

Principes de base de la mise en oeuvre du changement de visage:

  • UtiliserdlibDeshape_predictor_68_face_landmarks.datModèle,Extraire l'image source et l'image cible avec le visage droit68Caractéristiques du visage.

  • Les masques faciaux sont obtenus séparément selon les points caractéristiques du visage

  • Affine la transformation de l'image source pour aligner son visage sur le visage de l'image cible pour obtenir une nouvelle image

  • Effectuer la même opération affine sur le masque facial

  • Union de deux nouveaux graphiques

  • Utilisationopencv,Fusion de poisson de l'image source et de l'image cible après transformation d'affine

Un.、Principales étapes

1.Importer un kit

import cv2
import dlib
import numpy as np
#ImporterpythonDessinmatplotlib
import matplotlib.pyplot as plt
#UtiliseripythonLa méthode magique,.Intégrer l'image dessinée directement dansnotebookDans les cellules
%matplotlib inline
#Définir une fonction d'image visuelle
def look_img(img):
    '''opencvLire l'image dans le formatBGR,matplotlibLe format de visualisation estRGB,Il est donc nécessaire deBGRTourne.RGB'''
    img_RGB = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    plt.imshow(img_RGB)
    plt.show()

2.Obtenir la taille de l'image(Hauteur,Largeur)

def get_image_size(image):
    """ Obtenir la taille de l'image(Hauteur,Largeur) :param image: image :return: (Hauteur,Largeur) """
    image_size = (image.shape[0], image.shape[1])
    return image_size

3.Obtenir un logo Facial,68Points caractéristiques

def get_face_landmarks(image, face_detector, shape_predictor):
    """ Obtenir un logo Facial,68Points caractéristiques :param image: image :param face_detector: dlib.get_frontal_face_detector :param shape_predictor: dlib.shape_predictor :return: np.array([[],[]]), 68Points caractéristiques """
    dets = face_detector(image, 1)

    shape = shape_predictor(image, dets[0])
    face_landmarks = np.array([[p.x, p.y] for p in shape.parts()])
    return face_landmarks

4.Obtenir un masque facial

def get_face_mask(image_size, face_landmarks):
    """ Obtenir un masque facial :param image_size: Taille de l'image :param face_landmarks: 68Points caractéristiques :return: image_mask, Image du masque """
    mask = np.zeros(image_size, dtype=np.uint8)
    points = np.concatenate([face_landmarks[0:16], face_landmarks[26:17:-1]])
    cv2.fillPoly(img=mask, pts=[points], color=255)
    return mask

5. Obtenir l'image de l'image source après la transformation d'affine

def get_affine_image(image1, image2, face_landmarks1, face_landmarks2):
    """ Obtenir des photos1Image après transformation d'affine :param image1: Photos1, Image à transformer en affine :param image2: Photos2, Juste pour obtenir la taille de l'image,Générer une image de transformation d'affine de la même taille :param face_landmarks1: Photos1Les caractéristiques faciales de :param face_landmarks2: Photos2Les caractéristiques faciales de :return: Image après transformation d'affine """
    three_points_index = [18, 8, 25]
    M = cv2.getAffineTransform(face_landmarks1[three_points_index].astype(np.float32),
                               face_landmarks2[three_points_index].astype(np.float32))
    dsize = (image2.shape[1], image2.shape[0])
    affine_image = cv2.warpAffine(image1, M, dsize)
    return affine_image.astype(np.uint8)

6.Obtenir les coordonnées du point central du masque

def get_mask_center_point(image_mask):
    """ Obtenir les coordonnées du point central du masque :param image_mask: Image du masque :return: Le Centre du masque """
    image_mask_index = np.argwhere(image_mask > 0)
    miny, minx = np.min(image_mask_index, axis=0)
    maxy, maxx = np.max(image_mask_index, axis=0)
    center_point = ((maxx + minx) // 2, (maxy + miny) // 2)
    return center_point

7.Obtenir l'Union des deux parties masquées du masque

def get_mask_union(mask1, mask2):
    """ Obtenir l'Union des deux parties masquées du masque :param mask1: mask_image, Masque1 :param mask2: mask_image, Masque2 :return: L'Union de deux parties masquées """
    mask = np.min([mask1, mask2], axis=0)  # Masquer l'Union partielle
    mask = ((cv2.blur(mask, (5, 5)) == 255) * 255).astype(np.uint8)  # Réduire la taille du masque
    mask = cv2.blur(mask, (3, 3)).astype(np.uint8)  # Masque flou
    return mask

8.Ajustement de la couleur de la peau

def skin_color_adjustment(im1, im2, mask=None):
    """ Ajustement de la couleur de la peau :param im1: Photos1 :param im2: Photos2 :param mask: Visage humain mask. Si elle existe,Utiliser la moyenne partielle du visage pour calculer le coefficient de transformation de la peau;Sinon,Utiliser le flou gaussien pour calculer le coefficient de transformation de la peau :return: Selon l'image2Pour ajuster la couleur de l'image1 """
    if mask is None:
        im1_ksize = 55
        im2_ksize = 55
        im1_factor = cv2.GaussianBlur(im1, (im1_ksize, im1_ksize), 0).astype(np.float)
        im2_factor = cv2.GaussianBlur(im2, (im2_ksize, im2_ksize), 0).astype(np.float)
    else:
        im1_face_image = cv2.bitwise_and(im1, im1, mask=mask)
        im2_face_image = cv2.bitwise_and(im2, im2, mask=mask)
        im1_factor = np.mean(im1_face_image, axis=(0, 1))
        im2_factor = np.mean(im2_face_image, axis=(0, 1))

	im1 = np.clip((im1.astype(np.float64) * im2_factor / np.clip(im1_factor, 1e-6, None)), 0, 255).astype(np.uint8)
	return im1

9.Procédure principale

#  Créer un détecteur de visage 
det_face = dlib.get_frontal_face_detector()
#  Charger le détecteur de points de repère 
det_landmarks = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")  # 68Point

im1 = cv2.imread('peter.jpg')  # Image Source
im1 = cv2.resize(im1, (600, im1.shape[0] * 600 // im1.shape[1]))
landmarks1 = get_face_landmarks(im1, det_face, det_landmarks)  # 68_face_landmarks
im1_size = get_image_size(im1)  # Taille du visage
im1_mask = get_face_mask(im1_size, landmarks1)  # Masque facial

im2 = cv2.imread('mnls.jpg')  # Image cible
landmarks2 = get_face_landmarks(im2, det_face, det_landmarks)  # 68_face_landmarks
  
im2_size = get_image_size(im2)  # Taille de l'image cible
im2_mask = get_face_mask(im2_size, landmarks2)  #  Image cible masque facial 
affine_im1 = get_affine_image(im1, im2, landmarks1, landmarks2)  # im1(Carte faciale)Image après transformation d'affine
affine_im1_mask = get_affine_image(im1_mask, im2, landmarks1, landmarks2)  # im1(Carte faciale)Masque facial pour les images transformées d'affine
union_mask = get_mask_union(im2_mask, affine_im1_mask)  # Fusion de masques
affine_im1 = skin_color_adjustment(affine_im1, im2, mask=union_mask)  # Ajustement de la couleur de la peau
point = get_mask_center_point(affine_im1_mask)  # im1(Carte faciale)Le point central du masque facial après la transformation d'affine
seamless_im = cv2.seamlessClone(affine_im1, im2, mask=union_mask, p=point, flags=cv2.NORMAL_CLONE)  # Effectuer la fusion de poisson

look_img(im1)
look_img(im2)
look_img(affine_im1)
look_img(seamless_im)


Insérer la description de l'image ici
Insérer la description de l'image ici
Insérer la description de l'image ici
Insérer la description de l'image ici

2.、 Effet de changement de visage

#  Comparaison entre l'image originale et l'image après le changement de visage 

from PIL import Image
img0 = cv2.cvtColor(np.hstack((im2, seamless_im)), cv2.COLOR_BGR2RGB)
im=Image.fromarray(img0)
display(im)

Insérer la description de l'image ici

原网站

版权声明
本文为[Guozhou topmaker]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/184/202207030922412161.html