当前位置:网站首页>openCV+dlib实现给蒙娜丽莎换脸
openCV+dlib实现给蒙娜丽莎换脸
2022-07-03 09:23:00 【果州做题家】
opencv+dlib实现给蒙娜丽莎换脸
本案例利用opencv+dlib实现了给蒙娜丽莎换脸。
换脸实现的基本原理:
使用dlib的shape_predictor_68_face_landmarks.dat模型,提取有正脸的源图片和目标图片68个人脸特征点。
根据人脸特征点分别获取人脸掩模
对源图片仿射变换使其脸部对准目标图片中的脸部得到新的图片
对人脸掩模执行相同的操作仿射
将两个新得到的图取并集
利用opencv,对仿射变换后的源图片和目标图片进行泊松融合
一、主要步骤
1.导入工具包
import cv2
import dlib
import numpy as np
#导入python绘图matplotlib
import matplotlib.pyplot as plt
#使用ipython的魔法方法,将绘制出的图像直接嵌入在notebook单元格中
%matplotlib inline
#定义可视化图像函数
def look_img(img):
'''opencv读入图像格式为BGR,matplotlib可视化格式为RGB,因此需将BGR转RGB'''
img_RGB = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(img_RGB)
plt.show()
2.获取图片大小(高度,宽度)
def get_image_size(image):
""" 获取图片大小(高度,宽度) :param image: image :return: (高度,宽度) """
image_size = (image.shape[0], image.shape[1])
return image_size
3.获取人脸标志,68个特征点
def get_face_landmarks(image, face_detector, shape_predictor):
""" 获取人脸标志,68个特征点 :param image: image :param face_detector: dlib.get_frontal_face_detector :param shape_predictor: dlib.shape_predictor :return: np.array([[],[]]), 68个特征点 """
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.获取人脸掩模
def get_face_mask(image_size, face_landmarks):
""" 获取人脸掩模 :param image_size: 图片大小 :param face_landmarks: 68个特征点 :return: image_mask, 掩模图片 """
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.获取源图片仿射变换后的图片
def get_affine_image(image1, image2, face_landmarks1, face_landmarks2):
""" 获取图片1仿射变换后的图片 :param image1: 图片1, 要进行仿射变换的图片 :param image2: 图片2, 只要用来获取图片大小,生成与之大小相同的仿射变换图片 :param face_landmarks1: 图片1的人脸特征点 :param face_landmarks2: 图片2的人脸特征点 :return: 仿射变换后的图片 """
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.获取掩模的中心点坐标
def get_mask_center_point(image_mask):
""" 获取掩模的中心点坐标 :param image_mask: 掩模图片 :return: 掩模中心 """
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.获取两个掩模掩盖部分的并集
def get_mask_union(mask1, mask2):
""" 获取两个掩模掩盖部分的并集 :param mask1: mask_image, 掩模1 :param mask2: mask_image, 掩模2 :return: 两个掩模掩盖部分的并集 """
mask = np.min([mask1, mask2], axis=0) # 掩盖部分并集
mask = ((cv2.blur(mask, (5, 5)) == 255) * 255).astype(np.uint8) # 缩小掩模大小
mask = cv2.blur(mask, (3, 3)).astype(np.uint8) # 模糊掩模
return mask
8.肤色调整
def skin_color_adjustment(im1, im2, mask=None):
""" 肤色调整 :param im1: 图片1 :param im2: 图片2 :param mask: 人脸 mask. 如果存在,使用人脸部分均值来求肤色变换系数;否则,使用高斯模糊来求肤色变换系数 :return: 根据图片2的颜色调整的图片1 """
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.主程序
# 创建人脸检测器
det_face = dlib.get_frontal_face_detector()
# 加载标志点检测器
det_landmarks = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") # 68点
im1 = cv2.imread('peter.jpg') # 源图片
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) # 脸图大小
im1_mask = get_face_mask(im1_size, landmarks1) # 脸图人脸掩模
im2 = cv2.imread('mnls.jpg') # 目标图片
landmarks2 = get_face_landmarks(im2, det_face, det_landmarks) # 68_face_landmarks
im2_size = get_image_size(im2) # 目标图片大小
im2_mask = get_face_mask(im2_size, landmarks2) # 目标图片人脸掩模
affine_im1 = get_affine_image(im1, im2, landmarks1, landmarks2) # im1(脸图)仿射变换后的图片
affine_im1_mask = get_affine_image(im1_mask, im2, landmarks1, landmarks2) # im1(脸图)仿射变换后的图片的人脸掩模
union_mask = get_mask_union(im2_mask, affine_im1_mask) # 掩模合并
affine_im1 = skin_color_adjustment(affine_im1, im2, mask=union_mask) # 肤色调整
point = get_mask_center_point(affine_im1_mask) # im1(脸图)仿射变换后的图片的人脸掩模的中心点
seamless_im = cv2.seamlessClone(affine_im1, im2, mask=union_mask, p=point, flags=cv2.NORMAL_CLONE) # 进行泊松融合
look_img(im1)
look_img(im2)
look_img(affine_im1)
look_img(seamless_im)




二、换脸效果图
# 原图与换脸后的图比较
from PIL import Image
img0 = cv2.cvtColor(np.hstack((im2, seamless_im)), cv2.COLOR_BGR2RGB)
im=Image.fromarray(img0)
display(im)

边栏推荐
- Vgg16 migration learning source code
- Opencv gray histogram, histogram specification
- CV learning notes - Stereo Vision (point cloud model, spin image, 3D reconstruction)
- Toolbutton property settings
- CV learning notes ransca & image similarity comparison hash
- 使用sed替换文件夹下文件
- Tensorflow2.0 save model
- Leetcode 300 最长上升子序列
- SCM is now overwhelming, a wide variety, so that developers are overwhelmed
- My notes on intelligent charging pile development (II): overview of system hardware circuit design
猜你喜欢

3.1 Monte Carlo Methods & case study: Blackjack of on-Policy Evaluation

LeetCode - 919. Full binary tree inserter (array)

2.1 Dynamic programming and case study: Jack‘s car rental

03 FastJson 解决循环引用

The underlying principle of vector

LeetCode - 900. RLE 迭代器

Leetcode bit operation

There is no shortcut to learning and development, and there is almost no situation that you can learn faster by leading the way

It is difficult to quantify the extent to which a single-chip computer can find a job

Cases of OpenCV image enhancement
随机推荐
CV learning notes - reasoning and training
01仿B站项目业务架构
CV learning notes - deep learning
自動裝箱與拆箱了解嗎?原理是什麼?
Leetcode interview question 17.20 Continuous median (large top pile + small top pile)
My notes on intelligent charging pile development (II): overview of system hardware circuit design
CV learning notes - Stereo Vision (point cloud model, spin image, 3D reconstruction)
Positive and negative sample division and architecture understanding in image classification and target detection
Pymssql controls SQL for Chinese queries
QT detection card reader analog keyboard input
QT self drawing button with bubbles
CV learning notes - BP neural network training example (including detailed calculation process and formula derivation)
03 FastJson 解决循环引用
. DLL and Differences between lib files
LeetCode - 1670 设计前中后队列(设计 - 两个双端队列)
The 4G module designed by the charging pile obtains NTP time through mqtt based on 4G network
01 business structure of imitation station B project
CV learning notes - edge extraction
Toolbutton property settings
About windows and layout