中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python怎么實現攝像頭實時換臉

發布時間:2022-03-14 15:52:14 來源:億速云 閱讀:180 作者:iii 欄目:開發技術

這篇文章主要介紹“Python怎么實現攝像頭實時換臉”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Python怎么實現攝像頭實時換臉”文章能幫助大家解決問題。

環境

python3.9.6

pycharm 2021

庫環境:

dlib

opencv-python

基本原理

使用dlib的shape_predictor_68_face_landmarks.dat模型獲取一張有正臉的圖片(1.png)和攝像頭的自己的68個人臉特征點。

根據人臉特征點獲取分別獲取人臉掩模

對第一個圖片仿射變換使其臉部對準攝像頭圖片中的臉部得到新的圖片

對人臉掩模執行相同的操作仿射

將兩個性的得到圖取并集(不能讓別的地方空了)

用opencv對兩上面操作,對仿射變換后的a圖片和攝像頭圖片進行泊松融合

完整源碼

# -*- coding: utf-8 -*-

import cv2
import dlib
import numpy as np

detector = dlib.get_frontal_face_detector()  # dlib的正向人臉檢測器
predictor = dlib.shape_predictor(r'shape_predictor_68_face_landmarks.dat')  # dlib的人臉形狀檢測器


def get_image_size(image):
    """
    獲取圖片大小(高度,寬度)
    :param image: image
    :return: (高度,寬度)
    """
    image_size = (image.shape[0], image.shape[1])
    return image_size


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


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


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)


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


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


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.float) * im2_factor / np.clip(im1_factor, 1e-6, None)), 0, 255).astype(np.uint8)
    return im1


def main():
    im1 = cv2.imread('1.png')  # face_image
    im1 = cv2.resize(im1, (600, im1.shape[0] * 600 // im1.shape[1]))
    landmarks1 = get_face_landmarks(im1, detector, predictor)  # 68_face_landmarks
    if landmarks1 is None:
        print('{}:檢測不到人臉'.format(image_face_path))
        exit(1)
    im1_size = get_image_size(im1)  # 臉圖大小
    im1_mask = get_face_mask(im1_size, landmarks1)  # 臉圖人臉掩模

    cam = cv2.VideoCapture(0)
    while True:
        ret_val, im2 = cam.read()  # camera_image
        landmarks2 = get_face_landmarks(im2, detector, predictor)  # 68_face_landmarks
        if landmarks2 is not None:
            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)  # 進行泊松融合

            cv2.imshow('seamless_im', seamless_im)
        else:
            cv2.imshow('seamless_im', im2)
        if cv2.waitKey(1) == 27:  # 按Esc退出
            break
    cv2.destroyAllWindows()


if __name__ == '__main__':
    main()

關于“Python怎么實現攝像頭實時換臉”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汝阳县| 碌曲县| 榆树市| 夏津县| 衡阳县| 交城县| 县级市| 麦盖提县| 临漳县| 洛隆县| 沙雅县| 抚宁县| 九龙县| 紫金县| 翼城县| 郸城县| 裕民县| 莱州市| 玉溪市| 夏津县| 芮城县| 南岸区| 凤城市| 夹江县| 镇原县| 天气| 印江| 务川| 静宁县| 桑日县| 丹东市| 历史| 花莲县| 多伦县| 新民市| 衡水市| 洪江市| 噶尔县| 安乡县| 日照市| 金华市|