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

边栏推荐
- Windows下MySQL的安装和删除
- Opencv notes 17 template matching
- Leetcode 300 最长上升子序列
- Tensorflow built-in evaluation
- [combinatorics] Introduction to Combinatorics (combinatorial idea 3: upper and lower bound approximation | upper and lower bound approximation example Remsey number)
- Design of charging pile mqtt transplantation based on 4G EC20 module
- Serial communication based on 51 single chip microcomputer
- Cases of OpenCV image enhancement
- . DLL and Differences between lib files
- CV learning notes - reasoning and training
猜你喜欢

LeetCode 面试题 17.20. 连续中值(大顶堆+小顶堆)

Openeuler kernel technology sharing - Issue 1 - kdump basic principle, use and case introduction

Installation and removal of MySQL under Windows

CV learning notes convolutional neural network

Crash工具基本使用及实战分享

2312. Selling wood blocks | things about the interviewer and crazy Zhang San (leetcode, with mind map + all solutions)

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

I think all friends should know that the basic law of learning is: from easy to difficult

LeetCode - 460 LFU 缓存(设计 - 哈希表+双向链表 哈希表+平衡二叉树(TreeSet))*

使用密钥对的形式连接阿里云服务器
随机推荐
LeetCode - 5 最长回文子串
20220609其他:多数元素
LeetCode - 933 最近的请求次数
After clicking the Save button, you can only click it once
Working mode of 80C51 Serial Port
01仿B站项目业务架构
LeetCode - 508. Sum of subtree elements with the most occurrences (traversal of binary tree)
SCM is now overwhelming, a wide variety, so that developers are overwhelmed
LeetCode - 703 数据流中的第 K 大元素(设计 - 优先队列)
Pycharm cannot import custom package
Liquid crystal display
QT setting suspension button
Mobile phones are a kind of MCU, but the hardware it uses is not 51 chip
My notes on intelligent charging pile development (II): overview of system hardware circuit design
CV learning notes - image filter
Tensorflow built-in evaluation
LeetCode - 508. 出现次数最多的子树元素和 (二叉树的遍历)
4G module designed by charging pile obtains signal strength and quality
Leetcode - 933 number of recent requests
CV learning notes alexnet