当前位置:网站首页>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)




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)

边栏推荐
- El table X-axis direction (horizontal) scroll bar slides to the right by default
- LeetCode - 460 LFU 缓存(设计 - 哈希表+双向链表 哈希表+平衡二叉树(TreeSet))*
- 【C 题集】of Ⅵ
- LeetCode - 673. Number of longest increasing subsequences
- Development of intelligent charging pile (I): overview of the overall design of the system
- LeetCode - 1172 餐盘栈 (设计 - List + 小顶堆 + 栈))
- Yocto technology sharing phase IV: customize and add software package support
- Dynamic layout management
- [combinatorics] combinatorial existence theorem (three combinatorial existence theorems | finite poset decomposition theorem | Ramsey theorem | existence theorem of different representative systems |
- LeetCode - 706 设计哈希映射(设计) *
猜你喜欢

CV learning notes - edge extraction

LeetCode - 705 设计哈希集合(设计)

Leetcode - 460 LFU cache (Design - hash table + bidirectional linked hash table + balanced binary tree (TreeSet))*

CV learning notes - clustering

Timer and counter of 51 single chip microcomputer

2. Elment UI date selector formatting problem

CV learning notes - deep learning

el-table X轴方向(横向)滚动条默认滑到右边

LeetCode - 900. RLE 迭代器

LeetCode - 1670 設計前中後隊列(設計 - 兩個雙端隊列)
随机推荐
. DLL and Differences between lib files
LeetCode - 895 最大频率栈(设计- 哈希表+优先队列 哈希表 + 栈) *
JS foundation - prototype prototype chain and macro task / micro task / event mechanism
Leetcode interview question 17.20 Continuous median (large top pile + small top pile)
Connect Alibaba cloud servers in the form of key pairs
Mobile phones are a kind of MCU, but the hardware it uses is not 51 chip
[combinatorics] Introduction to Combinatorics (combinatorial idea 3: upper and lower bound approximation | upper and lower bound approximation example Remsey number)
CV learning notes - clustering
Retinaface: single stage dense face localization in the wild
LeetCode - 705 设计哈希集合(设计)
QT is a method of batch modifying the style of a certain type of control after naming the control
Swing transformer details-2
LeetCode - 673. Number of longest increasing subsequences
Leetcode bit operation
It is difficult to quantify the extent to which a single-chip computer can find a job
yocto 技术分享第四期:自定义增加软件包支持
My 4G smart charging pile gateway design and development related articles
Serial communication based on 51 single chip microcomputer
Leetcode - 895 maximum frequency stack (Design - hash table + priority queue hash table + stack)*
Gif image analysis drawing RGB to YUV table lookup method to reduce CPU occupancy