目录
Python实例题
题目
川普撞脸希拉里(基于OpenCV的面部特征交换)
实现思路
- 人脸检测:利用 OpenCV 的人脸检测器检测出川普和希拉里图片中的人脸。
- 特征点定位:使用预训练的面部特征点检测模型(如 dlib 的 68 点特征检测器)来定位人脸的特征点,如眼睛、鼻子、嘴巴等。
- 特征交换:根据检测到的特征点,将川普的面部特征区域提取出来,并将其映射到希拉里的对应位置,反之亦然。
- 图像融合:将交换后的特征区域融合到原始图像中,使交换后的图像看起来自然。
代码实现
import cv2
import dlib
import numpy as np
def get_landmarks(image):
"""
获取图像中人脸的 68 个特征点
:param image: 输入的图像
:return: 特征点的坐标
"""
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = detector(gray)
if len(faces) == 0:
return None
face = faces[0]
landmarks = predictor(gray, face)
landmarks_points = []
for n in range(0, 68):
x = landmarks.part(n).x
y = landmarks.part(n).y
landmarks_points.append((x, y))
return np.array(landmarks_points)
def affine_transform(image, source_points, dest_points):
"""
进行仿射变换
:param image: 输入的图像
:param source_points: 源特征点
:param dest_points: 目标特征点
:return: 变换后的图像
"""
M = cv2.getAffineTransform(source_points[:3], dest_points[:3])
warped_image = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
return warped_image
def face_swap(image1, image2):
"""
进行面部特征交换
:param image1: 图像 1
:param image2: 图像 2
:return: 交换后的图像
"""
landmarks1 = get_landmarks(image1)
landmarks2 = get_landmarks(image2)
if landmarks1 is None or landmarks2 is None:
print("未检测到人脸,请检查输入图像。")
return None
warped_image1 = affine_transform(image1, landmarks1, landmarks2)
# 创建一个掩码
hull_index = cv2.convexHull(landmarks2, returnPoints=False)
mask = np.zeros_like(image2)
cv2.fillConvexPoly(mask, cv2.convexHull(landmarks2), (255, 255, 255))
# 提取交换后的面部区域
warped_face = cv2.bitwise_and(warped_image1, warped_image1, mask=mask)
# 进行泊松融合
r = cv2.boundingRect(cv2.convexHull(landmarks2))
center_face2 = (r[0] + int(r[2] / 2), r[1] + int(r[3] / 2))
output = cv2.seamlessClone(warped_face, image2, mask, center_face2, cv2.NORMAL_CLONE)
return output
if __name__ == "__main__":
# 加载川普和希拉里的图片
trump_image = cv2.imread("trump.jpg")
hillary_image = cv2.imread("hillary.jpg")
# 进行面部特征交换
swapped_image = face_swap(trump_image, hillary_image)
if swapped_image is not None:
# 显示交换后的图像
cv2.imshow("Swapped Face", swapped_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
代码解释
-
get_landmarks
函数:- 使用 dlib 的人脸检测器检测图像中的人脸。
- 使用预训练的 68 点特征检测器定位人脸的特征点,并将其存储为
numpy
数组。
-
affine_transform
函数:- 计算源特征点到目标特征点的仿射变换矩阵。
- 使用
cv2.warpAffine
函数对图像进行仿射变换。
-
face_swap
函数:- 调用
get_landmarks
函数获取两张图像中人脸的特征点。 - 调用
affine_transform
函数将第一张图像的面部特征变换到第二张图像的对应位置。 - 创建一个掩码,提取交换后的面部区域。
- 使用
cv2.seamlessClone
函数进行泊松融合,使交换后的面部区域与原始图像自然融合。
- 调用
-
主程序:
- 加载川普和希拉里的图片。
- 调用
face_swap
函数进行面部特征交换。 - 显示交换后的图像。
运行思路
- 安装依赖库:确保已经安装了
opencv-python
和dlib
库,可以使用以下命令进行安装:
pip install opencv-python
pip install dlib
- 下载预训练模型:从 dlib 官方网站下载
shape_predictor_68_face_landmarks.dat
模型文件,并将其放在脚本所在的目录下。 - 准备图片:将川普和希拉里的图片分别命名为
trump.jpg
和hillary.jpg
,并放在脚本所在的目录下。 - 运行脚本:在终端中运行
python face_feature_swapping.py
,即可看到交换后的图像。
注意事项
- 图片质量:输入的图片质量会影响特征点检测和交换的效果,建议使用清晰、正面的人脸图片。
- 人脸检测:如果图片中未检测到人脸,脚本会输出提示信息,请检查输入图片。
- 模型文件:确保
shape_predictor_68_face_landmarks.dat
模型文件的路径正确。