当前位置:网站首页>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)
边栏推荐
- CV learning notes - BP neural network training example (including detailed calculation process and formula derivation)
- The underlying principle of vector
- LeetCode - 673. Number of longest increasing subsequences
- 【C 题集】of Ⅵ
- Sending and interrupt receiving of STM32 serial port
- LeetCode - 895 最大频率栈(设计- 哈希表+优先队列 哈希表 + 栈) *
- 01 business structure of imitation station B project
- Markdown latex full quantifier and existential quantifier (for all, existential)
- yocto 技术分享第四期:自定义增加软件包支持
- 2312. Selling wood blocks | things about the interviewer and crazy Zhang San (leetcode, with mind map + all solutions)
猜你喜欢
03 fastjason solves circular references
LeetCode - 715. Range 模块(TreeSet) *****
LeetCode - 1670 设计前中后队列(设计 - 两个双端队列)
ADS simulation design of class AB RF power amplifier
Open Euler Kernel Technology Sharing - Issue 1 - kdump Basic Principles, use and Case Introduction
Timer and counter of 51 single chip microcomputer
Leetcode 300 最长上升子序列
LeetCode 面试题 17.20. 连续中值(大顶堆+小顶堆)
LeetCode - 706 设计哈希映射(设计) *
It is difficult to quantify the extent to which a single-chip computer can find a job
随机推荐
Screen display of charging pile design -- led driver ta6932
Development of intelligent charging pile (I): overview of the overall design of the system
2021-10-27
[combinatorics] combinatorial existence theorem (three combinatorial existence theorems | finite poset decomposition theorem | Ramsey theorem | existence theorem of different representative systems |
Leetcode bit operation
LeetCode - 703 数据流中的第 K 大元素(设计 - 优先队列)
The underlying principle of vector
About windows and layout
Of course, the most widely used 8-bit single chip microcomputer is also the single chip microcomputer that beginners are most easy to learn
Tensorflow2.0 save model
4G module board level control interface designed by charging pile
CV learning notes - clustering
openEuler kernel 技术分享 - 第1期 - kdump 基本原理、使用及案例介绍
Simulate mouse click
Opencv image rotation
LeetCode - 460 LFU 缓存(设计 - 哈希表+双向链表 哈希表+平衡二叉树(TreeSet))*
Leetcode 300 longest ascending subsequence
03 FastJson 解决循环引用
2.2 DP: Value Iteration & Gambler‘s Problem
Leetcode - 895 maximum frequency stack (Design - hash table + priority queue hash table + stack)*