+
98
-

回答

Python 检测脸部区域并替换照片

要检测图片中脸部区域的大小与位置,并实现无缝更换,可以使用以下方法:

方法一:使用 OpenCV 和 dlib
import cv2
import dlib
import numpy as np

# 加载预训练的人脸检测器和关键点检测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")  # 需要下载此模型文件

def detect_and_replace_face(source_img_path, target_img_path, output_path):
    # 读取源图像(要替换的人脸)和目标图像
    source_img = cv2.imread(source_img_path)
    target_img = cv2.imread(target_img_path)

    # 转换为灰度图像以加快检测速度
    gray_source = cv2.cvtColor(source_img, cv2.COLOR_BGR2GRAY)
    gray_target = cv2.cvtColor(target_img, cv2.COLOR_BGR2GRAY)

    # 检测人脸
    source_faces = detector(gray_source)
    target_faces = detector(gray_target)

    if len(source_faces) == 0 or len(target_faces) == 0:
        print("未检测到人脸!")
        return

    # 获取第一个人脸(可根据需要修改)
    source_face = source_faces[0]
    target_face = target_faces[0]

    # 获取关键点
    source_landmarks = predictor(gray_source, source_face)
    target_landmarks = predictor(gray_target, target_face)

    # 提取关键点坐标
    source_points = np.array([[p.x, p.y] for p in source_landmarks.parts()], dtype=np.int32)
    target_points = np.array([[p.x, p.y] for p in target_landmarks.parts()], dtype=np.int32)

    # 计算凸包
    source_hull = cv2.convexHull(source_points)
    target_hull = cv2.convexHull(target_points)

    # 计算人脸区域的边界矩形
    (x, y, w, h) = cv2.boundingRect(target_hull)

    # 创建目标人脸的掩码
    mask = np.zeros_like(gray_target)
    cv2.fillConvexPoly(mask, target_hull, 255)

    # 计算Delaunay三角剖分
    rect = (0, 0, target_img.shape[1], target_img.shape[0])
    subdiv = cv2.Subdiv2D(rect)
    subdiv.insert(target_points.tolist())
    triangles = subdiv.getTriangleList()
    triangles = np.array(triangles, dtype=np.int32)

    # 实现三角剖分的人脸替换(此处简化,实际需要更复杂的实现)
    # 这里简化为直接替换整个凸包区域

    # 调整源人脸大小以匹配目标人脸
    source_face_resized = cv2.resize(source_img, (w, h))

    # 泊松融合实现无缝替换
    center = (x + w//2, y + h//2)
    output = cv2.seamlessClone(
        source_face_resized, 
        target_img, 
        mask[y:y+h, x:x+w], 
        center, 
        cv2.NORMAL_CLONE
    )

    cv2.imwrite(output_path, output)
    print(f"结果已保存到 {output_path}")

# 使用示例
detect_and_replace_face("person1.jpg", "person2.jpg", "output.jpg")
方法二:使用 face_recognition 库(更简单)
import face_recognition
import cv2
import numpy as np

def replace_face(source_img_path, target_img_path, output_path):
    # 加载图片
    source_img = face_recognition.load_image_file(source_img_path)
    target_img = face_recognition.load_image_file(target_img_path)

    # 检测人脸位置
    source_face_locations = face_recognition.face_locations(source_img)
    target_face_locations = face_recognition.face_locations(target_img)

    if not source_face_locations or not target_face_locations:
        print("未检测到人脸!")
        return

    # 获取第一个人脸的位置(可根据需要修改)
    (s_top, s_right, s_bottom, s_left) = source_face_locations[0]
    (t_top, t_right, t_bottom, t_left) = target_face_locations[0]

    # 提取人脸区域
    source_face = source_img[s_top:s_bottom, s_left:s_right]

    # 调整大小以匹配目标人脸
    target_face_height = t_bottom - t_top
    target_face_width = t_right - t_left
    resized_face = cv2.resize(source_face, (target_face_width, target_face_height))

    # 创建掩码
    mask = np.ones(resized_face.shape, dtype=np.uint8) * 255

    # 泊松融合
    center = (t_left + target_face_width // 2, t_top + target_face_height // 2)
    output = cv2.seamlessClone(
        resized_face,
        target_img,
        mask,
        center,
        cv2.NORMAL_CLONE
    )

    cv2.imwrite(output_path, cv2.cvtColor(output, cv2.COLOR_RGB2BGR))
    print(f"结果已保存到 {output_path}")

# 使用示例
replace_face("person1.jpg", "person2.jpg", "output.jpg")
注意事项

需要安装的库:

pip install opencv-python dlib face_recognition numpy

dlib 的预训练模型需要从 dlib.net 下载

更高级的实现可以考虑:

使用深度学习模型进行更精确的人脸检测和对齐实现更精细的面部特征点匹配考虑光照和肤色的匹配使用GAN模型实现更自然的融合效果

对于商业用途,请注意遵守相关法律法规和道德准则。

以上代码提供了基本的人脸检测和替换功能,实际应用中可能需要根据具体需求进行调整和优化。

网友回复

我知道答案,我要回答